Exemple #1
0
        /// <summary>
        /// Gets the field attributes.
        /// </summary>
        /// <param name="jf">The java field.</param>
        /// <returns>The attributes of the field.</returns>
        public static FieldAttributes GetAttributes(this JavaField jf)
        {
            Guard.NotNull(ref jf, nameof(jf));
            JavaFieldAccessFlags accessFlags = jf.AccessFlags;

            FieldAttributes result = 0;

            if (accessFlags.HasFlag(JavaFieldAccessFlags.Static))
            {
                result |= FieldAttributes.Static;
            }

            if (accessFlags.HasFlag(JavaFieldAccessFlags.Public))
            {
                result |= FieldAttributes.Public;
            }

            if (accessFlags.HasFlag(JavaFieldAccessFlags.Private))
            {
                result |= FieldAttributes.Private;
            }

            if (accessFlags.HasFlag(JavaFieldAccessFlags.Protected))
            {
                result |= FieldAttributes.Family;
            }

            return(result);
        }
Exemple #2
0
        public static MetadataJavaField ToMetadata(this JavaField field)
        {
            var javaField = new MetadataJavaField
            {
                Name = field.Name,
                Type = field.Type.GetSignature()
            };

            if (field.ConstantValue != null)
            {
                using var stream = new MemoryStream();
                using var ms     = new MemoryOutputStream(stream);
                using var dos    = new DataOutputStream(ms);

                field.ConstantValue.Dump(dos);

                //Write the original string there to be able to create a new constantpool from metadata
                if (field.ConstantValue is ConstantString constantString)
                {
                    dos.WriteUTF(constantString.GetBytes(field.ConstantPool));
                }

                javaField.ConstantValue = stream.ToArray();
            }

            return(javaField);
        }
Exemple #3
0
        /// <summary>
        /// Gets the descriptor of a method.
        /// </summary>
        /// <param name="jf">The java field.</param>
        /// <param name="jc">The java class.</param>
        /// <returns>The descriptor of the java method.</returns>
        public static string GetDescriptor(this JavaField jf, JavaClass jc)
        {
            Guard.NotNull(ref jc, nameof(jc));
            Guard.NotNull(ref jf, nameof(jf));

            return(jc.GetConstant <JavaConstantUtf8>(jf.DescriptorIndex).Value);
        }
 public void AddItemsToCart()
 {
     JavaField.SendKeys("1" + Keys.Enter);
     RubyField.SendKeys("2");
     PythonField.SendKeys("1");
     AddButton.Click();
 }
Exemple #5
0
 void LoadDll(string file, string sourceIdentifier = null)
 {
     foreach (var ta in AssemblyDefinition.ReadAssembly(file).Modules.SelectMany(m => m.Types.SelectMany(t => FlattenTypeHierarchy(t)))
              .Where(ta => !ta.Name.EndsWith("Invoker", StringComparison.Ordinal) && !ta.Name.EndsWith("Implementor", StringComparison.Ordinal))
              .Select(t => new Tuple <TypeDefinition, CustomAttribute> (t, GetRegisteredAttribute(t)))
              .Where(p => p.Item2 != null))
     {
         var td   = ta.Item1;
         var tatt = PopulateRegisterAttributeInfo(ta.Item2, true);
         var pkg  = Api.Packages.FirstOrDefault(p => p.Name == tatt.Package);
         if (pkg == null)
         {
             Api.Packages.Add(pkg = new JavaPackage(Api)
             {
                 Name = tatt.Package
             });
         }
         var type = td.IsInterface ? (JavaType) new JavaInterface(pkg) : new JavaClass(pkg);
         type.Name = tatt.Name;
         type.SetExtension(td);
         pkg.Types.Add(type);
         foreach (var fa in td.Fields
                  .Select(f => new Tuple <FieldDefinition, CustomAttribute> (f, GetRegisteredAttribute(f)))
                  .Where(p => p.Item2 != null))
         {
             var matt = PopulateRegisterAttributeInfo(fa.Item2);
             var f    = new JavaField(type)
             {
                 Name = matt.Name, Static = fa.Item1.IsStatic, Final = fa.Item1.HasConstant
             };
             f.SetExtension(fa.Item1);
             type.Members.Add(f);
         }
         foreach (var ma in GetAllMethods(td)
                  .Where(m => m != null)
                  .Select(m => new Tuple <MethodDefinition, CustomAttribute> (m, GetRegisteredAttribute(m)))
                  .Where(p => p.Item2 != null))
         {
             var matt = PopulateRegisterAttributeInfo(ma.Item2);
             var m    = new JavaMethod(type)
             {
                 Name = matt.Name, Abstract = ma.Item1.IsAbstract, Static = ma.Item1.IsStatic
             };
             var jniParameters = matt.JniSignature.Substring(0, matt.JniSignature.IndexOf(')')).Substring(1);
             m.Return     = ParseJniParameters(matt.JniSignature.Substring(matt.JniSignature.IndexOf(')') + 1)).First();
             m.Parameters = ParseJniParameters(jniParameters)
                            .Zip(ma.Item1.Parameters, (s, mp) => new { Type = s, ManagedParameter = mp })
                            .Select(_ => new JavaParameter(m)
             {
                 Name = _.ManagedParameter.Name, Type = _.Type
             })
                            .ToArray();
             m.SetExtension(ma.Item1);
             type.Members.Add(m);
         }
     }
     FillSourceIdentifier(Api, sourceIdentifier ?? file);
 }
        private string TraverseField(JavaField javaField)
        {
            var declaredAccesibility = accessibilityResolver.ResolveAccesebility(javaField.DeclaredAccessibility);
            var staticStr            = javaField.IsStatic ? "static" : "";
            var fieldStr             = string.Format("{0} {1} {2} {3}", declaredAccesibility, staticStr, javaTypeResolver.Resolve(javaField.TypeSymbol), javaField.FieldName);

            return(javaField.Initialization != null
                ? string.Format("{0} = {1}", fieldStr, statementTraverser.TraverseStmt(javaField.Initialization)).Trim()
                : fieldStr.Trim());
        }
