/// <summary> /// Weave an implementation of a method against the provided type. /// </summary> /// <param name="emitter">The emitter.</param> /// <param name="field">The attribute field.</param> /// <param name="method">The method.</param> /// <param name="interfaceType">The type of the interface.</param> public void WeaveImplementedMethod(TypeEmitter emitter, Variable field, MethodReference method, TypeDefinition interfaceType) { var resolved = method.Resolve(); var emitted = emitter.EmitMethod( method.Name, method.ReturnType.Import(), parameterTypes: method.HasParameters ? method.Parameters.Select(p => p.ParameterType.Import()).ToArray() : new TypeReference[0], genericTypes: method.HasGenericParameters ? method.GenericParameters.ToArray() : new GenericParameter[0], toStatic: resolved.IsStatic, toVisibility: resolved.GetVisiblity() ); var parameters = method.Parameters.Select(p => p.ParameterType).ToArray(); var generics = method.GenericParameters.ToArray(); var implemented = field.Type.GetMethod(method.Name, returns: method.ReturnType, parameters: parameters, generics: generics); if (implemented == null) { implemented = field.Type.GetMethod($"{interfaceType.FullName}.{method.Name}", returns: method.ReturnType, parameters: parameters, generics: generics); if (implemented == null) { throw new MissingMemberException($"Cannot implement '{field.Type.FullName}' as it does not implement method '{method.FullName}'"); } } var il = emitted.GetIL(); il.Emit(Codes.Nop); il.Emit(Codes.ThisIf(field)); il.Emit(Codes.Load(field)); for (int i = 0, count = method.Parameters.Count; i < count; i++) { il.Emit(Codes.Arg(i + 1)); } il.Emit(Codes.Invoke(method.Import().GetGeneric())); il.Emit(Codes.Return); emitted.Body.InitLocals = true; }