public void ImplementMethod(MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one, out MethodSpec ambiguousCandidate, ref bool optional) { InterfaceMethod(name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll, out ambiguousCandidate, ref optional); }
/// <summary> /// Whether the specified method is an interface method implementation /// </summary> public MethodSpec IsInterfaceMethod (MemberName name, TypeSpec ifaceType, MethodData method, out MethodSpec ambiguousCandidate, ref bool optional) { return InterfaceMethod (name, ifaceType, method, Operation.Lookup, out ambiguousCandidate, ref optional); }
/// <remarks> /// If a method in Type `t' (or null to look in all interfaces /// and the base abstract class) with name `Name', return type `ret_type' and /// arguments `args' implements an interface, this method will /// return the MethodInfo that this method implements. /// /// If `name' is null, we operate solely on the method's signature. This is for /// instance used when implementing indexers. /// /// The `Operation op' controls whether to lookup, clear the pending bit, or clear /// all the methods with the given signature. /// /// The `MethodInfo need_proxy' is used when we're implementing an interface's /// indexer in a class. If the new indexer's IndexerName does not match the one /// that was used in the interface, then we always need to create a proxy for it. /// /// </remarks> public MethodSpec InterfaceMethod (MemberName name, TypeSpec iType, MethodData method, Operation op, out MethodSpec ambiguousCandidate, ref bool optional) { ambiguousCandidate = null; if (pending_implementations == null) return null; TypeSpec ret_type = method.method.ReturnType; ParametersCompiled args = method.method.ParameterInfo; bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod; MethodSpec m; foreach (TypeAndMethods tm in pending_implementations){ if (!(iType == null || tm.type == iType)) continue; int method_count = tm.methods.Count; for (int i = 0; i < method_count; i++){ m = tm.methods [i]; if (m == null) continue; if (is_indexer) { if (!m.IsAccessor || m.Parameters.IsEmpty) continue; } else { if (name.Name != m.Name) continue; if (m.Arity != name.Arity) continue; } if (!TypeSpecComparer.Override.IsEqual (m.Parameters, args)) continue; if (!TypeSpecComparer.Override.IsEqual (m.ReturnType, ret_type)) { tm.found[i] = method; continue; } // // `need_proxy' is not null when we're implementing an // interface indexer and this is Clear(One/All) operation. // // If `name' is null, then we do a match solely based on the // signature and not on the name (this is done in the Lookup // for an interface indexer). // if (op != Operation.Lookup) { if (m.IsAccessor != method.method.IsAccessor) continue; // If `t != null', then this is an explicitly interface // implementation and we can always clear the method. // `need_proxy' is not null if we're implementing an // interface indexer. In this case, we need to create // a proxy if the implementation's IndexerName doesn't // match the IndexerName in the interface. if (m.DeclaringType.IsInterface && iType == null && name.Name != m.Name) { // TODO: This is very expensive comparison tm.need_proxy[i] = method.method.Spec; } else { tm.methods[i] = null; } } else { tm.found [i] = method; optional = tm.optional; } if (op == Operation.Lookup && name.ExplicitInterface != null && ambiguousCandidate == null) { ambiguousCandidate = m; continue; } // // Lookups and ClearOne return // if (op != Operation.ClearAll) return m; } // If a specific type was requested, we can stop now. if (tm.type == iType) break; } m = ambiguousCandidate; ambiguousCandidate = null; return m; }
public virtual MethodBuilder Define (DeclSpace parent) { parameters.Resolve (this); method_data = new MethodData (method, method.ModFlags, method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this); if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) return null; MethodBuilder mb = method_data.MethodBuilder; ParameterInfo.ApplyAttributes (mb); Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags); Spec.IsAccessor = true; return mb; }
public virtual MethodBuilder Define (TypeContainer parent) { // Fill in already resolved event type to speed things up and // avoid confusing duplicate errors ((Parameter) parameters.FixedParameters[0]).Type = method.member_type; parameters.Types = new TypeSpec[] { method.member_type }; method_data = new MethodData (method, method.ModFlags, method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this); if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) return null; method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo); if (Compiler.Settings.WriteMetadataOnly) block = null; Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, method.ModFlags); Spec.IsAccessor = true; return method_data.MethodBuilder; }
/// <summary> /// Whether the specified method is an interface method implementation /// </summary> public MethodSpec IsInterfaceMethod(MemberName name, TypeSpec ifaceType, MethodData method) { return InterfaceMethod (name, ifaceType, method, Operation.Lookup); }
public override void Define (TypeContainer parent) { base.Define (parent); Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, ModFlags); method_data = new MethodData (method, ModFlags, flags, this); method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)); }
public virtual MethodBuilder Define (DeclSpace parent) { method_data = new MethodData (method, method.ModFlags, method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this); if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) return null; MethodBuilder mb = method_data.MethodBuilder; ParameterInfo.ApplyAttributes (mb); return mb; }
/// <summary> /// Whether the specified method is an interface method implementation /// </summary> public MethodInfo IsInterfaceMethod (string name, Type ifaceType, MethodData method) { return InterfaceMethod (name, ifaceType, method, Operation.Lookup); }
public override void Emit () { if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated) PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (MethodBuilder); if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0) PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (MethodBuilder); if (TypeManager.IsDynamicType (ReturnType)) { return_attributes = new ReturnParameter (MethodBuilder, Location); return_attributes.EmitPredefined (PredefinedAttributes.Get.Dynamic, Location); } if (OptAttributes != null) OptAttributes.Emit (); if (declarative_security != null) { foreach (DictionaryEntry de in declarative_security) { MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value); } } if (MethodData != null) MethodData.Emit (Parent); base.Emit (); Block = null; MethodData = null; }
public override MethodBuilder Define (DeclSpace parent) { parameters.Resolve (this); base.Define (parent); if (IsDummy) return null; method_data = new MethodData (method, ModFlags, flags, this); if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) return null; return method_data.MethodBuilder; }
public override bool Define () { if (!base.Define ()) return false; if (!CheckBase ()) return false; if (block != null && block.IsIterator && !(Parent is IteratorStorey)) { // // Current method is turned into automatically generated // wrapper which creates an instance of iterator // Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler); ModFlags |= Modifiers.DEBUGGER_HIDDEN; } if (IsPartialDefinition) { caching_flags &= ~Flags.Excluded_Undetected; caching_flags |= Flags.Excluded; // Add to member cache only when a partial method implementation is not there if ((caching_flags & Flags.MethodOverloadsExist) == 0) { MethodBase mb = new PartialMethodDefinitionInfo (this); Parent.MemberCache.AddMember (mb, this); TypeManager.AddMethod (mb, this); } return true; } MethodData = new MethodData ( this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method); if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName), Report)) return false; MethodBuilder = MethodData.MethodBuilder; if (TypeManager.IsGenericMethod (MethodBuilder)) Parent.MemberCache.AddGenericMember (MethodBuilder, this); Parent.MemberCache.AddMember (MethodBuilder, this); return true; }
/// <summary> /// Verifies that any pending abstract methods or interface methods /// were implemented. /// </summary> public bool VerifyPendingMethods() { int top = pending_implementations.Length; bool errors = false; int i; for (i = 0; i < top; i++) { TypeSpec type = pending_implementations [i].type; bool base_implements_type = type.IsInterface && container.BaseType != null && container.BaseType.ImplementsInterface(type, false); for (int j = 0; j < pending_implementations [i].methods.Count; ++j) { var mi = pending_implementations[i].methods[j]; if (mi == null) { continue; } if (type.IsInterface) { var need_proxy = pending_implementations [i].need_proxy [j]; if (need_proxy != null) { DefineProxy(type, need_proxy, mi); continue; } if (pending_implementations [i].optional) { continue; } MethodSpec candidate = null; if (base_implements_type || BaseImplements(type, mi, out candidate)) { continue; } if (candidate == null) { MethodData md = pending_implementations [i].found [j]; if (md != null) { candidate = md.method.Spec; } } Report.SymbolRelatedToPreviousError(mi); if (candidate != null) { Report.SymbolRelatedToPreviousError(candidate); if (candidate.IsStatic) { Report.Error(736, container.Location, "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' is static", container.GetSignatureForError(), mi.GetSignatureForError(), candidate.GetSignatureForError()); } else if ((candidate.Modifiers & Modifiers.PUBLIC) == 0) { Report.Error(737, container.Location, "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' in not public", container.GetSignatureForError(), mi.GetSignatureForError(), candidate.GetSignatureForError()); } else { Report.Error(738, container.Location, "`{0}' does not implement interface member `{1}' and the best implementing candidate `{2}' return type `{3}' does not match interface member return type `{4}'", container.GetSignatureForError(), mi.GetSignatureForError(), candidate.GetSignatureForError(), candidate.ReturnType.GetSignatureForError(), mi.ReturnType.GetSignatureForError()); } } else { Report.Error(535, container.Location, "`{0}' does not implement interface member `{1}'", container.GetSignatureForError(), mi.GetSignatureForError()); } } else { Report.SymbolRelatedToPreviousError(mi); Report.Error(534, container.Location, "`{0}' does not implement inherited abstract member `{1}'", container.GetSignatureForError(), mi.GetSignatureForError()); } errors = true; } } return(errors); }
/// <remarks> /// If a method in Type `t' (or null to look in all interfaces /// and the base abstract class) with name `Name', return type `ret_type' and /// arguments `args' implements an interface, this method will /// return the MethodInfo that this method implements. /// /// If `name' is null, we operate solely on the method's signature. This is for /// instance used when implementing indexers. /// /// The `Operation op' controls whether to lookup, clear the pending bit, or clear /// all the methods with the given signature. /// /// The `MethodInfo need_proxy' is used when we're implementing an interface's /// indexer in a class. If the new indexer's IndexerName does not match the one /// that was used in the interface, then we always need to create a proxy for it. /// /// </remarks> public MethodSpec InterfaceMethod(MemberName name, TypeSpec iType, MethodData method, Operation op, out MethodSpec ambiguousCandidate, ref bool optional) { ambiguousCandidate = null; if (pending_implementations == null) { return(null); } TypeSpec ret_type = method.method.ReturnType; ParametersCompiled args = method.method.ParameterInfo; bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod; MethodSpec m; foreach (TypeAndMethods tm in pending_implementations) { if (!(iType == null || tm.type == iType)) { continue; } int method_count = tm.methods.Count; for (int i = 0; i < method_count; i++) { m = tm.methods [i]; if (m == null) { continue; } if (is_indexer) { if (!m.IsAccessor || m.Parameters.IsEmpty) { continue; } } else { if (name.Name != m.Name) { continue; } if (m.Arity != name.Arity) { continue; } } if (!TypeSpecComparer.Override.IsEqual(m.Parameters, args)) { continue; } if (!TypeSpecComparer.Override.IsEqual(m.ReturnType, ret_type)) { tm.found[i] = method; continue; } // // `need_proxy' is not null when we're implementing an // interface indexer and this is Clear(One/All) operation. // // If `name' is null, then we do a match solely based on the // signature and not on the name (this is done in the Lookup // for an interface indexer). // if (op != Operation.Lookup) { if (m.IsAccessor != method.method.IsAccessor) { continue; } // If `t != null', then this is an explicitly interface // implementation and we can always clear the method. // `need_proxy' is not null if we're implementing an // interface indexer. In this case, we need to create // a proxy if the implementation's IndexerName doesn't // match the IndexerName in the interface. if (m.DeclaringType.IsInterface && iType == null && name.Name != m.Name) // TODO: This is very expensive comparison { tm.need_proxy[i] = method.method.Spec; } else { tm.methods[i] = null; } } else { tm.found [i] = method; optional = tm.optional; } if (op == Operation.Lookup && name.ExplicitInterface != null && ambiguousCandidate == null) { ambiguousCandidate = m; continue; } // // Lookups and ClearOne return // if (op != Operation.ClearAll) { return(m); } } // If a specific type was requested, we can stop now. if (tm.type == iType) { break; } } m = ambiguousCandidate; ambiguousCandidate = null; return(m); }
public override void Emit() { if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated) PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (MethodBuilder); if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0) PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (MethodBuilder); if (ReturnType == InternalType.Dynamic) { return_attributes = new ReturnParameter (this, MethodBuilder, Location); PredefinedAttributes.Get.Dynamic.EmitAttribute (return_attributes.Builder); } else { var trans_flags = TypeManager.HasDynamicTypeUsed (ReturnType); if (trans_flags != null) { var pa = PredefinedAttributes.Get.DynamicTransform; if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) { return_attributes = new ReturnParameter (this, MethodBuilder, Location); return_attributes.Builder.SetCustomAttribute ( new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags })); } } } if (OptAttributes != null) OptAttributes.Emit (); if (declarative_security != null) { foreach (var de in declarative_security) { MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value); } } if (MethodData != null) MethodData.Emit (Parent); base.Emit (); Block = null; MethodData = null; }
/// <remarks> /// If a method in Type `t' (or null to look in all interfaces /// and the base abstract class) with name `Name', return type `ret_type' and /// arguments `args' implements an interface, this method will /// return the MethodInfo that this method implements. /// /// If `name' is null, we operate solely on the method's signature. This is for /// instance used when implementing indexers. /// /// The `Operation op' controls whether to lookup, clear the pending bit, or clear /// all the methods with the given signature. /// /// The `MethodInfo need_proxy' is used when we're implementing an interface's /// indexer in a class. If the new indexer's IndexerName does not match the one /// that was used in the interface, then we always need to create a proxy for it. /// /// </remarks> public MethodInfo InterfaceMethod (string name, Type iType, MethodData method, Operation op) { if (pending_implementations == null) return null; Type ret_type = method.method.ReturnType; ParametersCompiled args = method.method.ParameterInfo; int arg_len = args.Count; bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod; foreach (TypeAndMethods tm in pending_implementations){ if (!(iType == null || tm.type == iType)) continue; int method_count = tm.methods.Length; MethodInfo m; for (int i = 0; i < method_count; i++){ m = tm.methods [i]; if (m == null) continue; // // Check if we have the same parameters // if (tm.args [i] == null && arg_len != 0) continue; if (tm.args [i] != null && tm.args [i].Length != arg_len) continue; string mname = TypeManager.GetMethodName (m); // // `need_proxy' is not null when we're implementing an // interface indexer and this is Clear(One/All) operation. // // If `name' is null, then we do a match solely based on the // signature and not on the name (this is done in the Lookup // for an interface indexer). // if (is_indexer) { IMethodData md = TypeManager.GetMethod (m); if (md != null) { if (!(md is Indexer.SetIndexerMethod || md is Indexer.GetIndexerMethod)) continue; } else { if (TypeManager.GetPropertyFromAccessor (m) == null) continue; } } else if (name != mname) { continue; } int j; for (j = 0; j < arg_len; j++) { if (!TypeManager.IsEqual (tm.args [i][j], args.Types [j])) break; if (tm.mods [i][j] == args.FixedParameters [j].ModFlags) continue; // The modifiers are different, but if one of them // is a PARAMS modifier, and the other isn't, ignore // the difference. if (tm.mods [i][j] != Parameter.Modifier.PARAMS && args.FixedParameters [j].ModFlags != Parameter.Modifier.PARAMS) break; } if (j != arg_len) continue; Type rt = TypeManager.TypeToCoreType (m.ReturnType); if (!TypeManager.IsEqual (ret_type, rt) && !(ret_type == null && rt == TypeManager.void_type) && !(rt == null && ret_type == TypeManager.void_type)) { tm.found [i] = method; continue; } if (op != Operation.Lookup) { // If `t != null', then this is an explicitly interface // implementation and we can always clear the method. // `need_proxy' is not null if we're implementing an // interface indexer. In this case, we need to create // a proxy if the implementation's IndexerName doesn't // match the IndexerName in the interface. if (iType == null && name != mname) tm.need_proxy [i] = method.MethodBuilder; else tm.methods [i] = null; } else { tm.found [i] = method; } // // Lookups and ClearOne return // if (op != Operation.ClearAll) return m; } // If a specific type was requested, we can stop now. if (tm.type == iType) return null; } return null; }
public void ImplementMethod(MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one) { InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll); }
// // Creates the type // public override bool Define (TypeContainer parent) { if (!DoDefine (parent)) return false; if (!CheckBase (parent)) return false; CallingConventions cc = GetCallingConvention (parent is Class); MethodData = new MethodData (this, null, MemberType, ParameterTypes, ParameterInfo, cc, OptAttributes, ModFlags, flags, true); if (!MethodData.Define (parent)) return false; MethodBuilder = MethodData.MethodBuilder; // // This is used to track the Entry Point, // if (Name == "Main" && ((ModFlags & Modifiers.STATIC) != 0) && (RootContext.MainClass == null || RootContext.MainClass == parent.TypeBuilder.FullName)){ if (IsEntryPoint (MethodBuilder, ParameterInfo)) { if (RootContext.EntryPoint == null) { RootContext.EntryPoint = MethodBuilder; RootContext.EntryPointLocation = Location; } else { DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation); DuplicateEntryPoint (MethodBuilder, Location); } } else Report28(MethodBuilder); } return true; }
public override void Emit () { if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated) Compiler.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder); if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0) Compiler.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder); if (ReturnType == InternalType.Dynamic) { return_attributes = new ReturnParameter (this, MethodBuilder, Location); Compiler.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder); } else if (ReturnType.HasDynamicElement) { return_attributes = new ReturnParameter (this, MethodBuilder, Location); Compiler.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType); } if (OptAttributes != null) OptAttributes.Emit (); if (declarative_security != null) { foreach (var de in declarative_security) { MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value); } } if (MethodData != null) MethodData.Emit (Parent); base.Emit (); Block = null; MethodData = null; }
public override bool Define (TypeContainer parent) { if (!DoDefine (parent)) return false; if (!CheckBase (parent)) return false; flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName; if (Get != null) { Type [] parameters = TypeManager.NoTypes; InternalParameters ip = new InternalParameters ( parent, Parameters.EmptyReadOnlyParameters); GetData = new MethodData (this, "get", MemberType, parameters, ip, CallingConventions.Standard, Get.OptAttributes, ModFlags, flags, false); if (!GetData.Define (parent)) return false; GetBuilder = GetData.MethodBuilder; } if (Set != null) { Type [] parameters = new Type [1]; parameters [0] = MemberType; Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null); InternalParameters ip = new InternalParameters ( parent, new Parameters (parms, null, Location)); SetData = new MethodData (this, "set", TypeManager.void_type, parameters, ip, CallingConventions.Standard, Set.OptAttributes, ModFlags, flags, false); if (!SetData.Define (parent)) return false; SetBuilder = SetData.MethodBuilder; SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); } // FIXME - PropertyAttributes.HasDefault ? PropertyAttributes prop_attr = PropertyAttributes.RTSpecialName | PropertyAttributes.SpecialName; if (!IsExplicitImpl){ PropertyBuilder = parent.TypeBuilder.DefineProperty ( Name, prop_attr, MemberType, null); if (Get != null) PropertyBuilder.SetGetMethod (GetBuilder); if (Set != null) PropertyBuilder.SetSetMethod (SetBuilder); // // HACK for the reasons exposed above // if (!TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder)) { Report.Error ( 111, Location, "Class `" + parent.Name + "' already contains a definition for the property `" + Name + "'"); return false; } } return true; }
public override bool Define () { if (!base.Define ()) return false; if (!CheckBase ()) return false; MemberKind kind; if (this is Operator) kind = MemberKind.Operator; else if (this is Destructor) kind = MemberKind.Destructor; else kind = MemberKind.Method; if (IsPartialDefinition) { caching_flags &= ~Flags.Excluded_Undetected; caching_flags |= Flags.Excluded; // Add to member cache only when a partial method implementation has not been found yet if ((caching_flags & Flags.PartialDefinitionExists) == 0) { // MethodBase mb = new PartialMethodDefinitionInfo (this); spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags); if (MemberName.Arity > 0) { spec.IsGeneric = true; // TODO: Have to move DefineMethod after Define (ideally to Emit) throw new NotImplementedException ("Generic partial methods"); } Parent.MemberCache.AddMember (spec); } return true; } MethodData = new MethodData ( this, ModFlags, flags, this, MethodBuilder, base_method); if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName))) return false; MethodBuilder = MethodData.MethodBuilder; spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags); if (MemberName.Arity > 0) spec.IsGeneric = true; Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec); return true; }
public override bool Define (TypeContainer parent) { EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName; if (!DoDefine (parent)) return false; if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){ Report.Error (74, Location, "'" + parent.Name + "." + Name + "': abstract event can not have an initializer"); return false; } if (!MemberType.IsSubclassOf (TypeManager.delegate_type)) { Report.Error (66, Location, "'" + parent.Name + "." + Name + "' : event must be of a delegate type"); return false; } Type [] parameter_types = new Type [1]; parameter_types [0] = MemberType; Parameter [] parms = new Parameter [1]; parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null); InternalParameters ip = new InternalParameters ( parent, new Parameters (parms, null, Location)); if (!CheckBase (parent)) return false; // // Now define the accessors // AddData = new MethodData (this, "add", TypeManager.void_type, parameter_types, ip, CallingConventions.Standard, (Add != null) ? Add.OptAttributes : null, ModFlags, flags, false); if (!AddData.Define (parent)) return false; AddBuilder = AddData.MethodBuilder; AddBuilder.DefineParameter (1, ParameterAttributes.None, "value"); RemoveData = new MethodData (this, "remove", TypeManager.void_type, parameter_types, ip, CallingConventions.Standard, (Remove != null) ? Remove.OptAttributes : null, ModFlags, flags, false); if (!RemoveData.Define (parent)) return false; RemoveBuilder = RemoveData.MethodBuilder; RemoveBuilder.DefineParameter (1, ParameterAttributes.None, "value"); if (!IsExplicitImpl){ EventBuilder = new MyEventBuilder (this, parent.TypeBuilder, Name, e_attr, MemberType); if (Add == null && Remove == null) { FieldBuilder = parent.TypeBuilder.DefineField ( Name, MemberType, FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0)); TypeManager.RegisterPrivateFieldOfEvent ( (EventInfo) EventBuilder, FieldBuilder); TypeManager.RegisterFieldBase (FieldBuilder, this); } EventBuilder.SetAddOnMethod (AddBuilder); EventBuilder.SetRemoveOnMethod (RemoveBuilder); if (!TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder)) { Report.Error (111, Location, "Class `" + parent.Name + "' already contains a definition for the event `" + Name + "'"); return false; } } return true; }
public override MethodBuilder Define (DeclSpace parent) { parameters.Resolve (this); base.Define (parent); Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags); method_data = new MethodData (method, ModFlags, flags, this); if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) return null; Spec.SetMetaInfo (method_data.MethodBuilder); return method_data.MethodBuilder; }
public override bool Define (TypeContainer parent) { PropertyAttributes prop_attr = PropertyAttributes.RTSpecialName | PropertyAttributes.SpecialName; if (!DoDefine (parent)) return false; IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes); if (IndexerName == null) IndexerName = "Item"; else if (IsExplicitImpl) Report.Error (592, Location, "Attribute 'IndexerName' is not valid on this declaration " + "type. It is valid on `property' declarations only."); ShortName = IndexerName; if (IsExplicitImpl) { InterfaceIndexerName = TypeManager.IndexerPropertyName (InterfaceType); Name = InterfaceType.FullName + "." + IndexerName; } else { InterfaceIndexerName = IndexerName; Name = ShortName; } if (!CheckBase (parent)) return false; flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName; if (Get != null){ InternalParameters ip = new InternalParameters (parent, Parameters); GetData = new MethodData (this, "get", MemberType, ParameterTypes, ip, CallingConventions.Standard, Get.OptAttributes, ModFlags, flags, false); if (!GetData.Define (parent)) return false; GetBuilder = GetData.MethodBuilder; } if (Set != null){ int top = ParameterTypes.Length; Type [] set_pars = new Type [top + 1]; ParameterTypes.CopyTo (set_pars, 0); set_pars [top] = MemberType; Parameter [] fixed_parms = Parameters.FixedParameters; if (fixed_parms == null){ throw new Exception ("We currently do not support only array arguments in an indexer"); // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG // // Here is the problem: the `value' parameter has // to come *after* the array parameter in the declaration // like this: // X (object [] x, Type value) // .param [0] // // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG } Parameter [] tmp = new Parameter [fixed_parms.Length + 1]; fixed_parms.CopyTo (tmp, 0); tmp [fixed_parms.Length] = new Parameter ( Type, "value", Parameter.Modifier.NONE, null); Parameters set_formal_params = new Parameters (tmp, null, Location); InternalParameters ip = new InternalParameters (parent, set_formal_params); SetData = new MethodData (this, "set", TypeManager.void_type, set_pars, ip, CallingConventions.Standard, Set.OptAttributes, ModFlags, flags, false); if (!SetData.Define (parent)) return false; SetBuilder = SetData.MethodBuilder; } // // Now name the parameters // Parameter [] p = Parameters.FixedParameters; if (p != null) { int i; for (i = 0; i < p.Length; ++i) { if (Get != null) GetBuilder.DefineParameter ( i + 1, p [i].Attributes, p [i].Name); if (Set != null) SetBuilder.DefineParameter ( i + 1, p [i].Attributes, p [i].Name); } if (Set != null) SetBuilder.DefineParameter ( i + 1, ParameterAttributes.None, "value"); if (i != ParameterTypes.Length) { Parameter array_param = Parameters.ArrayParameter; SetBuilder.DefineParameter ( i + 1, array_param.Attributes, array_param.Name); } } if (GetData != null) IsImplementing = GetData.IsImplementing; else if (SetData != null) IsImplementing = SetData.IsImplementing; // // Define the PropertyBuilder if one of the following conditions are met: // a) we're not implementing an interface indexer. // b) the indexer has a different IndexerName and this is no // explicit interface implementation. // if (!IsExplicitImpl) { PropertyBuilder = parent.TypeBuilder.DefineProperty ( IndexerName, prop_attr, MemberType, ParameterTypes); if (GetData != null) PropertyBuilder.SetGetMethod (GetBuilder); if (SetData != null) PropertyBuilder.SetSetMethod (SetBuilder); TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes); } return true; }
public override MethodBuilder Define (TypeContainer parent) { parameters.Resolve (this); base.Define (parent); Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, ParameterInfo, ModFlags); method_data = new MethodData (method, ModFlags, flags, this); if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) return null; method_data.DefineMethodBuilder (parent.PartialContainer, ParameterInfo); return method_data.MethodBuilder; }
public override void Emit () { if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated) Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder); if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0) Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder); if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { return_attributes = new ReturnParameter (this, MethodBuilder, Location); Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder); } else if (ReturnType.HasDynamicElement) { return_attributes = new ReturnParameter (this, MethodBuilder, Location); Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location); } if (OptAttributes != null) OptAttributes.Emit (); if (declarative_security != null) { foreach (var de in declarative_security) { #if STATIC MethodBuilder.__AddDeclarativeSecurity (de); #else MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value); #endif } } if (type_expr != null) ConstraintChecker.Check (this, member_type, type_expr.Location); base.Emit (); if (MethodData != null) MethodData.Emit (Parent); Block = null; MethodData = null; }
public void ImplementMethod (MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one, out MethodSpec ambiguousCandidate, ref bool optional) { InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll, out ambiguousCandidate, ref optional); }
public virtual MethodBuilder Define (DeclSpace parent) { // Fill in already resolved event type to speed things up and // avoid confusing duplicate errors ((Parameter) parameters.FixedParameters[0]).Type = method.member_type; parameters.Types = new TypeSpec[] { method.member_type }; method_data = new MethodData (method, method.ModFlags, method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this); if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) return null; MethodBuilder mb = method_data.MethodBuilder; Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags); Spec.IsAccessor = true; return mb; }
public override bool Define () { if (!base.Define ()) return false; if (!CheckBase ()) return false; MemberKind kind; if (this is Operator) kind = MemberKind.Operator; else if (this is Destructor) kind = MemberKind.Destructor; else kind = MemberKind.Method; string explicit_name; if (IsPartialDefinition) { caching_flags &= ~Flags.Excluded_Undetected; caching_flags |= Flags.Excluded; // Add to member cache only when a partial method implementation has not been found yet if ((caching_flags & Flags.PartialDefinitionExists) != 0) return true; if (IsExplicitImpl) return true; explicit_name = null; } else { MethodData = new MethodData (this, ModFlags, flags, this, base_method); if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName))) return false; explicit_name = MethodData.MetadataName; } spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, parameters, ModFlags); if (MemberName.Arity > 0) spec.IsGeneric = true; Parent.MemberCache.AddMember (this, explicit_name, spec); return true; }
/// <summary> /// Whether the specified method is an interface method implementation /// </summary> public MethodSpec IsInterfaceMethod(MemberName name, TypeSpec ifaceType, MethodData method, out MethodSpec ambiguousCandidate, ref bool optional) { return(InterfaceMethod(name, ifaceType, method, Operation.Lookup, out ambiguousCandidate, ref optional)); }