예제 #1
0
        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"));
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }