예제 #1
0
        /// <summary>
        /// Create all annotations for this class and it's members
        /// </summary>
        public virtual void CreateAnnotations(DexTargetPackage targetPackage)
        {
            // Build class annotations
            if (Class != null)
            {
                // Custom attributes
                AttributeAnnotationInstanceBuilder.CreateAttributeAnnotations(compiler, Type, Class, targetPackage);

                // Properties
                if ((methodBuilders != null) && compiler.AddPropertyAnnotations())
                {
                    AddPropertiesAnnotation(targetPackage);
                }

                AddDefaultAnnotations(targetPackage);
            }

            // Build nested class annotation
            nestedBuilders.ForEach(x => x.CreateAnnotations(targetPackage));

            // Build field annotations
            if (fieldBuilders != null)
            {
                fieldBuilders.ForEach(x => x.CreateAnnotations(targetPackage));
            }

            // Build method annotations
            if (methodBuilders != null)
            {
                methodBuilders.ForEach(x => x.CreateAnnotations(targetPackage));
            }
        }
예제 #2
0
        /// <summary>
        /// Create all annotations for this field
        /// </summary>
        internal virtual void CreateAnnotations(DexTargetPackage targetPackage)
        {
            // Build field annotations
            AttributeAnnotationInstanceBuilder.CreateAttributeAnnotations(compiler, field, dfield, targetPackage);

            dfield.AddGenericDefinitionAnnotationIfGeneric(xField.FieldType, compiler, targetPackage);
        }
