From 49e1b67a3a68dbdea4874c1b8564f1081b4f890c Mon Sep 17 00:00:00 2001 From: mike <> Date: Sat, 5 May 2012 08:35:28 +0200 Subject: [PATCH] [Completion] GetParameterCompletionCommandOffset is now reusable/removed code duplication of GetCurrentParameterIndex. --- .../Completion/CSharpCompletionEngine.cs | 2 +- .../Completion/CSharpCompletionEngineBase.cs | 190 +++++++++++------- .../CSharpParameterCompletionEngine.cs | 139 +------------ 3 files changed, 122 insertions(+), 209 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 306d2c02ec..30def5d158 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -428,7 +428,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (!GetParameterCompletionCommandOffset(out cpos)) { break; } - int currentParameter = GetCurrentParameterIndex(cpos, 0) - 1; + int currentParameter = GetCurrentParameterIndex(cpos - 1, this.offset) - 1; if (currentParameter < 0) { return null; } diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs index d53f0c7515..7ec124b5cb 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs @@ -91,7 +91,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion set; } - protected void SetOffset (int offset) + public void SetOffset (int offset) { Reset (); @@ -101,7 +101,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion provider.GetCurrentMembers (offset, out currentType, out currentMember); } - protected bool GetParameterCompletionCommandOffset(out int cpos) + public bool GetParameterCompletionCommandOffset (out int cpos) { // Start calculating the parameter offset from the beginning of the // current member, instead of the beginning of the file. @@ -110,12 +110,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (mem == null || (mem is IType)) { return false; } - int startPos = document.GetOffset(mem.Region.BeginLine, mem.Region.BeginColumn); + int startPos = document.GetOffset (mem.Region.BeginLine, mem.Region.BeginColumn); int parenDepth = 0; int chevronDepth = 0; - Stack indexStack = new Stack(); + Stack indexStack = new Stack (); while (cpos > startPos) { - char c = document.GetCharAt(cpos); + char c = document.GetCharAt (cpos); if (c == ')') { parenDepth++; } @@ -124,14 +124,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } if (c == '}') { if (indexStack.Count > 0) { - parenDepth = indexStack.Pop(); + parenDepth = indexStack.Pop (); } else { parenDepth = 0; } chevronDepth = 0; } if (indexStack.Count == 0 && (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<')) { - int p = GetCurrentParameterIndex (cpos + 1, startPos); + int p = GetCurrentParameterIndex (startPos, cpos + 1); if (p != -1) { cpos++; return true; @@ -154,94 +154,144 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return false; } - protected int GetCurrentParameterIndex (int offset, int memberStart) + public int GetCurrentParameterIndex (int triggerOffset, int endOffset) { - int cursor = this.offset; - int i = offset; - - if (i > cursor) { - return -1; + char lastChar = document.GetCharAt (endOffset - 1); + if (lastChar == '(' || lastChar == '<') { + return 0; } - if (i == cursor) { - return 1; - } - // parameters are 1 based - int index = memberStart + 1; - int parentheses = 0; - int bracket = 0; - bool insideQuote = false, insideString = false, insideSingleLineComment = false, insideMultiLineComment = false; - Stack indexStack = new Stack (); - do { - char c = document.GetCharAt (i - 1); - switch (c) { - case '\\': - if (insideString || insideQuote) { - i++; + var parameter = new Stack (); + var bracketStack = new Stack> (); + bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false; + for (int i = triggerOffset; i < endOffset; i++) { + char ch = document.GetCharAt (i); + char nextCh = i + 1 < document.TextLength ? document.GetCharAt (i + 1) : '\0'; + switch (ch) { + case '{': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; } + bracketStack.Push (parameter); + parameter = new Stack (); break; - case '\'': - if (!insideString && !insideSingleLineComment && !insideMultiLineComment) { - insideQuote = !insideQuote; + case '[': + case '(': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; } + parameter.Push (0); break; - case '"': - if (!insideQuote && !insideSingleLineComment && !insideMultiLineComment) { - insideString = !insideString; + case '}': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + if (bracketStack.Count > 0) { + parameter = bracketStack.Pop (); + } else { + return -1; + } + break; + case ']': + case ')': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + if (parameter.Count > 0) { + parameter.Pop (); + } else { + return -1; + } + break; + case '<': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + parameter.Push (0); + break; + case '>': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + if (parameter.Count > 0) { + parameter.Pop (); + } + break; + case ',': + if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { + break; + } + if (parameter.Count > 0) { + parameter.Push (parameter.Pop () + 1); } break; case '/': - if (!insideQuote && !insideString && !insideMultiLineComment) { - if (document.GetCharAt (i) == '/') { - insideSingleLineComment = true; - } - if (document.GetCharAt (i) == '*') { - insideMultiLineComment = true; - } + if (inString || inChar || inVerbatimString) { + break; + } + if (nextCh == '/') { + i++; + inSingleComment = true; + } + if (nextCh == '*') { + inMultiLineComment = true; } break; case '*': - if (insideMultiLineComment && document.GetCharAt (i) == '/') { - insideMultiLineComment = false; + 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': - insideSingleLineComment = false; - break; - case '{': - if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) { - bracket++; - indexStack.Push (index); - } + inSingleComment = false; + inString = false; + inChar = false; break; - case '}': - if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) { - bracket--; - if (indexStack.Count > 0) - index = indexStack.Pop (); + case '\\': + if (inString || inChar) { + i++; } break; - case '(': - if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) { - parentheses++; + case '"': + if (inSingleComment || inMultiLineComment || inChar) { + break; } - break; - case ')': - if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) { - parentheses--; + if (inVerbatimString) { + if (nextCh == '"') { + i++; + break; + } + inVerbatimString = false; + break; } + inString = !inString; break; - case ',': - if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment && parentheses == 1 && bracket == 0) { - index++; + case '\'': + if (inSingleComment || inMultiLineComment || inString || inVerbatimString) { + break; } + inChar = !inChar; break; - } - i++; - } while (i <= cursor && parentheses >= 0); - Console.WriteLine (indexStack.Count >= 0 || parentheses != 1 || bracket > 0 ? -1 : index); - return indexStack.Count >= 0 || parentheses != 1 || bracket > 0 ? -1 : index; + } + if (parameter.Count == 0 || bracketStack.Count > 0) { + return -1; + } + + return parameter.Pop() + 1; } #region Context helper methods diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs index 76c266244c..4c740193d7 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs @@ -335,144 +335,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return result; } - public int GetCurrentParameterIndex(int triggerOffset, int endOffset) - { - char lastChar = document.GetCharAt(endOffset - 1); - if (lastChar == '(' || lastChar == '<') { - return 0; - } - var parameter = new Stack(); - var bracketStack = new Stack>(); - bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false; - for (int i = triggerOffset; i < endOffset; i++) { - char ch = document.GetCharAt(i); - char nextCh = i + 1 < document.TextLength ? document.GetCharAt(i + 1) : '\0'; - switch (ch) { - case '{': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { - break; - } - bracketStack.Push(parameter); - parameter = new Stack(); - break; - case '[': - case '(': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { - break; - } - parameter.Push(0); - break; - case '}': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { - break; - } - if (bracketStack.Count > 0) { - parameter = bracketStack.Pop(); - } else { - return -1; - } - break; - case ']': - case ')': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { - break; - } - if (parameter.Count > 0) { - parameter.Pop(); - } else { - return -1; - } - break; - case '<': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { - break; - } - parameter.Push(0); - break; - case '>': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { - break; - } - if (parameter.Count > 0) { - parameter.Pop(); - } - break; - case ',': - if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { - break; - } - if (parameter.Count > 0) { - parameter.Push(parameter.Pop() + 1); - } - break; - case '/': - if (inString || inChar || inVerbatimString) { - break; - } - if (nextCh == '/') { - i++; - inSingleComment = true; - } - 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; - } - } - if (parameter.Count == 0 || bracketStack.Count > 0) { - return -1; - } - return parameter.Pop() + 1; - } + } }