Exemple #7
0
        /// <summary>
        /// Reads fields from the stream.
        /// </summary>
        /// <param name="stream">The stream to read the fields from.</param>
        /// <param name="count">The number of fields to read.</param>
        /// <param name="constantPool">The constant pool used for finding the attribute names.</param>
        /// <returns>The fields read from the stream.</returns>
        private static JavaField[] ReadFields(Stream stream, int count, JavaConstantPool constantPool)
        {
            JavaField[] result = new JavaField[count];

            for (int i = 0; i < count; i++)
            {
                result[i] = ReadField(stream, constantPool);
            }

            return(result);
        }
Exemple #8
0
 public JavaField ResoverField()
 {
     if (Field == null)
     {
         var targetclass = this.ResoverClass();
         var temp        = targetclass.LookUpField(this.Name, this.Desc);
         if (!temp.IsAccessTo(targetclass))
         {
             throw new Exception();
         }
         Field = temp;
     }
     return(Field);
 }
Exemple #9
0
        public static void ConstructorTest()
        {
            JavaFieldAccessFlags flags = JavaFieldAccessFlags.Enum | JavaFieldAccessFlags.Private;
            ushort us1 = 1;
            ushort us2 = 2;
            ushort us3 = 3;

            IJavaAttribute[] attributes = new IJavaAttribute[2];
            JavaField        jf         = new JavaField(flags, us1, us2, us3, attributes);

            AssertThat(jf.AccessFlags).IsEqualTo(flags);
            AssertThat(jf.NameIndex).IsEqualTo(us1);
            AssertThat(jf.DescriptorIndex).IsEqualTo(us2);
            AssertThat(jf.AttributesCount).IsEqualTo(us3);
            AssertThat(jf.Attributes).ContainsExactly(attributes);
        }
Exemple #10
0
        public IJavaData Convert(JavaObject @object)
        {
            JavaObject transformed = new JavaObject(@object.Type);

            transformed.Fields.AddRange(@object.Fields);
            for (int i = 1; i < @object.Custom.Count; i += 2)
            {
                JavaValue value = @object.Custom[i] as JavaValue;
                if (value == null)
                {
                    continue;
                }
                JavaField field = new JavaField(value.Get <string>(), @object.Custom[i + 1]);
                transformed.Fields.Add(field);
            }
            return(transformed);
        }
Exemple #11
0
        /// <summary>
        /// Gets the attributes of the given type.
        /// </summary>
        /// <typeparam name="T">The type of the attributes.</typeparam>
        /// <param name="jf">The java field.</param>
        /// <returns>The attributes of the given type.</returns>
        public static T[] GetAttributes <T>(this JavaField jf)
            where T : IJavaAttribute
        {
            Guard.NotNull(ref jf, nameof(jf));

            List <T> result = new List <T>();

            foreach (IJavaAttribute attribute in jf.Attributes)
            {
                if (attribute is T matched)
                {
                    result.Add(matched);
                }
            }

            return(result.ToArray());
        }
