Ejemplo n.º 1
0
        public FieldOrMethod AddField(Modifiers access, string name, string signature, object constantValue)
        {
            FieldOrMethod field = new FieldOrMethod(access, AddUtf8(name), AddUtf8(signature));

            if (constantValue != null)
            {
                ushort constantValueIndex;
                if (constantValue is byte)
                {
                    constantValueIndex = AddInt((sbyte)(byte)constantValue);
                }
                else if (constantValue is bool)
                {
                    constantValueIndex = AddInt((bool)constantValue ? 1 : 0);
                }
                else if (constantValue is short)
                {
                    constantValueIndex = AddInt((short)constantValue);
                }
                else if (constantValue is char)
                {
                    constantValueIndex = AddInt((char)constantValue);
                }
                else if (constantValue is int)
                {
                    constantValueIndex = AddInt((int)constantValue);
                }
                else if (constantValue is long)
                {
                    constantValueIndex = AddLong((long)constantValue);
                }
                else if (constantValue is float)
                {
                    constantValueIndex = AddFloat((float)constantValue);
                }
                else if (constantValue is double)
                {
                    constantValueIndex = AddDouble((double)constantValue);
                }
                else if (constantValue is string)
                {
                    constantValueIndex = AddString((string)constantValue);
                }
                else
                {
                    throw new InvalidOperationException(constantValue.GetType().FullName);
                }
                field.AddAttribute(new ConstantValueAttribute(AddUtf8("ConstantValue"), constantValueIndex));
            }
            fields.Add(field);
            return(field);
        }
Ejemplo n.º 2
0
        private static void AddParameterAnnotations(ClassFileWriter writer, FieldOrMethod target, MethodBase source)
        {
#if !FIRST_PASS && !STUB_GENERATOR
#if !WINRT
            if (source != null)
            {
                RuntimeVisibleParameterAnnotationsAttribute attr = null;
                ParameterInfo[] parameters = source.GetParameters();
                for (int i = 0; i < parameters.Length; i++)
                {
                    RuntimeVisibleAnnotationsAttribute param = null;
                    foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(parameters[i]))
                    {
                        object[] ann = GetAnnotation(cad);
                        if (ann != null)
                        {
                            if (param == null)
                            {
                                if (attr == null)
                                {
                                    attr = new RuntimeVisibleParameterAnnotationsAttribute(writer);
                                    for (int j = 0; j < i; j++)
                                    {
                                        attr.Add(new RuntimeVisibleAnnotationsAttribute(writer));
                                    }
                                }
                                param = new RuntimeVisibleAnnotationsAttribute(writer);
                            }
                            param.Add(ann);
                        }
                    }
                    if (attr != null)
                    {
                        attr.Add(param ?? new RuntimeVisibleAnnotationsAttribute(writer));
                    }
                }
                if (attr != null)
                {
                    target.AddAttribute(attr);
                }
            }
#else
            throw new NotImplementedException();
#endif
#endif
        }
Ejemplo n.º 3
0
        private static void AddParameterAnnotations(ClassFileWriter writer, FieldOrMethod target, MethodBase source)
        {
#if !FIRST_PASS && !STUB_GENERATOR
            if (source != null)
            {
                RuntimeVisibleParameterAnnotationsAttribute attr = null;
                ParameterInfo[] parameters = source.GetParameters();
                for (int i = 0; i < parameters.Length; i++)
                {
                    RuntimeVisibleAnnotationsAttribute param = null;
                    foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(parameters[i]))
                    {
                        object[] ann = GetAnnotation(cad);
                        if (ann != null)
                        {
                            if (param == null)
                            {
                                if (attr == null)
                                {
                                    attr = new RuntimeVisibleParameterAnnotationsAttribute(writer);
                                    for (int j = 0; j < i; j++)
                                    {
                                        attr.Add(new RuntimeVisibleAnnotationsAttribute(writer));
                                    }
                                }
                                param = new RuntimeVisibleAnnotationsAttribute(writer);
                            }
                            param.Add(UnpackArray((IList <CustomAttributeTypedArgument>)cad.ConstructorArguments[0].Value));
                        }
                    }
                    if (attr != null)
                    {
                        attr.Add(param ?? new RuntimeVisibleAnnotationsAttribute(writer));
                    }
                }
                if (attr != null)
                {
                    target.AddAttribute(attr);
                }
            }
#endif
        }
