From 4499d32fdaf7fa90ec2eb1a198edfa2818b696aa Mon Sep 17 00:00:00 2001 From: mike Date: Wed, 7 Mar 2012 12:08:55 +0100 Subject: [PATCH] Fixed IsInsideDocComment method. TODO: Move the detection of comments & string regions to the IMemberProvider (needs rename) and handle that with a tree on IDE level. --- .../Completion/CSharpCompletionEngine.cs | 4 +- .../Completion/CSharpCompletionEngineBase.cs | 90 +++++++++++++++---- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 4f1ad1aa02..6b3428cc4a 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -468,7 +468,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion var prevToken2 = GetPreviousToken (ref prevTokenIndex, false); if (prevToken2 == "delegate") // after these always follows a name return null; - if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex)) && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) { + if (identifierStart == null && !string.IsNullOrEmpty (token) && !IsInsideCommentOrString () && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) { char last = token [token.Length - 1]; if (char.IsLetterOrDigit (last) || last == '_' || token == ">") { return HandleKeywordCompletion (tokenIndex, token); @@ -752,7 +752,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion bool IsInLinqContext (int offset) { string token; - while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideComment (offset) && !IsInsideString (offset)) { + while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideCommentOrString ()) { if (token == "from") return true; if (token == ";" || token == "{") diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs index 630b65f9f4..3b65b02be9 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs @@ -171,28 +171,82 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return inSingleComment || inString || inVerbatimString || inChar || inMultiLineComment; } - - protected bool IsInsideComment (int offset) - { - var loc = document.GetLocation (offset); - return Unit.GetNodeAt (loc.Line, loc.Column) != null; - } - + protected bool IsInsideDocComment () { - var loc = document.GetLocation (offset); - var cmt = Unit.GetNodeAt (loc.Line, loc.Column - 1); - return cmt != null && cmt.CommentType == CommentType.Documentation; - } - - protected bool IsInsideString (int offset) - { + var text = GetMemberTextToCaret (); + bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false; + bool singleLineIsDoc = false; + + for (int i = 0; i < text.Item1.Length - 1; i++) { + char ch = text.Item1 [i]; + char nextCh = text.Item1 [i + 1]; + + switch (ch) { + case '/': + if (inString || inChar || inVerbatimString) + break; + if (nextCh == '/') { + i++; + inSingleComment = true; + singleLineIsDoc = i + 1 < text.Item1.Length && text.Item1 [i + 1] == '/'; + if (singleLineIsDoc) { + i++; + } + } + if (nextCh == '*') + inMultiLineComment = true; + break; + case '*': + if (inString || inChar || inVerbatimString || inSingleComment) + break; + if (nextCh == '/') { + i++; + inMultiLineComment = false; + } + break; + case '@': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) + break; + if (nextCh == '"') { + i++; + inVerbatimString = true; + } + break; + case '\n': + case '\r': + inSingleComment = false; + inString = false; + inChar = false; + break; + case '\\': + if (inString || inChar) + i++; + break; + case '"': + if (inSingleComment || inMultiLineComment || inChar) + break; + if (inVerbatimString) { + if (nextCh == '"') { + i++; + break; + } + inVerbatimString = false; + break; + } + inString = !inString; + break; + case '\'': + if (inSingleComment || inMultiLineComment || inString || inVerbatimString) + break; + inChar = !inChar; + break; + } + } - var loc = document.GetLocation (offset); - var expr = Unit.GetNodeAt (loc.Line, loc.Column); - return expr != null && expr.Value is string; + return inSingleComment && singleLineIsDoc; } - + protected CSharpResolver GetState () { return new CSharpResolver (ctx);