Exemple #12
0
    FieldDefinition BuildCilField(TypeDefinition cilType, JavaField jfield)
    {
        FieldAttributes attrs = 0;

        if ((jfield.Flags & JavaAccessFlags.ACC_PUBLIC) != 0)
        {
            attrs = FieldAttributes.Public;
        }
        else if ((jfield.Flags & JavaAccessFlags.ACC_PRIVATE) != 0)
        {
            attrs = FieldAttributes.Private;
        }
        else if ((jfield.Flags & JavaAccessFlags.ACC_PROTECTED) != 0)
        {
            attrs = FieldAttributes.FamORAssem;
        }
        else
        {
            attrs = FieldAttributes.Assembly;
        }

        if ((jfield.Flags & JavaAccessFlags.ACC_STATIC) != 0)
        {
            attrs |= FieldAttributes.Static;
        }

        if ((jfield.Flags & JavaAccessFlags.ACC_FINAL) != 0)
        {
            attrs |= FieldAttributes.InitOnly;
        }

        var fieldDef = new FieldDefinition(
            jfield.Name, attrs, CilTypeReference(jfield.Type));

        if (cilType.IsInterface && jfield.Constant != null)
        {
            fieldDef.Constant  = jfield.Constant;
            fieldDef.IsLiteral = true;
        }

        return(fieldDef);
    }
Exemple #13
0
 public IEnumerable <IJavaData> Select(IJavaData data)
 {
     if (data is JavaArray)
     {
         foreach (IJavaData child in ((JavaArray)data).Items)
         {
             foreach (IJavaData result in Select(child))
             {
                 yield return(result);
             }
         }
     }
     else if (data is JavaObject)
     {
         JavaField field = ((JavaObject)data).Fields.FirstOrDefault(f => f.Name == Name);
         if (field != null)
         {
             yield return(field.Value);
         }
     }
 }
Exemple #14
0
        public static JavaClass MakeGenericClass(JavaClass fromClass, CilType fromType)
        {
            // if the generic class has static fields or a static initializer
            // then we need to move those into a separate class that can be
            // instantiated multiple times for multiple separate instances,
            // one for each concrete implementation of the generic type.

            int numGeneric = fromType.GenericParameters.Count;

            var dataClass = MoveStaticFields(fromClass, null);

            dataClass = MoveStaticInit(fromClass, dataClass);

            if (dataClass != null)
            {
                FixConstructorInData(dataClass, numGeneric);
            }

            // a generic class implements the IGenericObject interface,
            // and has a generic-type field for the concrete implementation
            // of the generic type and generic arguments

            CreateGenericTypeFields(fromClass, numGeneric);
            BuildGetTypeMethod(fromClass, fromType);

            return(dataClass);

            //
            // move any static fields from the generic class,
            // as instance fields in a new class
            //

            JavaClass MoveStaticFields(JavaClass fromClass, JavaClass dataClass)
            {
                var fields = fromClass.Fields;

                if (fields == null)
                {
                    return(dataClass);
                }

                int n = fields.Count;

                for (int i = 0; i < n;)
                {
                    var fld = fields[i];
                    if ((fld.Flags & JavaAccessFlags.ACC_STATIC) == 0)
                    {
                        i++;
                        continue;
                    }
                    if (((CilType)fld.Type).IsLiteral)
                    {
                        i++;
                        continue;
                    }

                    if (dataClass == null)
                    {
                        dataClass = CreateClass(fromClass);
                    }

                    if (fld.Constant != null)
                    {
                        throw CilMain.Where.Exception($"initializer in static field '{fld.Name}' in generic class");
                    }

                    fields.RemoveAt(i);
                    n--;

                    fld.Flags &= ~JavaAccessFlags.ACC_STATIC;
                    dataClass.Fields.Add(fld);
                }

                return(dataClass);
            }

            //
            // move the static constructor/initializer
            // from the generic class to the new data class
            //

            JavaClass MoveStaticInit(JavaClass fromClass, JavaClass dataClass)
            {
                var methods = fromClass.Methods;
                int n       = methods.Count;

                for (int i = 0; i < n;)
                {
                    var mth = methods[i];
                    if (mth.Name != "<clinit>")
                    {
                        i++;
                        continue;
                    }

                    if (dataClass == null)
                    {
                        dataClass = CreateClass(fromClass);
                    }

                    methods.RemoveAt(i);
                    n--;

                    mth.Name  = "<init>";
                    mth.Class = dataClass;
                    mth.Flags = JavaAccessFlags.ACC_PUBLIC;
                    dataClass.Methods.Add(mth);
                }

                return(dataClass);
            }

            //
            // create a constructor if there was no static initializer,
            // or inject a call to super class constructor
            //

            void FixConstructorInData(JavaClass dataClass, int numGeneric)
            {
                JavaCode code;
                bool     insertReturn;

                if (dataClass.Methods.Count == 0)
                {
                    code         = CilMethod.CreateConstructor(dataClass, numGeneric, true);
                    insertReturn = true;

                    code.MaxStack  = 1;
                    code.MaxLocals = 1 + numGeneric;
                }
                else
                {
                    code = dataClass.Methods[0].Code;
                    if (code.MaxStack < 1)
                    {
                        code.MaxStack = 1;
                    }

                    // we are injecting a call to super constructor at the very top,
                    // so local 0 should have the proper type, not uninitializedThis
                    code.StackMap.SetLocalInAllFrames(
                        0, CilType.From(new JavaType(0, 0, dataClass.Name)), null);

                    insertReturn = false;
                }

                code.Instructions.Insert(0, new Instruction(
                                             0x19 /* aload */, null, (int)0, 0xFFFF));

                code.Instructions.Insert(1, new Instruction(
                                             0xB7 /* invokespecial */, JavaType.ObjectType,
                                             new JavaMethodRef("<init>", JavaType.VoidType), 0xFFFF));

                // the static initializer can call static methods on its own type,
                // and those methods can invoke system.RuntimeType.GetType() to get
                // a reference to the generic type that is still being initialized.
                // and more importantly, a reference to the the static-generic data
                // object that is constructed by this method.  to make the object
                // available to such access, we call system.RuntimeType.SetStatic().
                // see also system.RuntimeType.MakeGenericType/MakeGenericType().

                code.Instructions.Insert(2, new Instruction(
                                             0x19 /* aload */, null, (int)0, 0xFFFF));

                code.Instructions.Insert(3, new Instruction(
                                             0xB8 /* invokestatic */, CilType.SystemRuntimeTypeType,
                                             new JavaMethodRef("SetStatic",
                                                               JavaType.VoidType, JavaType.ObjectType), 0xFFFF));

                if (insertReturn)
                {
                    code.NewInstruction(JavaType.VoidType.ReturnOpcode, null, null, 0xFFFF);
                }
            }

            //
            // create the new data class
            //

            JavaClass CreateClass(JavaClass fromClass) =>
            CilMain.CreateInnerClass(fromClass, fromClass.Name + "$$static", 0,
                                     markGenericEntity: true);

            //
            // create a private instance field to hold the runtime type
            // for a particular combination of generic type and arguments
            //

            void CreateGenericTypeFields(JavaClass fromClass, int numGeneric)
            {
                var fld = new JavaField();

                fld.Name  = ConcreteTypeField.Name;
                fld.Type  = ConcreteTypeField.Type;
                fld.Class = fromClass;
                fld.Flags = JavaAccessFlags.ACC_PRIVATE;

                if (fromClass.Fields == null)
                {
                    fromClass.Fields = new List <JavaField>();
                }

                fromClass.Fields.Add(fld);
            }
        }
