public void SetCustomAttribute(MethodSpec ctor, byte[] data) { FieldBuilder.SetCustomAttribute((ConstructorInfo)ctor.GetMetaInfo(), data); }
public void Emit(OpCode opcode, MethodSpec method, MetaType[] vargs) { // TODO MemberCache: This should mutate too ig.EmitCall(opcode, (MethodInfo)method.GetMetaInfo(), vargs); }
/// <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.IsSame(parameters.Types, candidate_param.Types)) { continue; } bool modifiers_match = true; for (int i = 0; i < parameters.Count; ++i) { // // First check exact ref/out match // const Parameter.Modifier ref_out = Parameter.Modifier.REF | Parameter.Modifier.OUT; if ((parameters.FixedParameters[i].ModFlags & ref_out) == (candidate_param.FixedParameters[i].ModFlags & ref_out)) { continue; } modifiers_match = false; // // Different in ref/out only // if ((parameters.FixedParameters[i].ModFlags & candidate_param.FixedParameters[i].ModFlags & Parameter.Modifier.ISBYREF) != 0) { 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 on 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); }