Browse Source

Merge branch 'master' of github.com:icsharpcode/NRefactory

newNRvisualizers
Mike Krüger 14 years ago
parent
commit
3761df4dff
  1. 48
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  2. 165
      ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
  3. 8
      ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
  4. 75
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs
  5. 10
      ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/PreProcessorTests.cs

48
ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs

@ -207,6 +207,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return CreateCompletionData(location, resolveResult.Item1, expr.Node, resolveResult.Item2); return CreateCompletionData(location, resolveResult.Item1, expr.Node, resolveResult.Item2);
} }
bool IsInPreprocessorDirective()
{
var text = GetMemberTextToCaret().Item1;
var miniLexer = new MiniLexer(text);
miniLexer.Parse();
return miniLexer.IsInPreprocessorDirective;
}
IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace) IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace)
{ {
ExpressionResult expr; ExpressionResult expr;
@ -216,17 +224,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Magic key completion // Magic key completion
case ':': case ':':
case '.': case '.':
if (IsInsideCommentOrString()) { if (IsInsideCommentStringOrDirective()) {
return Enumerable.Empty<ICompletionData>(); return Enumerable.Empty<ICompletionData>();
} }
return HandleMemberReferenceCompletion(GetExpressionBeforeCursor()); return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
case '#': case '#':
if (IsInsideCommentOrString()) { if (!IsInPreprocessorDirective())
return null; return null;
}
return GetDirectiveCompletionData(); return GetDirectiveCompletionData();
// XML doc completion
// XML doc completion
case '<': case '<':
if (IsInsideDocComment()) { if (IsInsideDocComment()) {
return GetXmlDocumentationCompletionData(); return GetXmlDocumentationCompletionData();
@ -265,7 +271,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Parameter completion // Parameter completion
case '(': case '(':
if (IsInsideCommentOrString()) { if (IsInsideCommentStringOrDirective()) {
return null; return null;
} }
var invoke = GetInvocationBeforeCursor(true); var invoke = GetInvocationBeforeCursor(true);
@ -303,12 +309,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Completion on space: // Completion on space:
case ' ': case ' ':
if (IsInsideCommentOrString()) {
return null;
}
int tokenIndex = offset; int tokenIndex = offset;
string token = GetPreviousToken(ref tokenIndex, false); string token = GetPreviousToken(ref tokenIndex, false);
if (IsInsideCommentStringOrDirective()) {
if (IsInPreprocessorDirective())
return HandleKeywordCompletion(tokenIndex, token);
return null;
}
// check propose name, for context <variable name> <ctrl+space> (but only in control space context) // check propose name, for context <variable name> <ctrl+space> (but only in control space context)
//IType isAsType = null; //IType isAsType = null;
var isAsExpression = GetExpressionAt(offset); var isAsExpression = GetExpressionAt(offset);
@ -475,7 +482,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return keywordCompletion; return keywordCompletion;
// Automatic completion // Automatic completion
default: default:
if (IsInsideCommentOrString()) { if (IsInsideCommentStringOrDirective()) {
return null; return null;
} }
if (IsInLinqContext(offset)) { if (IsInLinqContext(offset)) {
@ -565,7 +572,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return null; return null;
} }
if (identifierStart == null && !string.IsNullOrEmpty(token) && !IsInsideCommentOrString() && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) { if (identifierStart == null && !string.IsNullOrEmpty(token) && !IsInsideCommentStringOrDirective() && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
char last = token [token.Length - 1]; char last = token [token.Length - 1];
if (char.IsLetterOrDigit(last) || last == '_' || token == ">") { if (char.IsLetterOrDigit(last) || last == '_' || token == ">") {
return HandleKeywordCompletion(tokenIndex, token); return HandleKeywordCompletion(tokenIndex, token);
@ -862,7 +869,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
bool IsInLinqContext(int offset) bool IsInLinqContext(int offset)
{ {
string token; string token;
while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideCommentOrString ()) { while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideCommentStringOrDirective ()) {
if (token == "from") { if (token == "from") {
return true; return true;
} }
@ -1166,7 +1173,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IEnumerable<ICompletionData> HandleKeywordCompletion(int wordStart, string word) IEnumerable<ICompletionData> HandleKeywordCompletion(int wordStart, string word)
{ {
if (IsInsideCommentOrString()) { if (IsInsideCommentStringOrDirective()) {
if (IsInPreprocessorDirective()) {
if (word == "if" || word == "elif") {
if (wordStart > 0 && document.GetCharAt(wordStart - 1) == '#') {
return factory.CreatePreProcessorDefinesCompletionData();
}
}
}
return null; return null;
} }
switch (word) { switch (word) {
@ -1485,12 +1499,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// } // }
// } // }
// return CreateCtrlSpaceCompletionData (completionContext, null); // return CreateCtrlSpaceCompletionData (completionContext, null);
case "if":
case "elif":
if (wordStart > 0 && document.GetCharAt(wordStart - 1) == '#') {
return factory.CreatePreProcessorDefinesCompletionData();
}
return null;
case "yield": case "yield":
var yieldDataList = new CompletionDataWrapper(this); var yieldDataList = new CompletionDataWrapper(this);
DefaultCompletionString = "return"; DefaultCompletionString = "return";

165
ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs

@ -245,74 +245,113 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
#region Context helper methods #region Context helper methods
protected bool IsInsideCommentOrString () public class MiniLexer
{ {
var text = GetMemberTextToCaret (); readonly string text;
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
public bool IsFistNonWs = true;
for (int i = 0; i < text.Item1.Length - 1; i++) { public bool IsInSingleComment = false;
char ch = text.Item1 [i]; public bool IsInString = false;
char nextCh = text.Item1 [i + 1]; public bool IsInVerbatimString = false;
public bool IsInChar = false;
switch (ch) { public bool IsInMultiLineComment = false;
case '/': public bool IsInPreprocessorDirective = false;
if (inString || inChar || inVerbatimString)
break; public MiniLexer(string text)
if (nextCh == '/') { {
i++; this.text = text;
inSingleComment = true; }
}
if (nextCh == '*') public void Parse(Action<char> act = null)
inMultiLineComment = true; {
break; Parse(0, text.Length, act);
case '*': }
if (inString || inChar || inVerbatimString || inSingleComment)
break; public void Parse(int start, int length, Action<char> act = null)
if (nextCh == '/') { {
i++; for (int i = start; i < length; i++) {
inMultiLineComment = false; char ch = text [i];
} char nextCh = i + 1 < text.Length ? text [i + 1] : '\0';
break; switch (ch) {
case '@': case '#':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) if (IsFistNonWs)
break; IsInPreprocessorDirective = true;
if (nextCh == '"') { break;
i++; case '/':
inVerbatimString = true; if (IsInString || IsInChar || IsInVerbatimString)
} break;
break; if (nextCh == '/') {
case '\n': i++;
case '\r': IsInSingleComment = true;
inSingleComment = false; }
inString = false; if (nextCh == '*')
inChar = false; IsInMultiLineComment = true;
break; break;
case '\\': case '*':
if (inString || inChar) if (IsInString || IsInChar || IsInVerbatimString || IsInSingleComment)
i++; break;
break; if (nextCh == '/') {
case '"': i++;
if (inSingleComment || inMultiLineComment || inChar) IsInMultiLineComment = false;
break; }
if (inVerbatimString) { break;
if (nextCh == '"') { case '@':
i++; if (IsInString || IsInChar || IsInVerbatimString || IsInSingleComment || IsInMultiLineComment)
break;
if (nextCh == '"') {
i++;
IsInVerbatimString = true;
}
break;
case '\n':
case '\r':
IsInSingleComment = false;
IsInString = false;
IsInChar = false;
IsFistNonWs = true;
break;
case '\\':
if (IsInString || IsInChar)
i++;
break;
case '"':
if (IsInSingleComment || IsInMultiLineComment || IsInChar)
break;
if (IsInVerbatimString) {
if (nextCh == '"') {
i++;
break;
}
IsInVerbatimString = false;
break;
}
IsInString = !IsInString;
break;
case '\'':
if (IsInSingleComment || IsInMultiLineComment || IsInString || IsInVerbatimString)
break;
IsInChar = !IsInChar;
break; break;
}
inVerbatimString = false;
break;
} }
inString = !inString; if (act != null)
break; act(ch);
case '\'': IsFistNonWs &= ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
if (inSingleComment || inMultiLineComment || inString || inVerbatimString)
break;
inChar = !inChar;
break;
} }
} }
}
return inSingleComment || inString || inVerbatimString || inChar || inMultiLineComment;
protected bool IsInsideCommentStringOrDirective()
{
var text = GetMemberTextToCaret();
var lexer = new MiniLexer(text.Item1);
lexer.Parse();
return
lexer.IsInSingleComment ||
lexer.IsInString ||
lexer.IsInVerbatimString ||
lexer.IsInChar ||
lexer.IsInMultiLineComment ||
lexer.IsInPreprocessorDirective;
} }
protected bool IsInsideDocComment () protected bool IsInsideDocComment ()

8
ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs

@ -1,4 +1,4 @@
// //
// CSharpParameterCompletionEngine.cs // CSharpParameterCompletionEngine.cs
// //
// Author: // Author:
@ -105,6 +105,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
//var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
var expr = baseUnit.GetNodeAt<AstType>(location.Line, location.Column + 1); var expr = baseUnit.GetNodeAt<AstType>(location.Line, location.Column + 1);
if (expr == null)
return null;
// '>' position // '>' position
return new ExpressionResult((AstNode)expr, baseUnit); return new ExpressionResult((AstNode)expr, baseUnit);
} }
@ -146,7 +148,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
SetOffset(offset); SetOffset(offset);
if (IsInsideCommentOrString()) { if (IsInsideCommentStringOrDirective()) {
return null; return null;
} }
@ -351,6 +353,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
bracketStack.Push(parameter); bracketStack.Push(parameter);
parameter = new Stack<int>(); parameter = new Stack<int>();
break; break;
case '[':
case '(': case '(':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break; break;
@ -367,6 +370,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return -1; return -1;
} }
break; break;
case ']':
case ')': case ')':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) { if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break; break;

75
ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionBugTests.cs

@ -4815,7 +4815,7 @@ class A
/// Bug 4017 - code completion in foreach does not work for local variables declared in the same block /// Bug 4017 - code completion in foreach does not work for local variables declared in the same block
/// </summary> /// </summary>
[Test()] [Test()]
public void TestBug4017 () public void TestBug4017()
{ {
var provider = CreateProvider ( var provider = CreateProvider (
@" @"
@ -4864,10 +4864,10 @@ namespace Test
/// Bug 4085 - code completion problem with generic dictionary /// Bug 4085 - code completion problem with generic dictionary
/// </summary> /// </summary>
[Test()] [Test()]
public void TestBug4085 () public void TestBug4085()
{ {
// Name proposal feature breaks here // Name proposal feature breaks here
var provider = CreateCtrlSpaceProvider ( var provider = CreateCtrlSpaceProvider(
@"using System.Collections.Generic; @"using System.Collections.Generic;
namespace Test namespace Test
{ {
@ -4881,8 +4881,75 @@ namespace Test
} }
"); ");
Assert.IsNotNull (provider.Find ("TestClass"), "'TestClass' not found."); Assert.IsNotNull(provider.Find("TestClass"), "'TestClass' not found.");
}
/// <summary>
/// Bug 4283 - Newresolver: completing constructor parameters
/// </summary>
[Ignore ("fixme")]
[Test()]
public void TestBug4283()
{
CombinedProviderTest(
@"class Program
{
$public Program (int test) : base(t$
}", provider => {
Assert.IsNotNull(provider.Find("test"), "'test' not found.");
});
}
[Ignore ("fixme")]
[Test()]
public void TestBug4283ThisCase()
{
CombinedProviderTest(
@"class Program
{
$public Program (int test) : this(t$
}", provider => {
Assert.IsNotNull(provider.Find("test"), "'test' not found.");
});
}
/// <summary>
/// Bug 4290 - Parameter completion exception inserting method with arguments before other methods
/// </summary>
[Test()]
public void TestBug4290()
{
// just test for exception
ParameterCompletionTests.CreateProvider (
@"using System;
namespace Test
{
class TestClass
{
$public static void Foo(string bar,$
public static void Main(string[] args)
{
}
}
}");
} }
/// <summary>
/// Bug 4174 - Intellisense popup after #region (same line)
/// </summary>
[Test()]
public void TestBug4174()
{
var provider = CreateProvider(
@"
namespace Test
{
class TestClass
{
$#region S$
}
}");
Assert.IsTrue(provider == null || provider.Count == 0);
}
} }
} }

10
ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/PreProcessorTests.cs

@ -55,6 +55,14 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
CodeCompletionBugTests.CombinedProviderTest (@"$#if $", provider => { CodeCompletionBugTests.CombinedProviderTest (@"$#if $", provider => {
Assert.IsNotNull (provider.Find ("DEBUG"), "define 'DEBUG' not found."); Assert.IsNotNull (provider.Find ("DEBUG"), "define 'DEBUG' not found.");
}); });
} }
[Test()]
public void TestIfInsideComment ()
{
CodeCompletionBugTests.CombinedProviderTest (@"$// #if $", provider => {
Assert.IsNull (provider.Find ("DEBUG"), "define 'DEBUG' found.");
});
}
} }
} }

Loading…
Cancel
Save