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 @@ -207,6 +207,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
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)
{
ExpressionResult expr;
@ -216,17 +224,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -216,17 +224,15 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Magic key completion
case ':':
case '.':
if (IsInsideCommentOrString()) {
if (IsInsideCommentStringOrDirective()) {
return Enumerable.Empty<ICompletionData>();
}
return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
case '#':
if (IsInsideCommentOrString()) {
if (!IsInPreprocessorDirective())
return null;
}
return GetDirectiveCompletionData();
// XML doc completion
// XML doc completion
case '<':
if (IsInsideDocComment()) {
return GetXmlDocumentationCompletionData();
@ -265,7 +271,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -265,7 +271,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Parameter completion
case '(':
if (IsInsideCommentOrString()) {
if (IsInsideCommentStringOrDirective()) {
return null;
}
var invoke = GetInvocationBeforeCursor(true);
@ -303,12 +309,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -303,12 +309,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// Completion on space:
case ' ':
if (IsInsideCommentOrString()) {
return null;
}
int tokenIndex = offset;
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)
//IType isAsType = null;
var isAsExpression = GetExpressionAt(offset);
@ -475,7 +482,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -475,7 +482,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return keywordCompletion;
// Automatic completion
default:
if (IsInsideCommentOrString()) {
if (IsInsideCommentStringOrDirective()) {
return null;
}
if (IsInLinqContext(offset)) {
@ -565,7 +572,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -565,7 +572,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
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];
if (char.IsLetterOrDigit(last) || last == '_' || token == ">") {
return HandleKeywordCompletion(tokenIndex, token);
@ -862,7 +869,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -862,7 +869,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
bool IsInLinqContext(int offset)
{
string token;
while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideCommentOrString ()) {
while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideCommentStringOrDirective ()) {
if (token == "from") {
return true;
}
@ -1166,7 +1173,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1166,7 +1173,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
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;
}
switch (word) {
@ -1485,12 +1499,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion @@ -1485,12 +1499,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
// }
// }
// return CreateCtrlSpaceCompletionData (completionContext, null);
case "if":
case "elif":
if (wordStart > 0 && document.GetCharAt(wordStart - 1) == '#') {
return factory.CreatePreProcessorDefinesCompletionData();
}
return null;
case "yield":
var yieldDataList = new CompletionDataWrapper(this);
DefaultCompletionString = "return";

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

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

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

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

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

@ -4815,7 +4815,7 @@ class A @@ -4815,7 +4815,7 @@ class A
/// Bug 4017 - code completion in foreach does not work for local variables declared in the same block
/// </summary>
[Test()]
public void TestBug4017 ()
public void TestBug4017()
{
var provider = CreateProvider (
@"
@ -4864,10 +4864,10 @@ namespace Test @@ -4864,10 +4864,10 @@ namespace Test
/// Bug 4085 - code completion problem with generic dictionary
/// </summary>
[Test()]
public void TestBug4085 ()
public void TestBug4085()
{
// Name proposal feature breaks here
var provider = CreateCtrlSpaceProvider (
var provider = CreateCtrlSpaceProvider(
@"using System.Collections.Generic;
namespace Test
{
@ -4881,8 +4881,75 @@ 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 @@ -55,6 +55,14 @@ namespace ICSharpCode.NRefactory.CSharp.CodeCompletion
CodeCompletionBugTests.CombinedProviderTest (@"$#if $", provider => {
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