Ejemplo n.º 4
0
    private static void WriteClass(TypeWrapper tw)
    {
        string name  = tw.Name.Replace('.', '/');
        string super = null;

        if (tw.IsInterface)
        {
            super = "java/lang/Object";
        }
        else if (tw.BaseTypeWrapper != null)
        {
            super = tw.BaseTypeWrapper.Name.Replace('.', '/');
        }
        IKVM.StubGen.ClassFileWriter writer = new IKVM.StubGen.ClassFileWriter(tw.Modifiers, name, super, 0, 49);
        foreach (TypeWrapper iface in tw.Interfaces)
        {
            if (iface.IsPublic)
            {
                writer.AddInterface(iface.Name.Replace('.', '/'));
            }
        }
        IKVM.StubGen.InnerClassesAttribute innerClassesAttribute = null;
        if (tw.DeclaringTypeWrapper != null)
        {
            TypeWrapper outer     = tw.DeclaringTypeWrapper;
            string      innername = name;
            int         idx       = name.LastIndexOf('$');
            if (idx >= 0)
            {
                innername = innername.Substring(idx + 1);
            }
            innerClassesAttribute = new IKVM.StubGen.InnerClassesAttribute(writer);
            innerClassesAttribute.Add(name, outer.Name.Replace('.', '/'), innername, (ushort)tw.ReflectiveModifiers);
        }
        foreach (TypeWrapper inner in tw.InnerClasses)
        {
            if (inner.IsPublic)
            {
                if (innerClassesAttribute == null)
                {
                    innerClassesAttribute = new IKVM.StubGen.InnerClassesAttribute(writer);
                }
                string namePart = inner.Name;
                namePart = namePart.Substring(namePart.LastIndexOf('$') + 1);
                innerClassesAttribute.Add(inner.Name.Replace('.', '/'), name, namePart, (ushort)inner.ReflectiveModifiers);
            }
        }
        if (innerClassesAttribute != null)
        {
            writer.AddAttribute(innerClassesAttribute);
        }
        string genericTypeSignature = tw.GetGenericSignature();

        if (genericTypeSignature != null)
        {
            writer.AddStringAttribute("Signature", genericTypeSignature);
        }
        writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw));
        if (tw.TypeAsBaseType.IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false))
        {
            writer.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
        }
        foreach (MethodWrapper mw in tw.GetMethods())
        {
            if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected))
            {
                IKVM.StubGen.FieldOrMethod m;
                if (mw.Name == "<init>")
                {
                    m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/'));
                    IKVM.StubGen.CodeAttribute code = new IKVM.StubGen.CodeAttribute(writer);
                    code.MaxLocals = (ushort)(mw.GetParameters().Length * 2 + 1);
                    code.MaxStack  = 3;
                    ushort index1 = writer.AddClass("java/lang/UnsatisfiedLinkError");
                    ushort index2 = writer.AddString("ikvmstub generated stubs can only be used on IKVM.NET");
                    ushort index3 = writer.AddMethodRef("java/lang/UnsatisfiedLinkError", "<init>", "(Ljava/lang/String;)V");
                    code.ByteCode = new byte[] {
                        187, (byte)(index1 >> 8), (byte)index1,                         // new java/lang/UnsatisfiedLinkError
                        89,                                                             // dup
                        19, (byte)(index2 >> 8), (byte)index2,                          // ldc_w "..."
                        183, (byte)(index3 >> 8), (byte)index3,                         // invokespecial java/lang/UnsatisfiedLinkError/init()V
                        191                                                             // athrow
                    };
                    m.AddAttribute(code);
                }
                else
                {
                    m = writer.AddMethod(mw.Modifiers | Modifiers.Native, mw.Name, mw.Signature.Replace('.', '/'));
                    if (mw.IsOptionalAttributeAnnotationValue)
                    {
                        m.AddAttribute(new IKVM.StubGen.AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, mw.ReturnType)));
                    }
                }
                MethodBase mb = mw.GetMethod();
                if (mb != null)
                {
                    ThrowsAttribute throws = AttributeHelper.GetThrows(mb);
                    if (throws != null)
                    {
                        IKVM.StubGen.ExceptionsAttribute attrib = new IKVM.StubGen.ExceptionsAttribute(writer);
                        if (throws.classes != null)
                        {
                            foreach (string ex in throws.classes)
                            {
                                attrib.Add(ex.Replace('.', '/'));
                            }
                        }
                        if (throws.types != null)
                        {
                            foreach (Type ex in throws.types)
                            {
                                attrib.Add(ex.FullName.Replace('.', '/'));
                            }
                        }
                        m.AddAttribute(attrib);
                    }
                    if (mb.IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false))
                    {
                        m.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
                    }
                }
                string sig = tw.GetGenericMethodSignature(mw);
                if (sig != null)
                {
                    m.AddAttribute(writer.MakeStringAttribute("Signature", sig));
                }
            }
        }
        bool hasSerialVersionUID = false;

        foreach (FieldWrapper fw in tw.GetFields())
        {
            if (!fw.IsHideFromReflection)
            {
                bool isSerialVersionUID = includeSerialVersionUID && fw.Name == "serialVersionUID" && fw.FieldTypeWrapper == PrimitiveTypeWrapper.LONG;
                hasSerialVersionUID |= isSerialVersionUID;
                if (fw.IsPublic || fw.IsProtected || isSerialVersionUID)
                {
                    object constant = null;
                    if (fw.GetField() != null && fw.GetField().IsLiteral&& (fw.FieldTypeWrapper.IsPrimitive || fw.FieldTypeWrapper == CoreClasses.java.lang.String.Wrapper))
                    {
                        constant = fw.GetField().GetRawConstantValue();
                        if (fw.GetField().FieldType.IsEnum)
                        {
                            constant = EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(fw.GetField().FieldType), constant);
                        }
                    }
                    IKVM.StubGen.FieldOrMethod f = writer.AddField(fw.Modifiers, fw.Name, fw.Signature.Replace('.', '/'), constant);
                    string sig = tw.GetGenericFieldSignature(fw);
                    if (sig != null)
                    {
                        f.AddAttribute(writer.MakeStringAttribute("Signature", sig));
                    }
                    if (fw.GetField() != null && fw.GetField().IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false))
                    {
                        f.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
                    }
                }
            }
        }
        if (includeSerialVersionUID && !hasSerialVersionUID && IsSerializable(tw))
        {
            // class is serializable but doesn't have an explicit serialVersionUID, so we add the field to record
            // the serialVersionUID as we see it (mainly to make the Japi reports more realistic)
            writer.AddField(Modifiers.Private | Modifiers.Static | Modifiers.Final, "serialVersionUID", "J", IKVM.StubGen.SerialVersionUID.Compute(tw));
        }
        AddMetaAnnotations(writer, tw);
        zipCount++;
        zipFile.PutNextEntry(new ZipEntry(name + ".class"));
        writer.Write(zipFile);
    }
