diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 4dc86c496a..4f1ad1aa02 100644 --- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -176,7 +176,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.')) return null; } - + resolveResult = ResolveExpression (expr); if (resolveResult == null) return null; @@ -439,7 +439,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (identifierStart != null && identifierStart.Node is VariableInitializer && location <= ((VariableInitializer)identifierStart.Node).NameToken.EndLocation) { return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null; } - + if (identifierStart != null && identifierStart.Node is CatchClause) { if (((CatchClause)identifierStart.Node).VariableNameToken.Contains (location)) return null; @@ -474,7 +474,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion return HandleKeywordCompletion (tokenIndex, token); } } - + if (identifierStart == null) { var accCtx = HandleAccessorContext (); if (accCtx != null) @@ -486,7 +486,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (n != null && n.Parent is AnonymousTypeCreateExpression) { AutoSelect = false; } - + // Handle foreach (type name _ if (n is IdentifierExpression) { var prev = n.GetPrevNode () as ForeachStatement; @@ -506,7 +506,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (p != null) { var initializerResult = ResolveExpression (p, identifierStart.Unit); if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) { - + foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) { contextList.AddMember (m); } @@ -517,7 +517,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - + if (n != null && n.Parent is InvocationExpression) { var invokeParent = (InvocationExpression)n.Parent; var invokeResult = ResolveExpression (invokeParent.Target, identifierStart.Unit); @@ -546,16 +546,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion AutoSelect = false; AutoCompleteEmptyMatch = false; } - + } } } } - if (n != null && n.Parent is ObjectCreateExpression) { var invokeResult = ResolveExpression (n.Parent, identifierStart.Unit); var mgr = invokeResult != null ? invokeResult.Item1 as ResolveResult : null; - if (mgr != null) { foreach (var constructor in mgr.Type.GetConstructors ()) { foreach (var p in constructor.Parameters) { @@ -564,11 +562,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } } } - + if (n is IdentifierExpression) { var bop = n.Parent as BinaryOperatorExpression; Expression evaluationExpr = null; - + if (bop != null && bop.Right == n && (bop.Operator == BinaryOperatorType.Equality || bop.Operator == BinaryOperatorType.InEquality)) { evaluationExpr = bop.Left; } @@ -605,7 +603,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) { - + foreach (var property in initalizerResult.Item1.Type.GetProperties ()) { if (!property.IsPublic) continue; @@ -1710,19 +1708,29 @@ namespace ICSharpCode.NRefactory.CSharp.Completion n = n.Parent; return n is Attribute; } - + + IType GuessHintType (AstNode resolvedNode) + { + ObjectCreateExpression oce = resolvedNode.Parent as ObjectCreateExpression ?? (ObjectCreateExpression)resolvedNode.Ancestors.FirstOrDefault (n => n is ObjectCreateExpression); + if (oce != null && oce.Parent is ReturnStatement) + return ctx.CurrentMember != null ? ctx.CurrentMember.ReturnType : null; + return null; + } + IEnumerable CreateTypeAndNamespaceCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state) { if (resolveResult == null || resolveResult.IsError) return null; + + var hintType = GuessHintType (resolvedNode); var result = new CompletionDataWrapper (this); if (resolveResult is NamespaceResolveResult) { var nr = (NamespaceResolveResult)resolveResult; if (!(resolvedNode.Parent is UsingDeclaration || resolvedNode.Parent != null && resolvedNode.Parent.Parent is UsingDeclaration)) { - Console.WriteLine ("fooo"); foreach (var cl in nr.Namespace.Types) { string name = cl.Name; - + if (hintType != null && hintType.Kind != TypeKind.Array && cl.Kind == TypeKind.Interface) + continue; if (IsAttributeContext (resolvedNode) && name.EndsWith ("Attribute") && name.Length > "Attribute".Length) name = name.Substring (0, name.Length - "Attribute".Length); result.AddType (cl, name); @@ -1734,12 +1742,14 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } else if (resolveResult is TypeResolveResult) { var type = resolveResult.Type; foreach (var nested in type.GetNestedTypes ()) { + if (hintType != null && hintType.Kind != TypeKind.Array && nested.Kind == TypeKind.Interface) + continue; result.AddType (nested, nested.Name); } } return result.Result; } - + IEnumerable CreateTypeList () { foreach (var cl in Compilation.RootNamespace.Types) { @@ -2062,7 +2072,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion baseUnit = ParseStub ("a()"); curNode = baseUnit.GetNodeAt (location); } - + // Hack for handle object initializer continuation expressions if (curNode is EntityDeclaration || baseUnit.GetNodeAt (location) == null) { baseUnit = ParseStub ("a()};"); @@ -2079,7 +2089,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (invoke != null) mref = invoke.Target as MemberReferenceExpression; } - Expression expr = null; + AstNode expr = null; if (mref != null) { expr = mref.Target.Clone (); mref.Parent.ReplaceWith (expr); @@ -2089,37 +2099,46 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (memberType == null) { memberType = baseUnit.GetNodeAt (location); if (memberType != null) { - tref = baseUnit.GetNodeAt (location); - if (tref == null) { - tref = new TypeReferenceExpression (memberType.Clone ()); - memberType.Parent.AddChild (tref, AstNode.Roles.Expression); + if (memberType.Parent is ObjectCreateExpression) { + var mt = memberType.Target.Clone (); + memberType.ReplaceWith (mt); + expr = mt; + goto exit; + } else { + tref = baseUnit.GetNodeAt (location); + if (tref == null) { + tref = new TypeReferenceExpression (memberType.Clone ()); + memberType.Parent.AddChild (tref, AstNode.Roles.Expression); + } + if (tref is ObjectCreateExpression) { + expr = new TypeReferenceExpression (memberType.Target.Clone ()); + expr.AddAnnotation (new ObjectCreateExpression ()); + } } } - if (tref is ObjectCreateExpression) { - expr = new TypeReferenceExpression (memberType.Target.Clone ()); - expr.AddAnnotation (new ObjectCreateExpression ()); - } } - + if (memberType == null) return null; - if (expr == null) + if (expr == null) { expr = new TypeReferenceExpression (memberType.Target.Clone ()); + } tref.ReplaceWith (expr); } - + exit: var member = Unit.GetNodeAt (memberLocation); var member2 = baseUnit.GetNodeAt (memberLocation); member2.Remove (); member.ReplaceWith (member2); + Print (member2); return new ExpressionResult ((AstNode)expr, Unit); } - + ExpressionResult GetExpressionAtCursor () { // if (currentMember == null && currentType == null) // return null; - + TextLocation memberLocation; if (currentMember != null) { memberLocation = currentMember.Region.Begin; @@ -2145,6 +2164,9 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (expr == null) { baseUnit = ParseStub ("()"); expr = baseUnit.GetNodeAt (location.Line, location.Column - 1); + if (expr == null) { + expr = baseUnit.GetNodeAt (location.Line, location.Column - 1); + } } if (expr == null) { @@ -2152,17 +2174,17 @@ namespace ICSharpCode.NRefactory.CSharp.Completion expr = baseUnit.GetNodeAt (location, n => n is IdentifierExpression || n is MemberReferenceExpression || n is CatchClause); } - + // try statement if (expr == null) { expr = tmpUnit.GetNodeAt (location.Line, location.Column - 1); baseUnit = tmpUnit; } - + if (expr == null) { var block = tmpUnit.GetNodeAt (location); var node = block != null ? block.Statements.LastOrDefault () : null; - + var forStmt = node != null ? node.PrevSibling as ForStatement : null; if (forStmt != null && forStmt.EmbeddedStatement.IsNull) { expr = forStmt; @@ -2185,19 +2207,19 @@ namespace ICSharpCode.NRefactory.CSharp.Completion expr = tmpUnit.GetNodeAt (location.Line, location.Column - 1); 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); } - + // try expression in anonymous type "new { sample = x$" case if (expr == null) { baseUnit = ParseStub ("a", false); @@ -2209,12 +2231,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } if (expr == null) return null; - + var member = Unit.GetNodeAt (memberLocation); var member2 = baseUnit.GetNodeAt (memberLocation); if (member != null && member2 != null) { member2.Remove (); - + if (member is TypeDeclaration) { member.AddChild (member2, TypeDeclaration.MemberRole); } else {