示例#1
0
        /// <summary>
        /// Implement the class now that all classes have been created
        /// </summary>
        protected override void CreateMembers(DexTargetPackage targetPackage)
        {
            // Build value ctor
            var module    = Compiler.Module;
            var isWide    = Type.GetEnumUnderlyingType().Resolve().IsWide();
            var enumType  = Compiler.GetDot42InternalType("Enum");
            var valueType = isWide ? module.TypeSystem.Long : module.TypeSystem.Int;

            // Build default ctor
            defaultCtor = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Constructor, "<init>", module.TypeSystem.Void);
            Class.Methods.Add(defaultCtor.GetDexMethod(Class, targetPackage));

            // Build Create method
            create = XSyntheticMethodDefinition.Create(XType, XSyntheticMethodFlags.Protected, "Create", enumType,
                                                       XParameter.Create("value", valueType));
            Class.Methods.Add(create.GetDexMethod(Class, targetPackage));
        }
示例#2
0
        /// <summary>
        /// Create the body of the valueOf(string) method.
        /// </summary>
        private AstBlock CreateValueOfBody(XSyntheticMethodDefinition method, XFieldDefinition enumInfoField, XTypeSystem typeSystem)
        {
            var internalEnumType     = Compiler.GetDot42InternalType("Enum");
            var internalEnumInfoType = Compiler.GetDot42InternalType("EnumInfo");
            var parseMethod          = new XMethodReference.Simple("Parse", true, internalEnumType, internalEnumInfoType,
                                                                   XParameter.Create("value", typeSystem.String),
                                                                   XParameter.Create("ignoreCase", typeSystem.Bool),
                                                                   XParameter.Create("throwIfNotFound", typeSystem.Bool));

            var ast = AstBlock.CreateOptimizedForTarget(
                new AstExpression(AstNode.NoSource, AstCode.Ret, null,
                                  new AstExpression(AstNode.NoSource, AstCode.SimpleCastclass, XType,
                                                    new AstExpression(AstNode.NoSource, AstCode.Call, parseMethod,
                                                                      new AstExpression(AstNode.NoSource, AstCode.Ldsfld, enumInfoField),
                                                                      new AstExpression(AstNode.NoSource, AstCode.Ldloc, method.AstParameters[0]),
                                                                      new AstExpression(AstNode.NoSource, AstCode.Ldc_I4, 0),
                                                                      new AstExpression(AstNode.NoSource, AstCode.Ldc_I4, 1)))));

            return(ast);
        }
示例#3
0
 /// <summary>
 /// Reference to java.lang.String.equals(string)
 /// </summary>
 internal static XMethodReference StringEquals(XTypeSystem typeSystem)
 {
     return(new XMethodReference.Simple("equals", true, typeSystem.Bool, typeSystem.String, XParameter.Create("other", typeSystem.Object)));
 }
示例#4
0
        /// <summary>
        /// Create the body of the class ctor.
        /// </summary>
        private AstBlock CreateClassCtorBody(bool isWide, XFieldDefinition enumInfoField, XFieldDefinition defaultField, XMethodReference enumInfoCtor, XTypeReference valueType, XTypeSystem typeSystem)
        {
            var internalEnumType     = Compiler.GetDot42InternalType("Enum");
            var internalEnumInfoType = Compiler.GetDot42InternalType("EnumInfo");
            var valueToFieldMap      = new Dictionary <object, XFieldDefinition>();
            var ldc = isWide ? AstCode.Ldc_I8 : AstCode.Ldc_I4;

            var ast = AstBlock.CreateOptimizedForTarget(
                // Instantiate enum info field
                new AstExpression(AstNode.NoSource, AstCode.Stsfld, enumInfoField,
                                  new AstExpression(AstNode.NoSource, AstCode.Newobj, enumInfoCtor)));

            // Instantiate values for each field
            var ordinal = 0;

            foreach (var field in XType.Fields.Where(x => x.IsStatic && !(x is XSyntheticFieldDefinition)))
            {
                // Find dex field
                object value;
                if (!field.TryGetEnumValue(out value))
                {
                    throw new CompilerException(string.Format("Cannot get enum value from field {0}", field.FullName));
                }
                value = isWide ? (object)XConvert.ToLong(value) : (object)XConvert.ToInt(value);
                XFieldDefinition existingField;
                AstExpression    valueExpr;
                if (valueToFieldMap.TryGetValue(value, out existingField))
                {
                    // Re-use instance of existing field
                    valueExpr = new AstExpression(AstNode.NoSource, AstCode.Ldsfld, existingField);
                }
                else
                {
                    // Record
                    valueToFieldMap[value] = field;

                    // Call ctor
                    valueExpr = new AstExpression(AstNode.NoSource, AstCode.Newobj, ctor,
                                                  new AstExpression(AstNode.NoSource, AstCode.Ldstr, field.Name),
                                                  new AstExpression(AstNode.NoSource, AstCode.Ldc_I4, ordinal),
                                                  new AstExpression(AstNode.NoSource, ldc, value));
                }

                // Initialize static field
                ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Stsfld, field, valueExpr));

                // Add to info
                var addMethod = new XMethodReference.Simple("Add", true, typeSystem.Void, internalEnumInfoType,
                                                            XParameter.Create("value", valueType),
                                                            XParameter.Create("instance", internalEnumType));
                ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Call, addMethod,
                                               new AstExpression(AstNode.NoSource, AstCode.Ldsfld, enumInfoField),
                                               new AstExpression(AstNode.NoSource, ldc, value),
                                               new AstExpression(AstNode.NoSource, AstCode.Ldsfld, field)));

                // Increment ordinal
                ordinal++;
            }

            // Initialize default field
            var getValueMethod = new XMethodReference.Simple("GetValue", true, internalEnumType, internalEnumInfoType,
                                                             XParameter.Create("value", valueType));

            ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Stsfld, defaultField,
                                           new AstExpression(AstNode.NoSource, AstCode.SimpleCastclass, XType,
                                                             new AstExpression(AstNode.NoSource, AstCode.Call, getValueMethod,
                                                                               new AstExpression(AstNode.NoSource, AstCode.Ldsfld, enumInfoField),
                                                                               new AstExpression(AstNode.NoSource, ldc, 0)))));

            // Return
            ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Ret, null));
            return(ast);
        }
示例#5
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));
        }