From d78d5f17276100a7a60f8bd055b53a2666f5c0e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Kr=C3=BCger?= Date: Mon, 12 Dec 2011 18:26:34 +0100 Subject: [PATCH] Fixed "type too fast" issue in code completion. --- .../Completion/CSharpCompletionEngine.cs | 36 +++++++++++++------ .../Completion/CSharpCompletionEngineBase.cs | 29 ++++++++++++--- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index ff10813d74..355d4575a3 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -23,7 +23,6 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - using System; using System.Collections.Generic; using System.Linq; @@ -416,6 +415,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion var contextList = new CompletionDataWrapper (this); var identifierStart = GetExpressionAtCursor (); + + if (identifierStart != null && identifierStart.Item2 is TypeParameterDeclaration) + return null; + if (identifierStart != null && identifierStart.Item2 is VariableInitializer && location <= ((VariableInitializer)identifierStart.Item2).NameToken.EndLocation) { return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems () : null; } @@ -440,6 +443,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return HandleKeywordCompletion (tokenIndex, token); } } + if (identifierStart == null) return HandleAccessorContext () ?? DefaultControlSpaceItems (); @@ -462,14 +466,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return DefaultControlSpaceItems (); return null; } - if (n is ArrayInitializerExpression) { var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3); var concreteNode = identifierStart.Item3.GetNodeAt (location); // check if we're on the right side of an initializer expression - if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) + if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) { return DefaultControlSpaceItems (); + } if (initalizerResult != null) { @@ -603,7 +607,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return null; } - bool IsInLinqContext (int offset) { string token; @@ -698,7 +701,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion Predicate typePred = null; if (node is Attribute) { - var attribute = Compilation.FindType (typeof (System.Attribute)); + var attribute = Compilation.FindType (typeof(System.Attribute)); typePred = t => { return t.GetAllBaseTypeDefinitions ().Any (bt => bt.Equals (attribute)); }; @@ -756,8 +759,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - if (currentMember != null) { - foreach (var member in ctx.CurrentTypeDefinition.GetMembers ()) { + if (this.currentMember != null) { + var def = ctx.CurrentTypeDefinition ?? Compilation.MainAssembly.GetTypeDefinition (currentType); + foreach (var member in def.GetMembers ()) { if (memberPred == null || memberPred (member)) wrapper.AddMember (member); } @@ -1019,7 +1023,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion foreach (var a in invoke.Arguments) { if (a == expressionOrVariableDeclaration.Item2) { if (mgr.Member.Parameters.Count > i1) - hintType = mgr.Member.Parameters[i1].Type; + hintType = mgr.Member.Parameters [i1].Type; break; } i1++; @@ -1038,7 +1042,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion foreach (var a in invoke.Arguments) { if (a == expressionOrVariableDeclaration.Item2) { if (mgr.Member.Parameters.Count > i1) - hintType = mgr.Member.Parameters[i1].Type; + hintType = mgr.Member.Parameters [i1].Type; break; } i1++; @@ -1225,7 +1229,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion addedVirtuals = true; } if (!addedVirtuals) - AddVirtuals (alreadyInserted, wrapper, type.Resolve (ctx).GetDefinition (), modifiers, Compilation.FindType(typeof(object)).GetDefinition (), declarationBegin); + AddVirtuals (alreadyInserted, wrapper, type.Resolve (ctx).GetDefinition (), modifiers, Compilation.FindType (typeof(object)).GetDefinition (), declarationBegin); return wrapper.Result; } @@ -1875,6 +1879,18 @@ namespace ICSharpCode.NRefactory.CSharp.Completion baseUnit = tmpUnit; } + // try parameter declaration type + if (expr == null) { + baseUnit = ParseStub (">", false, "{}"); + expr = baseUnit.GetNodeAt (location.Line, location.Column - 1); + } + + // try parameter declaration method + if (expr == null) { + baseUnit = ParseStub ("> ()", false, "{}"); + expr = baseUnit.GetNodeAt (location.Line, location.Column - 1); + } + 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 a45bd0ce24..d7addc49e0 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs @@ -23,7 +23,6 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - using System; using System.Collections.Generic; using System.Linq; @@ -59,6 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion public IProjectContent ProjectContent { get; set; } ICompilation compilation; + protected ICompilation Compilation { get { if (compilation == null) @@ -69,6 +69,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion #endregion + IUnresolvedTypeDefinition FindInnerType (IUnresolvedTypeDefinition parent, TextLocation location) + { + var currentType = parent; + foreach (var type in parent.NestedTypes) { + if (type.Region.Begin < location && location < type.Region.End) + currentType = FindInnerType (type, location); + } + + return currentType; + } protected void SetOffset (int offset) { Reset (); @@ -76,7 +86,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion this.offset = offset; this.location = document.GetLocation (offset); - this.currentType = CSharpParsedFile.GetInnermostTypeDefinition (location); + this.currentType = null; + + foreach (var type in CSharpParsedFile.TopLevelTypeDefinitions) { + if (type.Region.Begin < location) + currentType = type; + } + currentType = FindInnerType (currentType, location); + this.currentMember = null; if (this.currentType != null) { foreach (var member in currentType.Members) { @@ -293,7 +310,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } - protected CompilationUnit ParseStub (string continuation, bool appendSemicolon = true) + protected CompilationUnit ParseStub (string continuation, bool appendSemicolon = true, string afterContinuation = null) { var mt = GetMemberTextToCaret (); if (mt == null) @@ -318,6 +335,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion wrapper.Append (memberText); wrapper.Append (continuation); AppendMissingClosingBrackets (wrapper, memberText, appendSemicolon); + wrapper.Append (afterContinuation); if (wrapInClass) wrapper.Append ('}'); @@ -330,11 +348,12 @@ 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 (); - return parser.Parse (stream, "stub.cs" , wrapInClass ? memberLocation.Line - 2 : 0); - } catch (Exception){ + return parser.Parse (stream, "stub.cs", wrapInClass ? memberLocation.Line - 2 : 0); + } catch (Exception) { Console.WriteLine ("------"); Console.WriteLine (wrapper); throw;