Exemple #15
0
        //
        //
        //

        public static void CreateGenericVarianceField(JavaClass theClass, CilType fromType,
                                                      TypeDefinition defType)
        {
            // check if any of the generic parameters are variant.
            // note that generic parameter variance is only supported
            // on interfaces and delegates.

            if (!(fromType.IsInterface || fromType.IsDelegate))
            {
                return;
            }
            string varianceString = null;

            bool anyVariance = false;

            foreach (var gp in defType.GenericParameters)
            {
                if ((gp.Attributes & GenericParameterAttributes.VarianceMask) != 0)
                {
                    anyVariance = true;
                    break;
                }
            }
            if (!anyVariance)
            {
                /* removed; see IComparer.cs in baselib
                 * if (fromType.JavaName == "system.collections.generic.IComparer$$1")
                 * {
                 *  // force a variance string for an interface that we create
                 *  // as an abstract class;  see also IComparer.cs in baselib
                 *  varianceString = "I";
                 * }
                 * else*/
                return;
            }

            // build a string that describes the generic variance

            if (varianceString == null)
            {
                var chars = new char[defType.GenericParameters.Count];
                int idx   = 0;
                foreach (var gp in defType.GenericParameters)
                {
                    var v = gp.Attributes & GenericParameterAttributes.VarianceMask;
                    chars[idx++] = (v == GenericParameterAttributes.Covariant)     ? 'O'
                                 : (v == GenericParameterAttributes.Contravariant) ? 'I'
                                                                                   : ' ';
                }
                varianceString = new string(chars);
            }

            var varianceField = new JavaField();

            varianceField.Name  = "-generic-variance";
            varianceField.Type  = JavaType.StringType;
            varianceField.Flags = JavaAccessFlags.ACC_STATIC
                                  | JavaAccessFlags.ACC_FINAL
                                  | JavaAccessFlags.ACC_PUBLIC
                                  | JavaAccessFlags.ACC_TRANSIENT
                                  | JavaAccessFlags.ACC_SYNTHETIC;
            varianceField.Constant = varianceString;
            varianceField.Class    = theClass;

            if (theClass.Fields == null)
            {
                theClass.Fields = new List <JavaField>();
            }
            theClass.Fields.Add(varianceField);
        }
