Expression ResolveAccessor (ResolveContext ec, Expression right_side) { CommonResolve (ec); bool dynamic; arguments.Resolve (ec, out dynamic); if (dynamic || TypeManager.IsDynamicType (indexer_type)) { int additional = right_side == null ? 1 : 2; Arguments args = new Arguments (arguments.Count + additional); if (is_base_indexer) { ec.Report.Error (1972, loc, "The indexer base access cannot be dynamically dispatched. Consider casting the dynamic arguments or eliminating the base access"); } else { args.Add (new Argument (instance_expr)); } args.AddRange (arguments); if (right_side != null) args.Add (new Argument (right_side)); return new DynamicIndexBinder (right_side != null, args, loc).Resolve (ec); } Indexers ilist = Indexers.GetIndexersForType (current_type, indexer_type); if (ilist.Methods == null) { ec.Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'", TypeManager.CSharpName (indexer_type)); return null; } MethodGroupExpr mg = new IndexerMethodGroupExpr (ilist, loc); mg = mg.OverloadResolve (ec, ref arguments, false, loc); if (mg == null) return null; MethodInfo mi = (MethodInfo) mg; PropertyInfo pi = null; for (int i = 0; i < ilist.Methods.Count; ++i) { if (ilist.Methods [i] == mi) { pi = (PropertyInfo) ilist.Properties [i]; break; } } type = TypeManager.TypeToCoreType (pi.PropertyType); if (type.IsPointer && !ec.IsUnsafe) UnsafeError (ec, loc); MethodInfo accessor; if (right_side == null) { accessor = get = pi.GetGetMethod (true); } else { accessor = set = pi.GetSetMethod (true); if (accessor == null && pi.GetGetMethod (true) != null) { ec.Report.SymbolRelatedToPreviousError (pi); ec.Report.Error (200, loc, "The read only property or indexer `{0}' cannot be assigned to", TypeManager.GetFullNameSignature (pi)); return null; } set_expr = Convert.ImplicitConversion (ec, right_side, type, loc); } if (accessor == null) { ec.Report.SymbolRelatedToPreviousError (pi); ec.Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks a `{1}' accessor", TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null)); return null; } // // Only base will allow this invocation to happen. // if (accessor.IsAbstract && this is BaseIndexerAccess) { Error_CannotCallAbstractBase (ec, TypeManager.GetFullNameSignature (pi)); } bool must_do_cs1540_check; if (!IsAccessorAccessible (ec.CurrentType, accessor, out must_do_cs1540_check)) { if (set == null) set = pi.GetSetMethod (true); else get = pi.GetGetMethod (true); if (set != null && get != null && (set.Attributes & MethodAttributes.MemberAccessMask) != (get.Attributes & MethodAttributes.MemberAccessMask)) { ec.Report.SymbolRelatedToPreviousError (accessor); ec.Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because a `{1}' accessor is inaccessible", TypeManager.GetFullNameSignature (pi), GetAccessorName (right_side != null)); } else { ec.Report.SymbolRelatedToPreviousError (pi); ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (pi), ec.Report); } } instance_expr.CheckMarshalByRefAccess (ec); eclass = ExprClass.IndexerAccess; return this; }
Expression ResolveAccessor (EmitContext ec, AccessorType accessorType) { if (!CommonResolve (ec)) return null; Indexers ilist = Indexers.GetIndexersForType (current_type, indexer_type); if (ilist.Methods == null) { Report.Error (21, loc, "Cannot apply indexing with [] to an expression of type `{0}'", TypeManager.CSharpName (indexer_type)); return null; } MethodGroupExpr mg = new IndexerMethodGroupExpr (ilist, loc); mg = mg.OverloadResolve (ec, ref arguments, false, loc); if (mg == null) return null; MethodInfo mi = (MethodInfo) mg; PropertyInfo pi = null; for (int i = 0; i < ilist.Methods.Count; ++i) { if (ilist.Methods [i] == mi) { pi = (PropertyInfo) ilist.Properties [i]; break; } } type = TypeManager.TypeToCoreType (pi.PropertyType); if (type.IsPointer && !ec.InUnsafe) UnsafeError (loc); MethodInfo accessor; if (accessorType == AccessorType.Get) { accessor = get = pi.GetGetMethod (true); } else { accessor = set = pi.GetSetMethod (true); if (accessor == null && pi.GetGetMethod (true) != null) { Report.SymbolRelatedToPreviousError (pi); Report.Error (200, loc, "The read only property or indexer `{0}' cannot be assigned to", TypeManager.GetFullNameSignature (pi)); return null; } } if (accessor == null) { Report.SymbolRelatedToPreviousError (pi); Report.Error (154, loc, "The property or indexer `{0}' cannot be used in this context because it lacks a `{1}' accessor", TypeManager.GetFullNameSignature (pi), GetAccessorName (accessorType)); return null; } // // Only base will allow this invocation to happen. // if (accessor.IsAbstract && this is BaseIndexerAccess) { Error_CannotCallAbstractBase (TypeManager.GetFullNameSignature (pi)); } bool must_do_cs1540_check; if (!IsAccessorAccessible (ec.ContainerType, accessor, out must_do_cs1540_check)) { if (set == null) set = pi.GetSetMethod (true); else get = pi.GetGetMethod (true); if (set != null && get != null && (set.Attributes & MethodAttributes.MemberAccessMask) != (get.Attributes & MethodAttributes.MemberAccessMask)) { Report.SymbolRelatedToPreviousError (accessor); Report.Error (271, loc, "The property or indexer `{0}' cannot be used in this context because a `{1}' accessor is inaccessible", TypeManager.GetFullNameSignature (pi), GetAccessorName (accessorType)); } else { Report.SymbolRelatedToPreviousError (pi); ErrorIsInaccesible (loc, TypeManager.GetFullNameSignature (pi)); } } instance_expr.CheckMarshalByRefAccess (ec); eclass = ExprClass.IndexerAccess; return this; }