Ejemplo n.º 5
0
 private static void AddParameterAnnotations(ClassFileWriter writer, FieldOrMethod target, MethodBase source)
 {
     #if !FIRST_PASS && !STUB_GENERATOR
     if (source != null)
     {
         RuntimeVisibleParameterAnnotationsAttribute attr = null;
         ParameterInfo[] parameters = source.GetParameters();
         for (int i = 0; i < parameters.Length; i++)
         {
             RuntimeVisibleAnnotationsAttribute param = null;
             foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(parameters[i]))
             {
                 object[] ann = GetAnnotation(cad);
                 if (ann != null)
                 {
                     if (param == null)
                     {
                         if (attr == null)
                         {
                             attr = new RuntimeVisibleParameterAnnotationsAttribute(writer);
                             for (int j = 0; j < i; j++)
                             {
                                 attr.Add(new RuntimeVisibleAnnotationsAttribute(writer));
                             }
                         }
                         param = new RuntimeVisibleAnnotationsAttribute(writer);
                     }
                     param.Add(ann);
                 }
             }
             if (attr != null)
             {
                 attr.Add(param ?? new RuntimeVisibleAnnotationsAttribute(writer));
             }
         }
         if (attr != null)
         {
             target.AddAttribute(attr);
         }
     }
     #endif
 }
Ejemplo n.º 6
0
 public FieldOrMethod AddField(Modifiers access, string name, string signature, object constantValue)
 {
     FieldOrMethod field = new FieldOrMethod(access, AddUtf8(name), AddUtf8(signature));
     if (constantValue != null)
     {
         ushort constantValueIndex;
         if (constantValue is byte)
         {
             constantValueIndex = AddInt((sbyte)(byte)constantValue);
         }
         else if (constantValue is bool)
         {
             constantValueIndex = AddInt((bool)constantValue ? 1 : 0);
         }
         else if (constantValue is short)
         {
             constantValueIndex = AddInt((short)constantValue);
         }
         else if (constantValue is char)
         {
             constantValueIndex = AddInt((char)constantValue);
         }
         else if (constantValue is int)
         {
             constantValueIndex = AddInt((int)constantValue);
         }
         else if (constantValue is long)
         {
             constantValueIndex = AddLong((long)constantValue);
         }
         else if (constantValue is float)
         {
             constantValueIndex = AddFloat((float)constantValue);
         }
         else if (constantValue is double)
         {
             constantValueIndex = AddDouble((double)constantValue);
         }
         else if (constantValue is string)
         {
             constantValueIndex = AddString((string)constantValue);
         }
         else
         {
             throw new InvalidOperationException(constantValue.GetType().FullName);
         }
         field.AddAttribute(new ConstantValueAttribute(AddUtf8("ConstantValue"), constantValueIndex));
     }
     fields.Add(field);
     return field;
 }