Exemple #16
0
        public static List <JavaClass> BuildProxyMethods(List <CilInterface> allInterfaces,
                                                         TypeDefinition fromType, CilType intoType,
                                                         JavaClass theClass)
        {
            //
            // process only if the class (or interface) has any methods or super interfaces
            //

            var classMethods = theClass.Methods;

            if (classMethods.Count == 0)
            {
                return(null);
            }

            bool isInterface = intoType.IsInterface;

            if ((!isInterface) && theClass.Interfaces == null)
            {
                return(null);
            }

            var theMethods = CilInterfaceMethod.CollectAll(fromType);

            //
            // if any interfaces are marked [RetainName], make sure that
            // all corresponding methods are also marked [RetainName]
            //

            CheckRetainNameMethods(theMethods, allInterfaces, intoType);

            //
            // if this is an abstract class but forced to an interface via [AddInterface]
            // decoration, then we need to remove all constructors generated for the class
            //

            if (intoType.IsInterface)
            {
                if (!fromType.IsInterface)
                {
                    for (int i = classMethods.Count; i-- > 0;)
                    {
                        if (classMethods[i].Name == "<init>")
                        {
                            classMethods.RemoveAt(i);
                        }
                    }
                }

                if (intoType.HasGenericParameters)
                {
                    // the RuntimeType constructor in baselib uses IGenericEntity
                    // marker interface to identify generic classes.  note that
                    // real generic types implement IGenericObject -> IGenericEntity.

                    theClass.AddInterface("system.IGenericEntity");
                }

                return(null);
            }

            //
            // for each implemented interface, build proxy methods
            //

            List <JavaClass> output = null;

            int ifcNumber = 0;

            foreach (var ifc in allInterfaces)
            {
                if ((!ifc.DirectReference) && ifc.SuperImplements)
                {
                    // we don't have to build proxy for an interface if it is
                    // implemented by a super type and not by our primary type
                    continue;
                }
                if (ifc.GenericTypes == null)
                {
                    foreach (var ifcMethod in ifc.Methods)
                    {
                        // build proxy methods:  interface$method -> method
                        var newMethod = BuildPlainProxy(ifcMethod, intoType, theMethods);
                        if (newMethod != null)
                        {
                            newMethod.Class = theClass;
                            theClass.Methods.Add(newMethod);
                        }
                    }
                }
                else
                {
                    var ifcClass = CreateInnerClass(theClass, intoType, ++ifcNumber);
                    ifcClass.AddInterface(ifc.InterfaceType.JavaName);

                    if (output == null)
                    {
                        output = new List <JavaClass>();
                        CreateInterfaceArrayField(theClass);
                    }
                    output.Add(ifcClass);

                    // if the class implements a generic interface for multiple types,
                    // then we need a method suffix to differentiate between the methods.
                    // see also:  CilMethod::InsertMethodNamePrefix
                    string methodSuffix = "";
                    foreach (var genericType in ifc.GenericTypes)
                    {
                        methodSuffix += "--" + CilMethod.GenericParameterSuffixName(genericType);
                    }

                    foreach (var ifcMethod in ifc.Methods)
                    {
                        // build proxy classes:  proxy sub-class -> this class
                        BuildGenericProxy(ifcMethod, methodSuffix, intoType, theMethods, ifcClass);
                    }
                }
            }

            return(output);

            JavaClass CreateInnerClass(JavaClass parentClass, CilType parentType, int ifcNumber)
            {
                // generic interfaces are implemented as proxy sub-classes which
                // call methods on the parent class object.  we need to define
                // an inner class.  this class has one instance field which is a
                // reference to the parent class.  the constructor takes this
                // reference as a parameter and initializes the instance field.

                var newClass = CilMain.CreateInnerClass(parentClass,
                                                        parentClass.Name + "$$generic" + ifcNumber.ToString());

                var fld = new JavaField();

                fld.Name  = ParentFieldName;
                fld.Type  = parentType;
                fld.Class = newClass;
                fld.Flags = JavaAccessFlags.ACC_PRIVATE;
                newClass.Fields.Add(fld);

                var code = CilMain.CreateHelperMethod(newClass,
                                                      new JavaMethodRef("<init>", JavaType.VoidType, JavaType.ObjectType),
                                                      2, 2);

                code.Method.Flags &= ~JavaAccessFlags.ACC_BRIDGE;   // invalid for constructor

                code.NewInstruction(0x19 /* aload */, null, (int)0);
                code.NewInstruction(0xB7 /* invokespecial */, JavaType.ObjectType,
                                    new JavaMethodRef("<init>", JavaType.VoidType));
                code.NewInstruction(0x19 /* aload */, null, (int)0);
                code.NewInstruction(0x19 /* aload */, null, (int)1);
                code.NewInstruction(0xC0 /* checkcast */, parentType, null);
                code.NewInstruction(0xB5 /* putfield */, new JavaType(0, 0, newClass.Name),
                                    new JavaFieldRef(ParentFieldName, parentType));
                code.NewInstruction(JavaType.VoidType.ReturnOpcode, null, null);

                return(newClass);
            }

            void CreateInterfaceArrayField(JavaClass parentClass)
            {
                // the parent class has a helper array field that is used to track
                // the proxy objects generated for implemented generic interfaces.
                // see also: InitInterfaceArrayField, below.

                var fld = new JavaField();

                fld.Name  = InterfaceArrayField.Name;
                fld.Type  = InterfaceArrayField.Type;
                fld.Class = parentClass;
                fld.Flags = JavaAccessFlags.ACC_PRIVATE;

                if (parentClass.Fields == null)
                {
                    parentClass.Fields = new List <JavaField>(1);
                }
                parentClass.Fields.Add(fld);
            }
        }
