/// <summary> /// Create an annotation for the given attribute /// </summary> private static void Create(AssemblyCompiler compiler, CustomAttribute attribute, TypeDefinition attributeType, List<Annotation> annotationList, DexTargetPackage targetPackage) { // Gets the mapping for the type of attribute var mapping = compiler.GetAttributeAnnotationType(attributeType); var ctorMap = mapping.CtorMap[attribute.Constructor.Resolve()]; // Create annotation var annotation = new Annotation {Visibility = AnnotationVisibility.Runtime}; annotation.Type = mapping.AnnotationInterfaceClass; // Add ctor arguments var argIndex = 0; foreach (var arg in attribute.ConstructorArguments) { var name = ctorMap.ArgumentGetters[argIndex].Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Type, arg.Value, targetPackage, compiler.Module)); argIndex++; } // Add field values foreach (var arg in attribute.Fields) { var entry = mapping.FieldToGetMethodMap.First(x => x.Key.Name == arg.Name); var name = entry.Value.Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Argument.Type, arg.Argument.Value, targetPackage, compiler.Module)); } // Add property values foreach (var arg in attribute.Properties) { if (mapping.PropertyToGetMethodMap.Keys.Any(x => x.Name == arg.Name)) { var entry = mapping.PropertyToGetMethodMap.First(x => x.Key.Name == arg.Name); var name = entry.Value.Name; annotation.Arguments.Add(CreateAnnotationArgument(name, arg.Argument.Type, arg.Argument.Value, targetPackage, compiler.Module)); } } // Create attribute annotation var attrAnnotation = new Annotation { Visibility = AnnotationVisibility.Runtime }; attrAnnotation.Type = compiler.GetDot42InternalType("IAttribute").GetClassReference(targetPackage); attrAnnotation.Arguments.Add(new AnnotationArgument("AttributeBuilder", ctorMap.Builder)); attrAnnotation.Arguments.Add(new AnnotationArgument("AttributeType", attributeType.GetReference(targetPackage, compiler.Module))); attrAnnotation.Arguments.Add(new AnnotationArgument("Annotation", annotation)); // Add annotation annotationList.Add(attrAnnotation); }
/// <summary> /// Create an annotation for the given attribute /// </summary> private static void CreateAttributeAnnotation(AssemblyCompiler compiler, CustomAttribute attribute, TypeDefinition attributeType, List<Annotation> annotationList, DexTargetPackage targetPackage) { // Gets the mapping for the type of attribute var mapping = compiler.GetAttributeAnnotationMapping(attributeType); MethodDefinition factoryMethod; // Note: not multithreading capable. see my comments elsewhere. if(mapping.FactoryMethodMap.ContainsKey(attribute)) factoryMethod = mapping.FactoryMethodMap[attribute]; else { // create the factory method. factoryMethod = CreateFactoryMethod(compiler, targetPackage, attribute, mapping); mapping.FactoryMethodMap[attribute] = factoryMethod; } // Create attribute annotation var attrAnnotation = new Annotation { Visibility = AnnotationVisibility.Runtime }; attrAnnotation.Type = compiler.GetDot42InternalType("IAttribute").GetClassReference(targetPackage); attrAnnotation.Arguments.Add(new AnnotationArgument("AttributeType", attributeType.GetReference(targetPackage, compiler.Module))); attrAnnotation.Arguments.Add(new AnnotationArgument("FactoryMethod", factoryMethod.Name)); // Add annotation annotationList.Add(attrAnnotation); }