public FieldOrMethod AddMethod(Modifiers access, string name, string signature) { FieldOrMethod method = new FieldOrMethod(access, AddUtf8(name), AddUtf8(signature)); methods.Add(method); return(method); }
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); }
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 }
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 }
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); }
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 }
public FieldOrMethod AddMethod(Modifiers access, string name, string signature) { FieldOrMethod method = new FieldOrMethod(access, AddUtf8(name), AddUtf8(signature)); methods.Add(method); return method; }
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; }
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); }