Exemple #17
0
        public static void ImportFields(JavaClass jclass, TypeDefinition cilType, bool isRetainName)
        {
            if (cilType.HasFields)
            {
                int n = cilType.Fields.Count;
                if (n > 0)
                {
                    if (isRetainName)
                    {
                        throw CilMain.Where.Exception("fields not supported in a [RetainName] type");
                    }

                    jclass.Fields = new List <JavaField>(n);
                    for (int i = 0; i < n; i++)
                    {
                        var cilField = cilType.Fields[i];
                        CilMain.Where.Push($"field '{cilField.Name}'");

                        if (cilField.InitialValue.Length != 0)
                        {
                            throw CilMain.Where.Exception("unsupported InitialValue in field");
                        }

                        var myField = new JavaField();
                        myField.Name  = CilMain.MakeValidMemberName(cilField.Name);
                        myField.Class = jclass;
                        myField.Flags = AttributesToAccessFlags(
                            cilField.Attributes,
                            (cilType.HasNestedTypes || cilType.HasGenericParameters));

                        if (cilType.IsEnum)
                        {
                            myField.Type = CilType.From(cilField.FieldType);

                            if (cilField.Constant != null)
                            {
                                myField.InitConstant(cilField.Constant, CilMain.Where);
                            }
                        }
                        else
                        {
                            myField.Type = ValueUtil.GetBoxedFieldType(null, cilField);

                            if (((CilType)myField.Type).IsValueClass)
                            {
                                myField.Constant = cilField;
                            }

                            else
                            {
                                if (cilField.Constant != null)
                                {
                                    myField.InitConstant(cilField.Constant, CilMain.Where);
                                }

                                if (((CilType)myField.Type).IsVolatile)
                                {
                                    myField.Flags |= JavaAccessFlags.ACC_VOLATILE;
                                }
                            }
                        }

                        jclass.Fields.Add(myField);

                        CilMain.Where.Pop();
                    }
                }
            }
        }
Exemple #18
0
 IEnumerable <ApiComparisonReport> CompareField(JavaField rf, JavaField tf)
 {
     // return CompareProperty (nameof (rf.Deprecated), rf, tf, _ => _.Deprecated);
     return(CompareProperty(nameof(rf.Final), rf, tf, _ => _.Final));
 }
Exemple #19
0
 IEnumerable <ApiComparisonReport> CompareProperty <T> (string propertyName, JavaField rf, JavaField tf, Func <JavaField, T> getProperty)
 {
     return(CompareProperty(propertyName, rf, tf, getProperty, _ => _.Parent.FullName + "." + _.Name, ApiComparisonIssue.FieldPropertyMismatch));
 }
Exemple #20
0
        private static FieldDefinition ConvertField(AssemblyDefinition assembly, JavaClass jc, JavaField jf)
        {
            string          name       = jf.GetName(jc);
            FieldAttributes attributes = jf.GetAttributes();
            FieldDefinition result     = new FieldDefinition(name, attributes, assembly.MainModule.GetDescriptorType(jf.GetDescriptor(jc)));

            return(result);
        }
