diff options
author | Mike Krüger <mkrueger@xamarin.com> | 2012-04-26 16:40:27 +0400 |
---|---|---|
committer | Mike Krüger <mkrueger@xamarin.com> | 2012-04-26 16:41:17 +0400 |
commit | 0a50001cbcf00ad6c7ec70137eb6a5841badf94b (patch) | |
tree | c25777af0007369a2abc80d12c805f0dba491d0b | |
parent | 03a133b33f8157718f9c4807e69adc5cf010e987 (diff) |
Fixed 'Bug 4591 - ctrl-space doesn't offer correct completion options
in object initializers'.
-rw-r--r-- | main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs | 32 | ||||
-rw-r--r-- | main/contrib/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs | 34 |
2 files changed, 56 insertions, 10 deletions
diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs index 5f35bd970f..cba56bf327 100644 --- a/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs +++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs @@ -221,19 +221,41 @@ namespace ICSharpCode.NRefactory.CSharp.Completion while (p != null && !(p is ObjectCreateExpression)) { p = p.Parent; } + var parent = (ArrayInitializerExpression)n.Parent; + if (parent.IsSingleElement) + parent = (ArrayInitializerExpression)parent.Parent; if (p != null) { var contextList = new CompletionDataWrapper(this); var initializerResult = ResolveExpression(p, unit); if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) { + // check 3 cases: + // New initalizer { xpr + // Object initializer { prop = val1, field = val2, xpr + // Array initializer { new Foo (), a, xpr + // in case 1 all object/array initializer options should be given - in the others not. + + AstNode prev = null; + if (parent.Elements.Count > 1) { + prev = parent.Elements.First(); + if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement) + prev = ((ArrayInitializerExpression)prev).Elements.FirstOrDefault(); + } + + if (prev != null && !(prev is NamedExpression)) { + AddContextCompletion(contextList, GetState(), n, unit); + return contextList.Result; + } foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) { contextList.AddMember(m); } - var enumerableType = typeof(IEnumerable<>).ToTypeReference().Resolve(ctx); - // check if we may be in a collection initializer, or enumerable initializer - if (enumerableType.Kind == TypeKind.Unknown || !initializerResult.Item1.Type.GetDefinition().IsDerivedFrom(enumerableType.GetDefinition())) { + + if (prev != null && (prev is NamedExpression)) return contextList.Result; - } + + AddContextCompletion(contextList, GetState(), n, unit); + return contextList.Result; + } } return null; @@ -745,6 +767,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion } return null; } + if (n is ArrayInitializerExpression) { // check for new [] {...} expression -> no need to resolve the type there var parent = n.Parent as ArrayCreateExpression; @@ -759,7 +782,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) { return DefaultControlSpaceItems(); } - if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) { foreach (var property in initalizerResult.Item1.Type.GetProperties ()) { diff --git a/main/contrib/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs b/main/contrib/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs index 9932fbd614..6af959b4cf 100644 --- a/main/contrib/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs +++ b/main/contrib/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/CreateFieldAction.cs @@ -131,6 +131,24 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring } } + static IType GetElementType(CSharpAstResolver resolver, IType type) + { + // TODO: A better get element type method. + if (type.Kind == TypeKind.Array || type.Kind == TypeKind.Dynamic) { + if (type.Kind == TypeKind.Array) + return ((ArrayType)type).ElementType; + return resolver.Compilation.FindType(KnownTypeCode.Object); + } + + foreach (var method in type.GetMethods (m => m.Name == "GetEnumerator")) { + var pr = method.ReturnType.GetProperties(p => p.Name == "Current").FirstOrDefault(); + if (pr != null) + return pr.ReturnType; + } + + return resolver.Compilation.FindType(KnownTypeCode.Object); + } + internal static IEnumerable<IType> GetValidTypes(CSharpAstResolver resolver, Expression expr) { if (expr.Parent is DirectionExpression) { @@ -141,12 +159,18 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring } } + if (expr.Parent is ArrayInitializerExpression) { + var aex = expr.Parent as ArrayInitializerExpression; + if (aex.IsSingleElement) + aex = aex.Parent as ArrayInitializerExpression; + var type = GetElementType(resolver, resolver.Resolve(aex.Parent).Type); + if (type.Kind != TypeKind.Unknown) + return new [] { type }; + } + if (expr.Parent is ObjectCreateExpression) { - var parent = expr.Parent; - if (parent is ObjectCreateExpression) { - var invoke = (ObjectCreateExpression)parent; - return GetAllValidTypesFromObjectCreation(resolver, invoke, expr); - } + var invoke = (ObjectCreateExpression)expr.Parent; + return GetAllValidTypesFromObjectCreation(resolver, invoke, expr); } if (expr.Parent is ArrayCreateExpression) { |