From 5069b98f17d7753e712bef3b6d15c817e1ea7a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Kr=C3=BCger?= Date: Mon, 14 Nov 2011 23:02:24 +0100 Subject: [PATCH] Fixed code completion bug. --- .../Completion/CSharpCompletionEngine.cs | 17 +++---- .../Completion/CSharpCompletionEngineBase.cs | 17 +++++-- .../CSharpParameterCompletionEngine.cs | 7 ++- .../CSharp/CodeCompletion/KeywordTests.cs | 48 +++++++++++++++++++ .../ParameterCompletionTests.cs | 24 +++++++++- .../ICSharpCode.NRefactory.csproj | 2 +- 6 files changed, 96 insertions(+), 19 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 8c168f3c81..3e3b18150e 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -91,7 +91,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion { if (type is PrimitiveType) { var pt = (PrimitiveType)type; - Console.WriteLine (pt.Keyword); switch (pt.Keyword) { case "object": yield return "o"; @@ -413,7 +412,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } var contextList = new CompletionDataWrapper (this); - var identifierStart = GetExpressionAtCursor (); if (identifierStart != null && identifierStart.Item2 is VariableInitializer && location <= ((VariableInitializer)identifierStart.Item2).NameToken.EndLocation) { return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems () : null; @@ -421,8 +419,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) { return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems () : null; } - - char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : '\0'; + char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : ';'; char nextCh = offset < document.TextLength ? document.GetCharAt (offset) : ' '; const string allowedChars = ";,[](){}+-*/%^?:&|~!<>="; if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0) @@ -435,7 +432,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex))) { char last = token [token.Length - 1]; if (char.IsLetterOrDigit (last) || last == '_' || token == ">") { - return null; + return controlSpace ? DefaultControlSpaceItems () : null; } } if (identifierStart == null) @@ -607,7 +604,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion IEnumerable DefaultControlSpaceItems () { var wrapper = new CompletionDataWrapper (this); - while (offset > 0 && char.IsWhiteSpace (document.GetCharAt (offset))) { + while (offset > 1 && char.IsWhiteSpace (document.GetCharAt (offset))) { offset--; } location = document.GetLocation (offset); @@ -630,10 +627,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion void AddContextCompletion (CompletionDataWrapper wrapper, CSharpResolver state, AstNode node) { - if (state == null) - return; - foreach (var variable in state.LocalVariables) { - wrapper.AddVariable (variable); + if (state != null) { + foreach (var variable in state.LocalVariables) { + wrapper.AddVariable (variable); + } } if (currentMember is IParameterizedMember) { diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs index 0f268ccc0a..b9570aca58 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs @@ -293,7 +293,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion bool wrapInClass = mt.Item2; var wrapper = new StringBuilder (); + if (wrapInClass) { +/* foreach (var child in Unit.Children) { + if (child is UsingDeclaration) { + var offset = document.GetOffset (child.StartLocation); + wrapper.Append (document.GetText (offset, document.GetOffset (child.EndLocation) - offset)); + } + }*/ wrapper.Append ("class Stub {"); wrapper.AppendLine (); } @@ -313,7 +320,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } else { memberLocation = new TextLocation (1, 1); } - using (var stream = new System.IO.StringReader (wrapper.ToString ())) { var parser = new CSharpParser (); return parser.Parse (stream, wrapInClass ? memberLocation.Line - 2 : 0); @@ -337,6 +343,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } else { startOffset = 0; } + while (startOffset > 0) { + char ch = document.GetCharAt (startOffset - 1); + if (ch != ' ' && ch != '\t') + break; + --startOffset; + } if (cachedText == null) cachedText = document.GetText (startOffset, offset - startOffset); @@ -374,7 +386,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } else { return null; } - +// Print (baseUnit); /* var member = Unit.GetNodeAt (memberLocation); var member2 = baseUnit.GetNodeAt (memberLocation); member2.Remove (); @@ -450,7 +462,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion var visitor = new ResolveVisitor (csResolver, file, navigator); visitor.Scan (unit); -// Print (unit); var state = visitor.GetResolverStateBefore (resolveNode); var result = visitor.GetResolveResult (resolveNode); if (ProjectContent is SimpleProjectContent) diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs index 5bc8eafb4b..4722cf9b15 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs @@ -98,22 +98,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return null; return factory.CreateConstructorProvider (attribute.Item1.Type); } - var invocationExpression = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3); - if (invocationExpression == null || invocationExpression.Item1 == null || invocationExpression.Item1.IsError) return null; resolveResult = invocationExpression.Item1; if (resolveResult is MethodGroupResolveResult) return factory.CreateMethodDataProvider (resolveResult as MethodGroupResolveResult); if (resolveResult is MemberResolveResult) { - if (resolveResult.Type.Kind == TypeKind.Delegate) - return factory.CreateDelegateDataProvider (resolveResult.Type); var mr = resolveResult as MemberResolveResult; if (mr.Member is IMethod) return factory.CreateMethodDataProvider ((IMethod)mr.Member); } + if (resolveResult.Type.Kind == TypeKind.Delegate) + return factory.CreateDelegateDataProvider (resolveResult.Type); + // // if (result.ExpressionContext == ExpressionContext.BaseConstructorCall) { // if (resolveResult is ThisResolveResult) diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/KeywordTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/KeywordTests.cs index 578df45cb1..a48dcf4c75 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/KeywordTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/KeywordTests.cs @@ -168,6 +168,54 @@ class Test Assert.IsNotNull (provider.Find ("as"), "keyword 'as' not found."); }); } + + [Test()] + public void PublicClassContextTest () + { + CodeCompletionBugTests.CombinedProviderTest (@"$c$", +provider => { + Assert.IsNotNull (provider.Find ("class"), "keyword 'class' not found."); + Assert.IsNotNull (provider.Find ("static"), "keyword 'static' not found."); + Assert.IsNotNull (provider.Find ("sealed"), "keyword 'sealed' not found."); + + }); + } + + [Ignore()] + [Test()] + public void PublicClassContextTest2 () + { + CodeCompletionBugTests.CombinedProviderTest (@"public $c$", +provider => { + Assert.IsNotNull (provider.Find ("class"), "keyword 'class' not found."); + Assert.IsNotNull (provider.Find ("static"), "keyword 'static' not found."); + Assert.IsNotNull (provider.Find ("sealed"), "keyword 'sealed' not found."); + + }); + } + + [Ignore()] + [Test()] + public void PublicClassContextTestContinuation1 () + { + CodeCompletionBugTests.CombinedProviderTest (@"public static $c$", +provider => { + Assert.IsNotNull (provider.Find ("class"), "keyword 'class' not found."); + + }); + } + + [Ignore()] + [Test()] + public void PublicClassContextTestContinuation2 () + { + CodeCompletionBugTests.CombinedProviderTest (@"public sealed $c$", +provider => { + Assert.IsNotNull (provider.Find ("class"), "keyword 'class' not found."); + + }); + } + } } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs index cea697ea52..05c00a3839 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/ParameterCompletionTests.cs @@ -435,5 +435,27 @@ class TestClass }"); Assert.IsNotNull (provider, "provider was not created."); Assert.AreEqual (1, provider.OverloadCount); - }} + } + + + /// Bug 599 - Regression: No intellisense over Func delegate + [Test()] + public void TestBug599 () + { + var provider = CreateProvider ( +@"using System; +using System.Core; + +class TestClass +{ + void A (Func f) + { + $f ($ + } +}"); + Assert.IsNotNull (provider, "provider was not created."); + Assert.AreEqual (1, provider.OverloadCount); + } + + } } \ No newline at end of file diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 58e74ff430..160f5079c4 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -17,7 +17,7 @@ False -Microsoft.Design#CA1026;-Microsoft.Security#CA2104 true - snk + ..\ICSharpCode.NRefactory.snk False File