diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index d097d9c89b..a24ef83d29 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -170,7 +170,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return null; } - var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3); if (resolveResult == null) @@ -411,6 +410,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (IsInLinqContext (offset)) { tokenIndex = offset; token = GetPreviousToken (ref tokenIndex, false); // token last typed + if (!char.IsWhiteSpace (completionChar) && !linqKeywords.Contains (token)) + token = GetPreviousToken (ref tokenIndex, false); // token last typed + if (linqKeywords.Contains (token)) { if (token == "from") // after from no auto code completion. return null; @@ -657,7 +659,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion while (null != (token = GetPreviousToken (ref offset, true)) && !IsInsideComment (offset) && !IsInsideString (offset)) { if (token == "from") return true; - if (token == ";") + if (token == ";" || token == "{") return false; } return false; @@ -693,6 +695,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion offset--; } location = document.GetLocation (offset); + if (xp == null) xp = GetExpressionAtCursor (); AstNode node; @@ -705,6 +708,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion node = unit.GetNodeAt (location); rr = ResolveExpression (CSharpParsedFile, node, unit); } + if (node is Identifier && node.Parent is ForeachStatement) { var foreachStmt = (ForeachStatement)node.Parent; foreach (var possibleName in GenerateNameProposals (foreachStmt.VariableType)) { @@ -740,25 +744,31 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return wrapper.Result; } } - CSharpResolver csResolver; - if (node != null) { - var nodes = new List (); - var n = node; - nodes.Add (n); - if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) - nodes.Add (n.Parent); - var navigator = new NodeListResolveVisitorNavigator (nodes); - - var visitor = new ResolveVisitor (GetState (), xp != null ? xp.Item1 : CSharpParsedFile, navigator); - visitor.Scan (node); - try { - csResolver = visitor.GetResolverStateBefore (node); - } catch (Exception) { + CSharpResolver csResolver = null; + if (rr != null) + csResolver = rr.Item2; + if (csResolver == null) { + if (node != null) { + csResolver = GetState (); + var nodes = new List (); + var n = node; + nodes.Add (n); + if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) + nodes.Add (n.Parent); + var navigator = new NodeListResolveVisitorNavigator (nodes); + var visitor = new ResolveVisitor (csResolver, xp != null ? xp.Item1 : CSharpParsedFile, navigator); + visitor.Scan (node); + + try { + csResolver = visitor.GetResolverStateBefore (node); + Console.WriteLine (csResolver.LocalVariables.Count ()); + } catch (Exception e) { + Console.WriteLine ("E!!!" + e); + } + + } else { csResolver = GetState (); } - - } else { - csResolver = GetState (); } AddContextCompletion (wrapper, csResolver, node); @@ -770,6 +780,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion { if (state != null && !(node is AstType)) { foreach (var variable in state.LocalVariables) { + if (variable.Region.IsInside (location.Line, location.Column - 1)) + continue; wrapper.AddVariable (variable); } } @@ -1861,13 +1873,20 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (currentMember == null && currentType == null) return null; - baseUnit = ParseStub ("a()"); + baseUnit = ParseStub ("a()", false); var curNode = baseUnit.GetNodeAt (location); + + // hack for local variable declaration missing ';' issue - remove that if it works. + if (curNode is AttributedNode || baseUnit.GetNodeAt (location) == null) { + baseUnit = ParseStub ("a()"); + curNode = baseUnit.GetNodeAt (location); + } + // Hack for handle object initializer continuation expressions if (curNode is AttributedNode || baseUnit.GetNodeAt (location) == null) { baseUnit = ParseStub ("a()};"); } - + Print (baseUnit); var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; var mref = baseUnit.GetNodeAt (location); if (mref == null) { @@ -1979,8 +1998,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion baseUnit = tmpUnit; } } - - if (expr == null) { expr = tmpUnit.GetNodeAt (location.Line, location.Column - 1); baseUnit = tmpUnit; @@ -1998,6 +2015,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion expr = baseUnit.GetNodeAt (location.Line, location.Column - 1); } + // try expression in anonymous type "new { sample = x$" case + if (expr == null) { + baseUnit = ParseStub ("a };", false); + expr = baseUnit.GetNodeAt (location.Line, location.Column); + if (expr != null) + expr = baseUnit.GetNodeAt (location.Line, location.Column); + } + if (expr == null) return null; var member = Unit.GetNodeAt (memberLocation); diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs index a8317e891d..2d038cf089 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs @@ -343,6 +343,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } else { memberLocation = new TextLocation (1, 1); } + using (var stream = new System.IO.StringReader (wrapper.ToString ())) { try { var parser = new CSharpParser (); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionCSharp3Tests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionCSharp3Tests.cs index 798c7c1215..bdf8ab0d73 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionCSharp3Tests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeCompletion/CodeCompletionCSharp3Tests.cs @@ -368,5 +368,87 @@ class A Assert.IsNotNull(provider); // <--- here 0 item in the completion list Assert.IsNotNull(provider.Find("ToString")); } + + [Test()] + public void TestLinqSelectContext () + { + var provider = CodeCompletionBugTests.CreateProvider( +@" +using System.Collections.Generic; +using System.Linq; +class A +{ + public static void Main (string[] args) + { + $from a in args select n$ + } +} + +"); + Assert.IsNotNull(provider); // <--- here 0 item in the completion list + Assert.IsNotNull(provider.Find("new"), "'new' not found"); + Assert.IsNotNull(provider.Find("args"), "'args' not found"); + Assert.IsNotNull(provider.Find("a"), "'a' not found"); + } + + [Test()] + public void TestLinqAnonymousTypeContext () + { + var provider = CodeCompletionBugTests.CreateProvider( +@" +using System.Collections.Generic; +using System.Linq; +class A +{ + public static void Main (string[] args) + { + $from a in args select new { tes$ + } +} + +"); + Assert.IsTrue(provider == null || provider.Count == 0); // <--- here 0 item in the completion list + } + + [Test()] + public void TestLinqAnonymousTypeContextCase2 () + { + var provider = CodeCompletionBugTests.CreateProvider( +@" +using System.Collections.Generic; +using System.Linq; +class A +{ + public static void Main (string[] args) + { + $from a in args select new { test = a$ + } +} + +"); + Assert.IsNotNull(provider); // <--- here 0 item in the completion list + Assert.IsNotNull(provider.Find("a"), "'a' not found"); + Assert.IsNotNull(provider.Find("new"), "'new' not found"); + Assert.IsNotNull(provider.Find("args"), "'args' not found"); + } + + [Test()] + public void TestLinqAnonymousTypeContextCase3 () + { + var provider = CodeCompletionBugTests.CreateProvider( +@" +using System.Collections.Generic; +using System.Linq; +class A +{ + public static void Main (string[] args) + { + $from a in args select new { test = a }$ + } +} + +"); + Assert.IsTrue(provider == null || provider.Count == 0); // <--- here 0 item in the completion list + } } }