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