예제 #3
0
        /// <summary>
        /// Create all annotations for this method
        /// </summary>
        internal virtual void CreateAnnotations(DexTargetPackage targetPackage)
        {
            // Build method annotations
            AttributeAnnotationInstanceBuilder.CreateAttributeAnnotations(compiler, method, dmethod, targetPackage);

            // only add generics annotation for getters or setters or constructors
            if (method.IsGetter)
            {
                // Note that the return type might has been
                // changed above, to compensate for interface
                // inheritance and generic specialization.
                // We need to use the original declaration.
                // TODO: why not get rid of "OriginalReturnType"
                //       and use the IL's return type??
                var returnType = xMethod.OriginalReturnType;
                var xType      = XBuilder.AsTypeReference(compiler.Module, returnType);
                dmethod.AddGenericDefinitionAnnotationIfGeneric(xType, compiler, targetPackage);
            }
            else if (method.IsSetter)
            {
                for (int i = 0; i < xMethod.Parameters.Count; ++i)
                {
                    var dp = dmethod.Prototype.Parameters[i];
                    dp.AddGenericDefinitionAnnotationIfGeneric(xMethod.Parameters[i].ParameterType, compiler,
                                                               targetPackage);
                }
            }
            else if (method.IsConstructor && !method.IsStatic)
            {
                // Add parameter names and original access flags, as these might be important
                // in serialization and/or dependency injection.

                var reflectionInfo = compiler.GetDot42InternalType(InternalConstants.ReflectionInfoAnnotation)
                                     .GetClassReference(targetPackage);
                var annotation = new Annotation {
                    Type = reflectionInfo, Visibility = AnnotationVisibility.Runtime
                };

                bool isPublic = (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;

                // Not sure if it makes any sense to remap the access flags.
                bool isProtected = (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family ||
                                   (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem ||
                                   (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;

                bool isInternal = (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly ||
                                  (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem ||
                                  (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;

                bool isPrivate = (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;

                // only create accessFlags if they differs from java's
                if (isPublic != dmethod.IsPublic ||
                    isProtected != dmethod.IsProtected ||
                    isPrivate != dmethod.IsPrivate ||
                    isInternal)
                {
                    int accessFlags = 0;
                    if (isPublic)
                    {
                        accessFlags |= 0x01;
                    }
                    if (isProtected)
                    {
                        accessFlags |= 0x02;
                    }
                    if (isPrivate)
                    {
                        accessFlags |= 0x04;
                    }
                    if (isInternal)
                    {
                        accessFlags |= 0x08;
                    }
                    annotation.Arguments.Add(new AnnotationArgument(InternalConstants.ReflectionInfoAccessFlagsField, accessFlags));
                }

                if (method.Parameters.Count > 0)
                {
                    annotation.Arguments.Add(new AnnotationArgument(InternalConstants.ReflectionInfoParameterNamesField,
                                                                    method.Parameters.Select(p => p.Name).ToArray()));
                }

                if (annotation.Arguments.Count > 0)
                {
                    dmethod.Annotations.Add(annotation);
                }

                //for (int i = 0; i < xMethod.Parameters.Count; ++i)
                //{
                //    var dp = dmethod.Prototype.Parameters[i];
                //    dp.AddGenericDefinitionAnnotationIfGeneric(xMethod.Parameters[i].ParameterType, compiler,
                //        targetPackage);
                //}
            }
        }
예제 #4
0
        private void AddPropertiesAnnotation(DexTargetPackage targetPackage)
        {
            // Find property accessors
            var propertyMap = new Dictionary <PropertyDefinition, MethodBuilder[]>();

            foreach (var methodBuilder in methodBuilders)
            {
                PropertyDefinition propertyDef;
                bool isSetter;
                if (!methodBuilder.IsPropertyAccessor(out propertyDef, out isSetter))
                {
                    continue;
                }
                MethodBuilder[] accessors;
                if (!propertyMap.TryGetValue(propertyDef, out accessors))
                {
                    accessors = new MethodBuilder[2];
                    propertyMap[propertyDef] = accessors;
                }
                accessors[isSetter ? 1 : 0] = methodBuilder;
            }

            // Build annotations
            if (propertyMap.Count > 0)
            {
                var propertyClass       = compiler.GetDot42InternalType("IProperty").GetClassReference(targetPackage);
                var propertiesClass     = compiler.GetDot42InternalType("IProperties").GetClassReference(targetPackage);
                var propertyAnnotations = new List <Annotation>();

                foreach (var pair in propertyMap)
                {
                    var provider = new PropertyAnnotationProvider {
                        Annotations = new List <Annotation>()
                    };
                    AttributeAnnotationInstanceBuilder.CreateAttributeAnnotations(compiler, pair.Key, provider, targetPackage, true);

                    string propName = pair.Key.Name;

                    var ann = new Annotation(propertyClass, AnnotationVisibility.Runtime,
                                             new AnnotationArgument("Name", propName));
                    if (pair.Value[0] != null)
                    {
                        var getter = pair.Value[0].DexMethod;

                        if (getter.Prototype.Parameters.Count > 0)
                        {
                            // When the VS plugin correctly supports DLog.Info,
                            // this should be changed to Info again.
                            DLog.Debug(DContext.CompilerCodeGenerator,
                                       "not generating property for getter with arguments " + getter);
                            continue;
                        }

                        var getterName = getter.Name;
                        if (getterName != "get_" + propName)
                        {
                            ann.Arguments.Add(new AnnotationArgument("Get", getterName));
                        }
                    }

                    if (pair.Value[1] != null)
                    {
                        var setter = pair.Value[1].DexMethod;
                        if (setter.Prototype.Parameters.Count != 1)
                        {
                            DLog.Info(DContext.CompilerCodeGenerator,
                                      "not generating property for setter with wrong argument count " + setter);
                            continue;
                        }


                        var setterName = setter.Name;
                        if (setterName != "set_" + propName)
                        {
                            ann.Arguments.Add(new AnnotationArgument("Set", setterName));
                        }
                    }

                    //propType = pair.Key.PropertyType;
                    // Mono.Cecil.TypeReference propType = null;

                    var attributes = provider.Annotations.FirstOrDefault();
                    if (attributes != null && attributes.Arguments[0].Value != null)
                    {
                        ann.Arguments.Add(new AnnotationArgument("Attributes", attributes.Arguments[0].Value));
                    }
                    propertyAnnotations.Add(ann);
                }

                var propAnn = new Annotation(propertiesClass, AnnotationVisibility.Runtime,
                                             new AnnotationArgument("Properties", propertyAnnotations.ToArray()));
                Class.Annotations.Add(propAnn);
            }
        }