Exemple #21
0
 /// <summary>
 /// Gets the attribute of the given type.
 /// </summary>
 /// <typeparam name="T">The type of the attribute.</typeparam>
 /// <param name="jf">The java field.</param>
 /// <returns>The attribute of the given type.</returns>
 public static T GetAttribute <T>(this JavaField jf)
     where T : IJavaAttribute
 {
     Guard.NotNull(ref jf, nameof(jf));
     return(jf.GetAttributes <T>().FirstOrDefault());
 }
Exemple #22
0
        internal static void BuildJavaClass(TypeDefinition cilType, JavaClass parentClass)
        {
            CilMain.Where.Push($"class '{cilType.FullName}'");

            var genericMark = CilMain.GenericStack.Mark();
            var myType      = CilMain.GenericStack.EnterType(cilType);

            var jclass = new JavaClass();

            jclass.Name  = myType.JavaName;
            jclass.Flags = AttributesToAccessFlags(cilType.Attributes, myType.IsInterface);

            if (myType.IsInterface)
            {
                jclass.Super = JavaType.ObjectType.ClassName; // java.lang.Object
            }
            else if (cilType.BaseType != null)
            {
                var myBaseType = CilType.From(cilType.BaseType);
                jclass.Super = myBaseType.Equals(JavaType.ObjectType)
                             ? JavaType.ObjectType.ClassName // java.lang.Object
                             : myBaseType.JavaName;
            }
            else
            {
                throw CilMain.Where.Exception("missing base class");
            }

            var myInterfaces = ImportInterfaces(jclass, myType, cilType);

            int numCastableInterfaces = myType.IsGenericThisOrSuper
                                      ? InterfaceBuilder.CastableInterfaceCount(myInterfaces)
                                      : 0;

            ImportFields(jclass, cilType, myType.IsRetainName);

            ImportMethods(jclass, cilType, numCastableInterfaces);

            if (myType.JavaName == "system.Convert")
            {
                DiscardBase64MethodsInConvertClass(jclass);
            }

            ValueUtil.InitializeStaticFields(jclass, myType);

            if (myType.IsValueClass)
            {
                ValueUtil.MakeValueClass(jclass, myType, numCastableInterfaces);
            }

            else if (myType.IsEnum)
            {
                ValueUtil.MakeEnumClass(jclass, myType,
                                        cilType.HasCustomAttribute("System.FlagsAttribute", true));
            }

            else if (myType.IsDelegate)
            {
                var delegateInterface = Delegate.FixClass(jclass, myType);
                CilMain.JavaClasses.Add(delegateInterface);
            }

            // if derives directly from object, and does not implement ToString
            CodeBuilder.CreateToStringMethod(jclass);

            ResetFieldReferences(jclass);

            LinkClasses(jclass, parentClass, cilType);

            var interfaceClasses = InterfaceBuilder.BuildProxyMethods(
                myInterfaces, cilType, myType, jclass);

            if (interfaceClasses != null)
            {
                foreach (var childClass in interfaceClasses)
                {
                    CilMain.JavaClasses.Add(childClass);
                }
            }

            if (myType.HasGenericParameters)
            {
                JavaClass dataClass;

                if (!myType.IsInterface)
                {
                    dataClass = GenericUtil.MakeGenericClass(jclass, myType);
                    if (dataClass != null)
                    {
                        CilMain.JavaClasses.Add(dataClass);
                    }
                }
                else
                {
                    dataClass = null;
                }

                JavaClass infoClass = jclass;
                if (myType.IsInterface)
                {
                    // Android 'D8' desugars static methods on an interface by
                    // moving into a separate class, so we do it ourselves.
                    // see also system.RuntimeType.CreateGeneric() in baselib
                    infoClass = CilMain.CreateInnerClass(jclass, jclass.Name + "$$info",
                                                         markGenericEntity: true);
                    CilMain.JavaClasses.Add(infoClass);

                    // Android 'R8' (ProGuard) might discard this new class,
                    // so insert a dummy field with the type of the class.
                    // see also ProGuard rules in IGenericEntity in baselib
                    var infoClassField = new JavaField();
                    infoClassField.Name  = "-generic-info-class";
                    infoClassField.Type  = new JavaType(0, 0, infoClass.Name);
                    infoClassField.Class = jclass;
                    infoClassField.Flags = JavaAccessFlags.ACC_PUBLIC
                                           | JavaAccessFlags.ACC_STATIC
                                           | JavaAccessFlags.ACC_FINAL
                                           | JavaAccessFlags.ACC_SYNTHETIC;
                    if (jclass.Fields == null)
                    {
                        jclass.Fields = new List <JavaField>(1);
                    }
                    jclass.Fields.Add(infoClassField);
                }

                GenericUtil.CreateGenericInfoMethod(infoClass, dataClass, myType);

                GenericUtil.CreateGenericVarianceField(infoClass, myType, cilType);
            }

            if (myType.IsGenericThisOrSuper)
            {
                jclass.Signature = GenericUtil.MakeGenericSignature(cilType, jclass.Super);

                if (!myInterfaces.Exists(x => x.InterfaceType.JavaName == "system.IGenericObject"))
                {
                    if (!myType.IsInterface)
                    {
                        // create IGenericObject methods GetType and TryCast
                        // only if class did not already implement IGenericObject
                        if (!myType.HasGenericParameters)
                        {
                            GenericUtil.BuildGetTypeMethod(jclass, myType);
                        }

                        InterfaceBuilder.BuildTryCastMethod(
                            myInterfaces, myType, numCastableInterfaces, jclass);
                    }
                }
            }

            CilMain.GenericStack.Release(genericMark);
            CilMain.Where.Pop();
        }
