public override void CreateAnnotations(DexTargetPackage targetPackage) { // Note: Maybe it makes more sense to not save this property // information as annotations, but as an asset e.g. in a // simple .ini like format. This would also be true for // the AssemblyType annotations. var compiler = Compiler; if (!compiler.AddFrameworkPropertyAnnotations()) { return; } var propertyClass = compiler.GetDot42InternalType("IProperty").GetClassReference(targetPackage); var propertiesClass = compiler.GetDot42InternalType("IProperties").GetClassReference(targetPackage); var reflInfoRef = compiler.GetDot42InternalType("Dot42.Internal.ReflectionInfo", "FrameworkPropertyInfoProvider") .GetClassReference(targetPackage); var relfInfo = targetPackage.DexFile.GetClass(reflInfoRef.Fullname); var thisRef = XType.GetClassReference(targetPackage); var thisrefDexClassName = thisRef.Descriptor.Substring(1, thisRef.Descriptor.Length - 2); var properties = relfInfo.Annotations.FirstOrDefault(a => a.Type.Fullname == propertiesClass.Fullname); if (properties == null) { properties = new Annotation(propertiesClass, AnnotationVisibility.Runtime); // note we are using a list, undil all class builders have properties.Arguments.Add(new AnnotationArgument("Properties", new List <Annotation>())); relfInfo.Annotations.Add(properties); } var propertyList = (List <Annotation>)properties.Arguments.Single().Value; foreach (var prop in Type.Properties) { // don't generate setter-only properties (which don't exist // due to the framework generator anyways) if (prop.GetMethod == null || prop.GetMethod.HasParameters) { continue; } string propName = prop.Name; string getterName = GetMethodName(prop.GetMethod, thisrefDexClassName); string setterName = GetMethodName(prop.SetMethod, thisrefDexClassName); if (getterName == null && setterName == null) { continue; } var ann = new Annotation(propertyClass, AnnotationVisibility.Runtime, new AnnotationArgument("DeclaringTypeDescriptor", thisRef.Descriptor), new AnnotationArgument("Name", propName)); // We might save a few bytes by abbreviating the common pattern "isProperty" with // a special code like "is*". This would be interpreted by the PropertyInfoProvider // to generate the setter/getter names. if (getterName != null && getterName != "get" + propName) { ann.Arguments.Add(new AnnotationArgument("Get", getterName)); } if (setterName != null && setterName != "set" + propName) { ann.Arguments.Add(new AnnotationArgument("Set", setterName)); } propertyList.Add(ann); } }