IEnumerable<ICompletionData> HandleObjectInitializer(CompilationUnit unit, AstNode n)
{
var p = n.Parent;
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);
if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {
// check 3 cases:
// 1) New initalizer { xpr
// 2) Object initializer { prop = val1, field = val2, xpr
// 3) 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);
// case 3)
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);
}
if (prev != null && (prev is NamedExpression)) {
// case 2)
return contextList.Result;
}
// case 1)
// check if the object is a list, if not only provide object initalizers
var list = typeof(System.Collections.IList).ToTypeReference().Resolve(Compilation);
if (initializerResult.Item1.Type.Kind != TypeKind.Array && list != null) {
var def = initializerResult.Item1.Type.GetDefinition();
if (def != null && !def.IsDerivedFrom(list.GetDefinition()))
return contextList.Result;
}
AddContextCompletion(contextList, GetState(), n);
return contextList.Result;
}
}
return null;
}