/// <summary> /// Weaves an implementation of a property against the provided type. /// </summary> /// <param name="emitter">The emitter.</param> /// <param name="field">The attribute field.</param> /// <param name="property">The property.</param> /// <param name="interfaceType">The type of the interface.</param> public void WeaveImplementedProperty(TypeEmitter emitter, Variable field, PropertyDefinition property, TypeDefinition interfaceType) { var emitted = emitter.EmitProperty(property.Name, property.PropertyType.Import(), toBackingField: true); var implemented = field.Type.GetProperty(property.Name, property.PropertyType)?.Resolve(); if (implemented == null) { implemented = field.Type.GetProperty($"{interfaceType.FullName}.{property.Name}", returnType: property.PropertyType)?.Resolve(); if (implemented == null) { throw new MissingMemberException($"Cannot implement '{field.Type.FullName}' as it does not implement property '{property.Name}'"); } } var source = new PropertyEmitter(emitter, implemented); if (source.HasGetter && !emitted.HasGetter) { var getter = emitted.GetGetter(); var il = getter.GetIL(); var propertyGet = property.GetMethod?.Import() ?? implemented.GetMethod.Import(); getter.Body.SimplifyMacros(); il.Emit(Codes.Nop); il.Emit(Codes.ThisIf(field)); il.Emit(Codes.Cast(interfaceType)); il.Emit(Codes.Load(field)); il.Emit(Codes.Invoke(propertyGet.GetGeneric())); il.Emit(Codes.Return); getter.Body.OptimizeMacros(); getter.Body.InitLocals = true; } if (source.HasSetter && !emitted.HasSetter) { var setter = emitted.GetSetter(); var il = setter.GetIL(); var propertySet = property.SetMethod?.Import() ?? implemented.SetMethod.Import(); setter.Body.SimplifyMacros(); il.Emit(Codes.Nop); il.Emit(Codes.ThisIf(field)); il.Emit(Codes.Load(field)); il.Emit(Codes.Arg(setter.Target.IsStatic ? 0 : 1)); il.Emit(Codes.Invoke(propertySet.GetGeneric())); il.Emit(Codes.Return); setter.Body.OptimizeMacros(); setter.Body.InitLocals = true; } }