public override void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            if (_baseFieldBuilder.dfield == null)
            {
                return;
            }

            // can't create udater for static fields.
            if (field.IsStatic)
            {
                return;
            }

            var updaterType = GetAtomicFieldUpdaterType(field.FieldType);

            if (updaterType == null)
            {
                return;
            }

            var fullUpdateTypeName = "Java.Util.Concurrent.Atomic." + updaterType;

            // create matching xField. Note: this seems to be a hack. what to do?

            var objType           = new ObjectTypeReference(fullUpdateTypeName, new TypeArgument[0]);
            var javaTypeReference = new XBuilder.JavaTypeReference(Compiler.Module, objType, objType.ClassName);

            var basexField = _baseFieldBuilder.xField;
            var basedField = _baseFieldBuilder.dfield;
            var fieldName  = basedField.Name + NameConstants.Atomic.FieldUpdaterPostfix;

            var xflags = XSyntheticFieldFlags.Static | XSyntheticFieldFlags.ReadOnly;

            if (basedField.IsProtected)
            {
                xflags |= XSyntheticFieldFlags.Protected;
            }
            if (basedField.IsPrivate)
            {
                xflags |= XSyntheticFieldFlags.Private;
            }


            var xAtomicField = XSyntheticFieldDefinition.Create(basexField.DeclaringType, xflags, fieldName, javaTypeReference);

            xField = xAtomicField;

            // create dfield.

            dfield = new DexLib.FieldDefinition
            {
                Name        = fieldName,
                IsStatic    = true,
                IsFinal     = true,
                IsSynthetic = true,
                // same access as the original field.
                IsPublic    = basedField.IsPublic,
                IsPrivate   = basedField.IsPrivate,
                IsProtected = basedField.IsProtected,
            };

            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);

            targetPackage.NameConverter.Record(xField, dfield);
        }
Esempio n. 2
0
        /// <summary>
        /// Implement the class now that all classes have been created
        /// </summary>
        protected override void CreateMembers(DexTargetPackage targetPackage)
        {
            // Build value__ field
            var module             = Compiler.Module;
            var underlyingEnumType = Type.GetEnumUnderlyingType();
            var isWide             = underlyingEnumType.IsWide();
            var xValueType         = isWide ? module.TypeSystem.Long : module.TypeSystem.Int;
            var valueField         = XSyntheticFieldDefinition.Create(XType, XSyntheticFieldFlags.Protected, NameConstants.Enum.ValueFieldName, xValueType);

            Class.Fields.Add(valueField.GetDexField(Class, targetPackage));

            // Create normal members
            base.CreateMembers(targetPackage);

            // Build value ctor
            ctor = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Constructor | XSyntheticMethodFlags.Protected, "<init>", module.TypeSystem.Void,
                                                     XParameter.Create("name", module.TypeSystem.String),
                                                     XParameter.Create("ordinal", module.TypeSystem.Int),
                                                     XParameter.Create("value", xValueType));
            ctor.Body = CreateCtorBody(ctor);
            Class.Methods.Add(ctor.GetDexMethod(Class, targetPackage));

            // Build enumInfo field
            var internalEnumInfoType = Compiler.GetDot42InternalType("EnumInfo");
            var enumInfoField        = XSyntheticFieldDefinition.Create(XType, XSyntheticFieldFlags.Static, NameConstants.Enum.InfoFieldName, internalEnumInfoType /* enumInfoClassBuilder.Class*/);

            Class.Fields.Add(enumInfoField.GetDexField(Class, targetPackage));

            // Build default__ field
            var defaultField = XSyntheticFieldDefinition.Create(XType, XSyntheticFieldFlags.Static, NameConstants.Enum.DefaultFieldName, XType);

            Class.Fields.Add(defaultField.GetDexField(Class, targetPackage));

            // Build class ctor
            var classCtor = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Static | XSyntheticMethodFlags.Constructor | XSyntheticMethodFlags.Private, "<clinit>", module.TypeSystem.Void);

            classCtor.Body = CreateClassCtorBody(isWide, enumInfoField, defaultField, enumInfoClassBuilder.DefaultCtor, xValueType, module.TypeSystem);
            Class.Methods.Add(classCtor.GetDexMethod(Class, targetPackage));

            if (!isWide)
            {
                // Build IntValue method
                var intValue = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Virtual, "IntValue", module.TypeSystem.Int);
                intValue.Body = CreateIntOrLongValueBody();
                Class.Methods.Add(intValue.GetDexMethod(Class, targetPackage));
            }
            else
            {
                // Build LongValue method
                var longValue = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Virtual, "LongValue", module.TypeSystem.Long);
                longValue.Body = CreateIntOrLongValueBody();
                Class.Methods.Add(longValue.GetDexMethod(Class, targetPackage));
            }

            // Build values() method
            var valuesMethod = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Static, NameConstants.Enum.ValuesMethodName, new XArrayType(XType));

            valuesMethod.Body = CreateValuesBody();
            Class.Methods.Add(valuesMethod.GetDexMethod(Class, targetPackage));

            // Build valueOf(string) method
            var valueOfMethod = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Static, NameConstants.Enum.ValueOfMethodName, XType, XParameter.Create("name", module.TypeSystem.String));

            valueOfMethod.Body = CreateValueOfBody(valueOfMethod, module.TypeSystem);
            Class.Methods.Add(valueOfMethod.GetDexMethod(Class, targetPackage));

            // Build Unbox(object) method
            unboxMethod      = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Static, NameConstants.Enum.UnboxMethodName, XType, XParameter.Create("value", Compiler.Module.TypeSystem.Object));
            unboxMethod.Body = CreateUnboxBody(unboxMethod, isWide, Compiler);
            Class.Methods.Add(unboxMethod.GetDexMethod(Class, targetPackage));
        }