/// <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)); } }
/// <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); }
/// <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); //} } }
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); } }