Beispiel #1
0
        /// <summary>
        /// Create wrapper for given jar file
        /// </summary>
        private void CreateAssembly(JarFile jf, string folder)
        {
            // Create java type wrappers
            var module = new NetModule(jf.Scope);

            var classTypeBuilders = jf.ClassNames.SelectMany(n => StandardTypeBuilder.Create(jf.LoadClass(n), target));

            var typeBuilders = classTypeBuilders.OrderBy(x => x.Priority).ToList();

            typeBuilders.ForEach(x => x.CreateType(null, module, target));

            // Implement and finalize types
            Implement(typeBuilders, target);

            var assemblyAttributes = new List <NetCustomAttribute>();

            if (!importAsStubs)
            {
                // Import code
                var attrType = new NetTypeDefinition(ClassFile.Empty, target, AttributeConstants.Dot42Scope)
                {
                    Name      = AttributeConstants.JavaCodeAttributeName,
                    Namespace = AttributeConstants.Dot42AttributeNamespace
                };
                string hash = JarReferenceHash.ComputeJarReferenceHash(jarFilePath);
                var    attr = new NetCustomAttribute(attrType, hash, Path.GetFileName(jarFilePath));
                assemblyAttributes.Add(attr);
            }

            // Save
            CodeGenerator.Generate(folder, module.Types, assemblyAttributes, target, this, target);
        }
        /// <summary>
        /// Convert the given IL custom attribute to a NetCustomAttribute.
        /// </summary>
        private static NetCustomAttribute BuildCustomAttribute(CustomAttribute attr)
        {
            var ca = new NetCustomAttribute(null, attr.ConstructorArguments.Select(x => x.Value).ToArray());

            foreach (var pv in attr.Properties)
            {
                ca.Properties.Add(pv.Name, pv.Argument.Value);
            }
            return(ca);
        }
Beispiel #3
0
        /// <summary>
        /// Create the DexImport that will be attached to the type.
        /// </summary>
        protected virtual NetCustomAttribute CreateDexImportAttribute(ClassFile cf)
        {
            var ca = new NetCustomAttribute(null, cf.ClassName);

            ca.Properties.Add(AttributeConstants.DexImportAttributeAccessFlagsName, (int)cf.AccessFlags);
            var signature = (cf.Signature != null) ? cf.Signature.Original : null;

            if ((signature != null) && (signature != cf.ClassName))
            {
                ca.Properties.Add(AttributeConstants.DexImportAttributeSignature, signature);
            }
            return(ca);
        }
Beispiel #4
0
        /// <summary>
        /// Finalize all references now that all types have been created
        /// </summary>
        public void Complete(ClassFile declaringClass, TargetFramework target)
        {
            if (field == null)
            {
                return;
            }

            // Setup field value
            var cValue = javaField.ConstantValue;

            // Fixup value
            if (cValue != null)
            {
                if (field.FieldType.IsSingle() && (float.IsPositiveInfinity((float)cValue) || float.IsNegativeInfinity((float)cValue)))
                {
                    cValue = null;
                }
                if (field.FieldType.IsDouble() && (double.IsPositiveInfinity((double)cValue) || double.IsNegativeInfinity((double)cValue)))
                {
                    cValue = null;
                }
            }

            if (cValue != null)
            {
                field.DefaultValue = cValue;
            }
            else if (field.DeclaringType.IsEnum)
            {
                /*field.DefaultValue = field.DeclaringType.Fields.ToList().IndexOf(field);
                 * field.Attributes |= FieldAttributes.Literal | FieldAttributes.Static;
                 * field.Attributes &= ~FieldAttributes.InitOnly;*/
                field.Attributes |= FieldAttributes.InitOnly | FieldAttributes.Static;
                field.Attributes &= ~FieldAttributes.Literal;
            }
            else
            {
                field.Attributes &= ~FieldAttributes.Literal;
            }

            // Add DexImport attribute
            var ca = new NetCustomAttribute(null, javaField.Name, javaField.Descriptor);

            ca.Properties.Add(AttributeConstants.DexImportAttributeAccessFlagsName, (int)javaField.AccessFlags);
            field.CustomAttributes.Add(ca);
        }