Ejemplo n.º 7
0
        internal static void WriteClass(Stream stream, TypeWrapper tw, bool includeNonPublicInterfaces, bool includeNonPublicMembers, bool includeSerialVersionUID)
        {
            string name  = tw.Name.Replace('.', '/');
            string super = null;

            if (tw.IsInterface)
            {
                super = "java/lang/Object";
            }
            else if (tw.BaseTypeWrapper != null)
            {
                super = tw.BaseTypeWrapper.Name.Replace('.', '/');
            }
            ClassFileWriter writer = new ClassFileWriter(tw.Modifiers, name, super, 0, 49);

            foreach (TypeWrapper iface in tw.Interfaces)
            {
                if (iface.IsPublic || includeNonPublicInterfaces)
                {
                    writer.AddInterface(iface.Name.Replace('.', '/'));
                }
            }
            InnerClassesAttribute innerClassesAttribute = null;

            if (tw.DeclaringTypeWrapper != null)
            {
                TypeWrapper outer     = tw.DeclaringTypeWrapper;
                string      innername = name;
                int         idx       = name.LastIndexOf('$');
                if (idx >= 0)
                {
                    innername = innername.Substring(idx + 1);
                }
                innerClassesAttribute = new InnerClassesAttribute(writer);
                innerClassesAttribute.Add(name, outer.Name.Replace('.', '/'), innername, (ushort)tw.ReflectiveModifiers);
            }
            foreach (TypeWrapper inner in tw.InnerClasses)
            {
                if (inner.IsPublic)
                {
                    if (innerClassesAttribute == null)
                    {
                        innerClassesAttribute = new InnerClassesAttribute(writer);
                    }
                    string namePart = inner.Name;
                    namePart = namePart.Substring(namePart.LastIndexOf('$') + 1);
                    innerClassesAttribute.Add(inner.Name.Replace('.', '/'), name, namePart, (ushort)inner.ReflectiveModifiers);
                }
            }
            if (innerClassesAttribute != null)
            {
                writer.AddAttribute(innerClassesAttribute);
            }
            string genericTypeSignature = tw.GetGenericSignature();

            if (genericTypeSignature != null)
            {
                writer.AddStringAttribute("Signature", genericTypeSignature);
            }
            AddAnnotations(writer, writer, tw.TypeAsBaseType);
            writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw));
            if (tw.TypeAsBaseType.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false))
            {
                writer.AddAttribute(new DeprecatedAttribute(writer));
            }
            foreach (MethodWrapper mw in tw.GetMethods())
            {
                if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected || includeNonPublicMembers))
                {
                    FieldOrMethod m;
                    if (mw.Name == "<init>")
                    {
                        m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/'));
                        CodeAttribute code = new CodeAttribute(writer);
                        code.MaxLocals = (ushort)(mw.GetParameters().Length * 2 + 1);
                        code.MaxStack  = 3;
                        ushort index1 = writer.AddClass("java/lang/UnsatisfiedLinkError");
                        ushort index2 = writer.AddString("ikvmstub generated stubs can only be used on IKVM.NET");
                        ushort index3 = writer.AddMethodRef("java/lang/UnsatisfiedLinkError", "<init>", "(Ljava/lang/String;)V");
                        code.ByteCode = new byte[] {
                            187, (byte)(index1 >> 8), (byte)index1,                     // new java/lang/UnsatisfiedLinkError
                            89,                                                         // dup
                            19, (byte)(index2 >> 8), (byte)index2,                      // ldc_w "..."
                            183, (byte)(index3 >> 8), (byte)index3,                     // invokespecial java/lang/UnsatisfiedLinkError/init()V
                            191                                                         // athrow
                        };
                        m.AddAttribute(code);
                    }
                    else
                    {
                        Modifiers mods = mw.Modifiers;
                        if ((mods & Modifiers.Abstract) == 0)
                        {
                            mods |= Modifiers.Native;
                        }
                        m = writer.AddMethod(mods, mw.Name, mw.Signature.Replace('.', '/'));
                        if (mw.IsOptionalAttributeAnnotationValue)
                        {
                            m.AddAttribute(new AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, mw.ReturnType)));
                        }
                    }
                    MethodBase mb = mw.GetMethod();
                    if (mb != null)
                    {
                        ThrowsAttribute throws = AttributeHelper.GetThrows(mb);
                        if (throws == null)
                        {
                            string[] throwsArray = mw.GetDeclaredExceptions();
                            if (throwsArray != null && throwsArray.Length > 0)
                            {
                                ExceptionsAttribute attrib = new ExceptionsAttribute(writer);
                                foreach (string ex in throwsArray)
                                {
                                    attrib.Add(ex.Replace('.', '/'));
                                }
                                m.AddAttribute(attrib);
                            }
                        }
                        else
                        {
                            ExceptionsAttribute attrib = new ExceptionsAttribute(writer);
                            if (throws.classes != null)
                            {
                                foreach (string ex in throws.classes)
                                {
                                    attrib.Add(ex.Replace('.', '/'));
                                }
                            }
                            if (throws.types != null)
                            {
                                foreach (Type ex in throws.types)
                                {
                                    attrib.Add(ClassLoaderWrapper.GetWrapperFromType(ex).Name.Replace('.', '/'));
                                }
                            }
                            m.AddAttribute(attrib);
                        }
                        if (mb.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false)
                            // HACK the instancehelper methods are marked as Obsolete (to direct people toward the ikvm.extensions methods instead)
                            // but in the Java world most of them are not deprecated (and to keep the Japi results clean we need to reflect this)
                            && (!mb.Name.StartsWith("instancehelper_") ||
                                mb.DeclaringType.FullName != "java.lang.String"
                                // the Java deprecated methods actually have two Obsolete attributes
                                || GetObsoleteCount(mb) == 2))
                        {
                            m.AddAttribute(new DeprecatedAttribute(writer));
                        }
                        CustomAttributeData attr = GetAnnotationDefault(mb);
                        if (attr != null)
                        {
                            m.AddAttribute(new AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, attr.ConstructorArguments[0])));
                        }
                    }
                    string sig = tw.GetGenericMethodSignature(mw);
                    if (sig != null)
                    {
                        m.AddAttribute(writer.MakeStringAttribute("Signature", sig));
                    }
                    AddAnnotations(writer, m, mw.GetMethod());
                    AddParameterAnnotations(writer, m, mw.GetMethod());
                }
            }
            bool hasSerialVersionUID = false;

            foreach (FieldWrapper fw in tw.GetFields())
            {
                if (!fw.IsHideFromReflection)
                {
                    bool isSerialVersionUID = includeSerialVersionUID && fw.Name == "serialVersionUID" && fw.FieldTypeWrapper == PrimitiveTypeWrapper.LONG;
                    hasSerialVersionUID |= isSerialVersionUID;
                    if (fw.IsPublic || fw.IsProtected || isSerialVersionUID || includeNonPublicMembers)
                    {
                        object constant = null;
                        if (fw.GetField() != null && fw.GetField().IsLiteral&& (fw.FieldTypeWrapper.IsPrimitive || fw.FieldTypeWrapper == CoreClasses.java.lang.String.Wrapper))
                        {
                            constant = fw.GetField().GetRawConstantValue();
                            if (fw.GetField().FieldType.IsEnum)
                            {
                                constant = EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(fw.GetField().FieldType), constant);
                            }
                        }
                        FieldOrMethod f   = writer.AddField(fw.Modifiers, fw.Name, fw.Signature.Replace('.', '/'), constant);
                        string        sig = tw.GetGenericFieldSignature(fw);
                        if (sig != null)
                        {
                            f.AddAttribute(writer.MakeStringAttribute("Signature", sig));
                        }
                        if (fw.GetField() != null && fw.GetField().IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false))
                        {
                            f.AddAttribute(new DeprecatedAttribute(writer));
                        }
                        AddAnnotations(writer, f, fw.GetField());
                    }
                }
            }
            if (includeSerialVersionUID && !hasSerialVersionUID && IsSerializable(tw))
            {
                // class is serializable but doesn't have an explicit serialVersionUID, so we add the field to record
                // the serialVersionUID as we see it (mainly to make the Japi reports more realistic)
                writer.AddField(Modifiers.Private | Modifiers.Static | Modifiers.Final, "serialVersionUID", "J", SerialVersionUID.Compute(tw));
            }
            AddMetaAnnotations(writer, tw);
            writer.Write(stream);
        }