Exemple #23
0
        public static void CreateSuppressibleFinalize(JavaMethod innerMethod, CilType declType,
                                                      JavaClass theClass)
        {
            //
            // if the class defines a finalizer method Finalize() then:
            //
            // - create a flag field that tracks whether finalization is suppressed
            //
            // - implement interface system.GC.FinalizeSuppressible, and its Set()
            // method, which sets the flag field
            //
            // - create a wrapper method that checks the flag field and possibly
            // invokes the original finalizer
            //
            // see also: system.GC in baselib
            //

            var flagField = new JavaField();

            flagField.Name  = "-finalize-suppressed";
            flagField.Type  = CilType.From(JavaType.BooleanType);
            flagField.Class = theClass;
            flagField.Flags = JavaAccessFlags.ACC_PRIVATE | JavaAccessFlags.ACC_VOLATILE;

            if (theClass.Fields == null)
            {
                theClass.Fields = new List <JavaField>();
            }
            theClass.Fields.Add(flagField);

            //
            // implement the interface method
            //

            var ifcMethod = new JavaMethod("system-GC$SuppressibleFinalize-Set",
                                           JavaType.VoidType);

            ifcMethod.Class = theClass;
            ifcMethod.Flags = JavaAccessFlags.ACC_PUBLIC;

            var code = ifcMethod.Code = new JavaCode();

            code.Method       = ifcMethod;
            code.Instructions = new List <JavaCode.Instruction>();
            code.MaxLocals    = code.MaxStack = 2;

            code.NewInstruction(0x19 /* aload */, null, (int)0);
            code.NewInstruction(0x12 /* ldc */, null, (int)1);
            code.NewInstruction(0xB5 /* putfield */, declType, flagField);
            code.NewInstruction(JavaType.VoidType.ReturnOpcode, null, null);

            theClass.Methods.Add(ifcMethod);
            theClass.AddInterface("system.GC$SuppressibleFinalize");

            //
            // create the wrapper method
            //

            var outerMethod = new JavaMethod(theClass, innerMethod);

            outerMethod.Flags = JavaAccessFlags.ACC_PROTECTED;
            innerMethod.Flags = JavaAccessFlags.ACC_PRIVATE;

            innerMethod.Name += "---inner";

            // prepare to generate instructions

            code              = outerMethod.Code = new JavaCode();
            code.Method       = outerMethod;
            code.Instructions = new List <JavaCode.Instruction>();
            code.StackMap     = new JavaStackMap();
            code.StackMap.SaveFrame((ushort)0, false, CilMain.Where);
            code.MaxLocals = code.MaxStack = 1;

            //
            // check the flag field to determine if suppressed
            //

            code.NewInstruction(0x19 /* aload */, null, (int)0);

            code.NewInstruction(0xB4 /* getfield */, declType, flagField);

            code.NewInstruction(0x9A /* ifne != zero */, null, (ushort)0xFFFE);

            code.NewInstruction(0x19 /* aload */, null, (int)0);

            code.NewInstruction(0xB7 /* invokespecial */, declType, innerMethod);

            code.NewInstruction(JavaType.VoidType.ReturnOpcode, null, null,
                                /* label */ 0xFFFE);

            code.StackMap.SaveFrame((ushort)0xFFFE, true, CilMain.Where);

            theClass.Methods.Add(outerMethod);
        }
 public void clearFields()
 {
     JavaField.Clear();
     RubyField.Clear();
     PythonField.Clear();
 }