return indexer;
}
- if (type != InternalType.ErrorType) {
- ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
- type.GetSignatureForError ());
- }
+ Error_CannotApplyIndexing (ec, type, loc);
return null;
}
return CreateExpressionFactoryCall (ec, "ArrayIndex", args);
}
+ public static void Error_CannotApplyIndexing (ResolveContext rc, TypeSpec type, Location loc)
+ {
+ if (type != InternalType.ErrorType) {
+ rc.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'",
+ type.GetSignatureForError ());
+ }
+ }
+
public override bool HasConditionalAccess ()
{
return ConditionalAccess || Expr.HasConditionalAccess ();
//
// Indexer access expression
//
- sealed class IndexerExpr : PropertyOrIndexerExpr<IndexerSpec>, OverloadResolver.IBaseMembersProvider
+ class IndexerExpr : PropertyOrIndexerExpr<IndexerSpec>, OverloadResolver.IBaseMembersProvider
{
IList<MemberSpec> indexers;
Arguments arguments;
TypeSpec queried_type;
public IndexerExpr (IList<MemberSpec> indexers, TypeSpec queriedType, ElementAccess ea)
- : base (ea.Location)
+ : this (indexers, queriedType, ea.Expr, ea.Arguments, ea.Location)
+ {
+ }
+
+ public IndexerExpr (IList<MemberSpec> indexers, TypeSpec queriedType, Expression instance, Arguments args, Location loc)
+ : base (loc)
{
this.indexers = indexers;
this.queried_type = queriedType;
- this.InstanceExpression = ea.Expr;
- this.arguments = ea.Arguments;
+ this.InstanceExpression = instance;
+ this.arguments = args;
}
#region Properties
{
this.Name = name;
}
+
+ public bool IsDictionaryInitializer {
+ get {
+ return Name == null;
+ }
+ }
protected override void CloneTo (CloneContext clonectx, Expression t)
{
if (source == null)
return EmptyExpressionStatement.Instance;
- var t = ec.CurrentInitializerVariable.Type;
+ if (!ResolveElement (ec))
+ return null;
+
+ if (source is CollectionOrObjectInitializers) {
+ Expression previous = ec.CurrentInitializerVariable;
+ ec.CurrentInitializerVariable = target;
+ source = source.Resolve (ec);
+ ec.CurrentInitializerVariable = previous;
+ if (source == null)
+ return null;
+
+ eclass = source.eclass;
+ type = source.Type;
+ return this;
+ }
+
+ return base.DoResolve (ec);
+ }
+
+ public override void EmitStatement (EmitContext ec)
+ {
+ if (source is CollectionOrObjectInitializers)
+ source.Emit (ec);
+ else
+ base.EmitStatement (ec);
+ }
+
+ protected virtual bool ResolveElement (ResolveContext rc)
+ {
+ var t = rc.CurrentInitializerVariable.Type;
if (t.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
Arguments args = new Arguments (1);
- args.Add (new Argument (ec.CurrentInitializerVariable));
+ args.Add (new Argument (rc.CurrentInitializerVariable));
target = new DynamicMemberBinder (Name, args, loc);
} else {
- var member = MemberLookup (ec, false, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
+ var member = MemberLookup (rc, false, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
if (member == null) {
- member = Expression.MemberLookup (ec, true, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
+ member = Expression.MemberLookup (rc, true, t, Name, 0, MemberLookupRestrictions.ExactArity, loc);
if (member != null) {
// TODO: ec.Report.SymbolRelatedToPreviousError (member);
- ErrorIsInaccesible (ec, member.GetSignatureForError (), loc);
- return null;
+ ErrorIsInaccesible (rc, member.GetSignatureForError (), loc);
+ return false;
}
}
if (member == null) {
- Error_TypeDoesNotContainDefinition (ec, loc, t, Name);
- return null;
+ Error_TypeDoesNotContainDefinition (rc, loc, t, Name);
+ return false;
}
var me = member as MemberExpr;
if (me is EventExpr) {
- me = me.ResolveMemberAccess (ec, null, null);
+ me = me.ResolveMemberAccess (rc, null, null);
} else if (!(member is PropertyExpr || member is FieldExpr)) {
- ec.Report.Error (1913, loc,
+ rc.Report.Error (1913, loc,
"Member `{0}' cannot be initialized. An object initializer may only be used for fields, or properties",
member.GetSignatureForError ());
- return null;
+ return false;
}
if (me.IsStatic) {
- ec.Report.Error (1914, loc,
+ rc.Report.Error (1914, loc,
"Static field or property `{0}' cannot be assigned in an object initializer",
me.GetSignatureForError ());
}
target = me;
- me.InstanceExpression = ec.CurrentInitializerVariable;
- }
-
- if (source is CollectionOrObjectInitializers) {
- Expression previous = ec.CurrentInitializerVariable;
- ec.CurrentInitializerVariable = target;
- source = source.Resolve (ec);
- ec.CurrentInitializerVariable = previous;
- if (source == null)
- return null;
-
- eclass = source.eclass;
- type = source.Type;
- return this;
+ me.InstanceExpression = rc.CurrentInitializerVariable;
}
- return base.DoResolve (ec);
- }
-
- public override void EmitStatement (EmitContext ec)
- {
- if (source is CollectionOrObjectInitializers)
- source.Emit (ec);
- else
- base.EmitStatement (ec);
+ return true;
}
}
return base.DoResolve (ec);
}
}
+
+ class DictionaryElementInitializer : ElementInitializer
+ {
+ readonly Arguments args;
+
+ public DictionaryElementInitializer (List<Expression> arguments, Expression initializer, Location loc)
+ : base (null, initializer, loc)
+ {
+ this.args = new Arguments (arguments.Count);
+ foreach (var arg in arguments)
+ this.args.Add (new Argument (arg));
+ }
+
+ public override Expression CreateExpressionTree (ResolveContext ec)
+ {
+ ec.Report.Error (8074, loc, "Expression tree cannot contain a dictionary initializer");
+ return null;
+ }
+
+ protected override bool ResolveElement (ResolveContext rc)
+ {
+ var init = rc.CurrentInitializerVariable;
+ var type = init.Type;
+
+ var indexers = MemberCache.FindMembers (type, MemberCache.IndexerNameAlias, false);
+ if (indexers == null && type.BuiltinType != BuiltinTypeSpec.Type.Dynamic) {
+ ElementAccess.Error_CannotApplyIndexing (rc, type, loc);
+ return false;
+ }
+
+ target = new IndexerExpr (indexers, type, init, args, loc).Resolve (rc);
+ return true;
+ }
+ }
//
// A block of object or collection initializers
if (i == 0) {
if (element_initializer != null) {
element_names = new List<string> (initializers.Count);
- element_names.Add (element_initializer.Name);
- } else if (initializer is CompletingExpression){
+ if (!element_initializer.IsDictionaryInitializer)
+ element_names.Add (element_initializer.Name);
+ } else if (initializer is CompletingExpression) {
initializer.Resolve (ec);
throw new InternalErrorException ("This line should never be reached");
} else {
continue;
}
- if (!is_collection_initialization) {
+ if (!is_collection_initialization && !element_initializer.IsDictionaryInitializer) {
if (element_names.Contains (element_initializer.Name)) {
ec.Report.Error (1912, element_initializer.Location,
"An object initializer includes more than one member `{0}' initialization",