public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { #if false if (a.Type == pa.MarshalAs) { UnmanagedMarshal marshal = a.GetMarshal (this); if (marshal != null) { builder.SetMarshal (marshal); } return; } #endif if (a.HasSecurityAttribute) { a.Error_InvalidSecurityParent (); return; } if (a.Type == pa.Dynamic) { a.Error_MisusedDynamicAttribute (); return; } builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); }
/// <summary> /// C# allows this kind of scenarios: /// interface I { void M (); } /// class X { public void M (); } /// class Y : X, I { } /// /// For that case, we create an explicit implementation function /// I.M in Y. /// </summary> void DefineProxy (TypeSpec iface, MethodSpec base_method, MethodSpec iface_method) { // TODO: Handle nested iface names string proxy_name; var ns = iface.MemberDefinition.Namespace; if (string.IsNullOrEmpty (ns)) proxy_name = iface.MemberDefinition.Name + "." + iface_method.Name; else proxy_name = ns + "." + iface.MemberDefinition.Name + "." + iface_method.Name; var param = iface_method.Parameters; MethodBuilder proxy = container.TypeBuilder.DefineMethod ( proxy_name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.Standard | CallingConventions.HasThis, base_method.ReturnType.GetMetaInfo (), param.GetMetaInfo ()); if (iface_method.IsGeneric) { var gnames = iface_method.GenericDefinition.TypeParameters.Select (l => l.Name).ToArray (); proxy.DefineGenericParameters (gnames); } for (int i = 0; i < param.Count; i++) { string name = param.FixedParameters [i].Name; ParameterAttributes attr = ParametersCompiled.GetParameterAttribute (param.FixedParameters [i].ModFlags); proxy.DefineParameter (i + 1, attr, name); } int top = param.Count; var ec = new EmitContext (new ProxyMethodContext (container), proxy.GetILGenerator (), null, null); ec.EmitThis (); // TODO: GetAllParametersArguments for (int i = 0; i < top; i++) ec.EmitArgumentLoad (i); ec.Emit (OpCodes.Call, base_method); ec.Emit (OpCodes.Ret); container.TypeBuilder.DefineMethodOverride (proxy, (MethodInfo) iface_method.GetMetaInfo ()); }
/// <summary> /// This function tells whether one of our base classes implements /// the given method (which turns out, it is valid to have an interface /// implementation in a base /// </summary> bool BaseImplements (TypeSpec iface_type, MethodSpec mi, out MethodSpec base_method) { base_method = null; var base_type = container.BaseType; // // Setup filter with no return type to give better error message // about mismatch at return type when the check bellow rejects them // var parameters = mi.Parameters; while (true) { var candidates = MemberCache.FindMembers (base_type, mi.Name, false); if (candidates == null) return false; MethodSpec similar_candidate = null; foreach (var candidate in candidates) { if (candidate.Kind != MemberKind.Method) continue; if (candidate.Arity != mi.Arity) continue; var candidate_param = ((MethodSpec) candidate).Parameters; if (!TypeSpecComparer.Override.IsEqual (parameters.Types, candidate_param.Types)) continue; bool modifiers_match = true; for (int i = 0; i < parameters.Count; ++i) { // // First check exact ref/out match // if ((parameters.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) == (candidate_param.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) continue; modifiers_match = false; // // Different in ref/out only // if ((parameters.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (candidate_param.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) { if (similar_candidate == null) { if (!candidate.IsPublic) break; if (!TypeSpecComparer.Override.IsEqual (mi.ReturnType, ((MethodSpec) candidate).ReturnType)) break; // It's used for ref/out ambiguity overload check similar_candidate = (MethodSpec) candidate; } continue; } similar_candidate = null; break; } if (!modifiers_match) continue; // // From this point the candidate is used for detailed error reporting // because it's very close match to what we are looking for // base_method = (MethodSpec) candidate; if (!candidate.IsPublic) return false; if (!TypeSpecComparer.Override.IsEqual (mi.ReturnType, base_method.ReturnType)) return false; if (mi.IsGeneric && !Method.CheckImplementingMethodConstraints (container, base_method, mi)) { return true; } } if (base_method != null) { if (similar_candidate != null) { Report.SymbolRelatedToPreviousError (similar_candidate); Report.SymbolRelatedToPreviousError (mi); Report.SymbolRelatedToPreviousError (container); Report.Warning (1956, 1, ((MemberCore) base_method.MemberDefinition).Location, "The interface method `{0}' implementation is ambiguous between following methods: `{1}' and `{2}' in type `{3}'", mi.GetSignatureForError (), base_method.GetSignatureForError (), similar_candidate.GetSignatureForError (), container.GetSignatureForError ()); } break; } base_type = candidates[0].DeclaringType.BaseType; if (base_type == null) return false; } if (!base_method.IsVirtual) { #if STATIC var base_builder = base_method.GetMetaInfo () as MethodBuilder; if (base_builder != null) { // // We can avoid creating a proxy if base_method can be marked 'final virtual'. This can // be done for all methods from compiled assembly // base_builder.__SetAttributes (base_builder.Attributes | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot); return true; } #endif DefineProxy (iface_type, base_method, mi); } return true; }
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if ((a.HasSecurityAttribute)) { a.Error_InvalidSecurityParent (); return; } EventBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); }
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.HasSecurityAttribute) { a.Error_InvalidSecurityParent (); return; } if (a.Type == pa.Dynamic) { a.Error_MisusedDynamicAttribute (); return; } PropertyBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); }
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) { Report.Error (1667, a.Location, "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ()); return; } if (a.IsValidSecurityAttribute ()) { a.ExtractSecurityPermissionSet (ctor, ref declarative_security); return; } if (a.Target == AttributeTargets.Method) { method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); return; } if (a.Target == AttributeTargets.ReturnValue) { if (return_attributes == null) return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location); return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa); return; } ApplyToExtraTarget (a, ctor, cdata, pa); }
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.Target == AttributeTargets.ReturnValue) { if (return_attributes == null) return_attributes = new ReturnParameter (this, MethodBuilder, Location); return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa); return; } if (a.Type == pa.MethodImpl) { if ((ModFlags & Modifiers.ASYNC) != 0 && (a.GetMethodImplOptions () & MethodImplOptions.Synchronized) != 0) { Report.Error (4015, a.Location, "`{0}': Async methods cannot use `MethodImplOptions.Synchronized'", GetSignatureForError ()); } is_external_implementation = a.IsInternalCall (); } else if (a.Type == pa.DllImport) { const Modifiers extern_static = Modifiers.EXTERN | Modifiers.STATIC; if ((ModFlags & extern_static) != extern_static) { Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'"); } is_external_implementation = true; } if (a.IsValidSecurityAttribute ()) { a.ExtractSecurityPermissionSet (ctor, ref declarative_security); return; } if (MethodBuilder != null) MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); }
public void SetCustomAttribute (MethodSpec ctor, byte[] data) { FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), data); }
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.IsValidSecurityAttribute ()) { a.ExtractSecurityPermissionSet (ctor, ref declarative_security); return; } if (a.Type == pa.MethodImpl) { is_external_implementation = a.IsInternalCall (); } ConstructorBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); }
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.Type == pa.FieldOffset) { status |= Status.HAS_OFFSET; if (!Parent.PartialContainer.HasExplicitLayout) { Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)"); return; } if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) { Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields"); return; } } if (a.Type == pa.FixedBuffer) { Report.Error (1716, Location, "Do not use 'System.Runtime.CompilerServices.FixedBuffer' attribute. Use the 'fixed' field modifier instead"); return; } #if false if (a.Type == pa.MarshalAs) { UnmanagedMarshal marshal = a.GetMarshal (this); if (marshal != null) { FieldBuilder.SetMarshal (marshal); } return; } #endif if ((a.HasSecurityAttribute)) { a.Error_InvalidSecurityParent (); return; } if (a.Type == pa.Dynamic) { a.Error_MisusedDynamicAttribute (); return; } FieldBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); }
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (has_normal_indexers && a.Type == pa.DefaultMember) { Report.Error (646, a.Location, "Cannot specify the `DefaultMember' attribute on type containing an indexer"); return; } if (a.Type == pa.Required) { Report.Error (1608, a.Location, "The RequiredAttribute attribute is not permitted on C# types"); return; } TypeBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); }
public void Emit (OpCode opcode, MethodSpec method, MetaType[] vargs) { // TODO MemberCache: This should mutate too ig.EmitCall (opcode, (MethodInfo) method.GetMetaInfo (), vargs); }
public void Emit (OpCode opcode, MethodSpec method) { if (IsAnonymousStoreyMutateRequired) method = method.Mutate (CurrentAnonymousMethod.Storey.Mutator); if (method.IsConstructor) ig.Emit (opcode, (ConstructorInfo) method.GetMetaInfo ()); else ig.Emit (opcode, (MethodInfo) method.GetMetaInfo ()); }
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.Target == AttributeTargets.Assembly) { assembly.ApplyAttributeBuilder (a, ctor, cdata, pa); return; } if (a.Type == pa.DefaultCharset) { switch (a.GetCharSetValue ()) { case CharSet.Ansi: case CharSet.None: break; case CharSet.Auto: DefaultCharSet = CharSet.Auto; DefaultCharSetType = TypeAttributes.AutoClass; break; case CharSet.Unicode: DefaultCharSet = CharSet.Unicode; DefaultCharSetType = TypeAttributes.UnicodeClass; break; default: Report.Error (1724, a.Location, "Value specified for the argument to `{0}' is not valid", a.GetSignatureForError ()); break; } } else if (a.Type == pa.CLSCompliant) { Attribute cls = DeclaringAssembly.CLSCompliantAttribute; if (cls == null) { Report.Warning (3012, 1, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking"); } else if (DeclaringAssembly.IsCLSCompliant != a.GetBoolean ()) { Report.SymbolRelatedToPreviousError (cls.Location, cls.GetSignatureForError ()); Report.Warning (3017, 1, a.Location, "You cannot specify the CLSCompliant attribute on a module that differs from the CLSCompliant attribute on the assembly"); return; } } builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata); }