Beispiel #5
0
        /// <summary>
        /// Finalize all references now that all types have been created
        /// </summary>
        public void Complete(ClassFile declaringClass, TargetFramework target)
        {
            if (method == null)
            {
                return;
            }

            // Add DexImport attribute
            var ca = new NetCustomAttribute(null, javaMethod.Name, javaMethod.Descriptor);

            ca.Properties.Add(AttributeConstants.DexImportAttributeAccessFlagsName, (int)javaMethod.AccessFlags);
            if (method.HasUnsignedPartner)
            {
                ca.Properties.Add(AttributeConstants.DexImportAttributeIgnoreFromJavaName, true);
            }
            var signature = (javaMethod.Signature != null) ? javaMethod.Signature.Original : null;

            if ((signature != null) && (signature != javaMethod.Descriptor))
            {
                ca.Properties.Add(AttributeConstants.DexImportAttributeSignature, signature);
            }
            method.CustomAttributes.Add(ca);
        }
Beispiel #6
0
        /// <summary>
        /// Add abstract method (that do not yet exist) for all interface methods.
        /// </summary>
        private void AddAbstractInterfaceMethods(NetTypeDefinition typeDef, TargetFramework target)
        {
            if ((typeDef.IsInterface) || (this is IInterfaceConstantsTypeBuilder))
            {
                return;
            }

            var typeMethods = typeDef.Methods.ToList();

            foreach (var iterator in typeDef.Interfaces)
            {
                // Collect all interface methods
                var iDef     = iterator;
                var iMethods = iDef.GetElementType().Methods.Select(x => Tuple.Create(iDef, x)).ToList();
                iMethods.AddRange(iDef.GetElementType().GetBaseTypes(true).Where(x => x.GetElementType().IsInterface).SelectMany(x => x.GetElementType().Methods.Select(m => Tuple.Create(x, m))));
                foreach (var pair in iMethods)
                {
                    var iMethod = pair.Item2;
                    if (typeMethods.Any(x => x.IsExactDuplicate(iMethod)))
                    {
                        continue;
                    }

                    // Add abstract method
                    var method = new NetMethodDefinition(iMethod.Name, null, typeDef, target, iMethod.SignConvertMode, "TypeBuilder.AddAbstractInterfaceMethods");
                    method.AccessFlags = iMethod.AccessFlags;
                    method.Attributes  = iMethod.Attributes;
                    method.IsAbstract  = false;
                    method.IsVirtual   = !typeDef.IsSealed;
                    method.GenericParameters.AddRange(iMethod.GenericParameters.Select(x => new NetGenericParameter(GetMethodGenericParameterName(typeDef, x.Name), x.Name, method)));
                    method.ReturnType = GenericParameters.Resolve(iMethod.ReturnType, typeDef, target.TypeNameMap);
                    method.Parameters.AddRange(iMethod.Parameters.Select(x => new NetParameterDefinition(x.Name, GenericParameters.Resolve(x.ParameterType, typeDef, target.TypeNameMap), x.IsParams)));

                    // Check if there are duplicates now that the generic parameters are resolved.
                    if (typeMethods.Any(x => x.IsExactDuplicate(method)))
                    {
                        continue;
                    }

                    // Should we ignore this one?
                    if (IgnoreInterfaceMethod(method, iMethod))
                    {
                        continue;
                    }

                    // Test if the method is a duplicate of an existing method, but with different return type
                    var differentAccessMask = !method.HasSameVisibility(iMethod);
                    if (differentAccessMask || typeMethods.Any(x => x.IsDuplicate(method)) ||
                        ImplementAsExplicitInterfaceMethod(method, iMethod) || typeDef.NestedTypes.Any(x => x.Name == method.Name))
                    {
                        // Method with different return type exists.
                        // Make it an explicit interface method
                        method.SetExplicitImplementation(iMethod, pair.Item1);
                        method.IsAbstract = false;
                        method.IsVirtual  = false;
                    }
                    else
                    {
                        // Check for override
                        //method.IsOverride = isOverride;
                        if (method.IsOverride && method.Overrides.All(x => !x.IsVirtual))
                        {
                            // No need to override anything
                            continue;
                        }
                    }

                    // Create DexImport attribute
                    var typeCa   = iMethod.DeclaringType.CustomAttributes.First(x => x.AttributeType == null);
                    var methodCa = iMethod.CustomAttributes.First(x => x.AttributeType == null);
                    var ca       = new NetCustomAttribute(null, typeCa.ConstructorArguments[0], methodCa.ConstructorArguments[0], methodCa.ConstructorArguments[1]);
                    ca.CopyPropertiesFrom(methodCa);
                    method.CustomAttributes.Add(ca);

                    typeDef.Methods.Add(method);
                    typeMethods.Add(method);

                    // Avoid name conflicts
                    var nested = typeDef.NestedTypes.FirstOrDefault(x => x.Name == method.Name);
                    if (nested != null)
                    {
                        nested.Name = "Java" + nested.Name;
                    }
                }
            }
        }