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