protected override bool ShouldImplementMethod(Mono.Cecil.MethodDefinition method) { if (method.DeclaringType.FullName != typeof(MulticastDelegate).FullName) { return(false); } var name = method.Name; return((name == "Add") || (name == "Remove")); }
/// <summary> /// Create an annotation with default values. /// </summary> private static Annotation CreateDefaultAnnotation(AttributeAnnotationInterface mapping) { // Create annotation Annotation annotation = new Annotation { Visibility = AnnotationVisibility.Runtime }; annotation.Type = mapping.AnnotationInterfaceClass; // Add field default values foreach (KeyValuePair <Mono.Cecil.FieldDefinition, MethodDefinition> entry in mapping.FieldToGetMethodMap) { string name = entry.Value.Name; Mono.Cecil.TypeReference type = entry.Key.FieldType; annotation.Arguments.Add(new AnnotationArgument(name, GetDefaultValue(type))); } // Add property default values foreach (KeyValuePair <PropertyDefinition, MethodDefinition> entry in mapping.PropertyToGetMethodMap) { string name = entry.Value.Name; Mono.Cecil.TypeReference type = entry.Key.PropertyType; annotation.Arguments.Add(new AnnotationArgument(name, GetDefaultValue(type))); } // Add ctor argument default values foreach (KeyValuePair <Mono.Cecil.MethodDefinition, AttributeCtorMapping> entry in mapping.CtorMap) { Mono.Cecil.MethodDefinition ctor = entry.Key; for (int i = 0; i < ctor.Parameters.Count; i++) { string name = entry.Value.ArgumentGetters[i].Name; Mono.Cecil.TypeReference type = entry.Key.Parameters[i].ParameterType; annotation.Arguments.Add(new AnnotationArgument(name, GetDefaultValue(type))); } } // Wrap it in a dalvik.annotation.AnnotationDefault Annotation defAnnotation = new Annotation { Visibility = AnnotationVisibility.System }; defAnnotation.Type = new ClassReference("dalvik.annotation.AnnotationDefault"); defAnnotation.Arguments.Add(new AnnotationArgument("value", annotation)); return(defAnnotation); }
/// <summary> /// Create a method definition for the builder method that builds a custom attribute from an annotation. /// </summary> private static MethodDefinition CreateBuildMethod( ISourceLocation seqp, Mono.Cecil.MethodDefinition ctor, List <MethodDefinition> paramGetMethods, AssemblyCompiler compiler, DexTargetPackage targetPackage, ClassDefinition attributeClass, AttributeAnnotationInterface mapping) { // Create method definition string name = CreateBuildMethodName(attributeClass); TypeReference attributeTypeRef = ctor.DeclaringType.GetReference(targetPackage, compiler.Module); MethodDefinition method = new MethodDefinition(attributeClass, name, new Prototype(attributeTypeRef, new Parameter(mapping.AnnotationInterfaceClass, "ann"))); method.AccessFlags = AccessFlags.Public | AccessFlags.Static | AccessFlags.Synthetic; attributeClass.Methods.Add(method); // Create method body MethodBody body = new MethodBody(null); Register annotationReg = body.AllocateRegister(RCategory.Argument, RType.Object); //body.Instructions.Add(seqp, RCode.Check_cast, mapping.AnnotationInterfaceClass, annotationReg); // Allocate attribute Register attributeReg = body.AllocateRegister(RCategory.Temp, RType.Object); body.Instructions.Add(seqp, RCode.New_instance, attributeClass, attributeReg); // Get ctor arguments List <Register> ctorArgRegs = new List <Register>(); foreach (MethodDefinition p in paramGetMethods) { TypeReference paramType = p.Prototype.ReturnType; Register[] valueRegs = CreateLoadValueSequence(seqp, body, paramType, annotationReg, p); ctorArgRegs.AddRange(valueRegs); } // Invoke ctor DexLib.MethodReference dctor = ctor.GetReference(targetPackage, compiler.Module); body.Instructions.Add(seqp, RCode.Invoke_direct, dctor, new[] { attributeReg }.Concat(ctorArgRegs).ToArray()); // Get field values foreach (var fieldMap in mapping.FieldToGetMethodMap) { Mono.Cecil.FieldDefinition field = fieldMap.Key; MethodDefinition getter = fieldMap.Value; Register[] valueRegs = CreateLoadValueSequence(seqp, body, getter.Prototype.ReturnType, annotationReg, getter); DexLib.FieldReference dfield = field.GetReference(targetPackage, compiler.Module); XModel.XTypeReference xFieldType = XBuilder.AsTypeReference(compiler.Module, field.FieldType); body.Instructions.Add(seqp, xFieldType.IPut(), dfield, valueRegs[0], attributeReg); } // Get property values foreach (var propertyMap in mapping.PropertyToGetMethodMap) { PropertyDefinition property = propertyMap.Key; MethodDefinition getter = propertyMap.Value; Register[] valueRegs = CreateLoadValueSequence(seqp, body, getter.Prototype.ReturnType, annotationReg, getter); DexLib.MethodReference dmethod = property.SetMethod.GetReference(targetPackage, compiler.Module); XModel.XMethodDefinition xSetMethod = XBuilder.AsMethodDefinition(compiler.Module, property.SetMethod); body.Instructions.Add(seqp, xSetMethod.Invoke(xSetMethod, null), dmethod, new[] { attributeReg }.Concat(valueRegs).ToArray()); } // Return attribute body.Instructions.Add(seqp, RCode.Return_object, attributeReg); // Register method body targetPackage.Record(new CompiledMethod() { DexMethod = method, RLBody = body }); // Return method return(method); }