зеркало из https://github.com/mono/ikvm-fork.git
Added ikvmstub -parameters option to add parameter names to stub classes.
This commit is contained in:
Родитель
5befcded8a
Коммит
3c0a730167
|
@ -40,6 +40,7 @@ static class NetExp
|
|||
private static bool includeSerialVersionUID;
|
||||
private static bool includeNonPublicInterfaces;
|
||||
private static bool includeNonPublicMembers;
|
||||
private static bool includeParameterNames;
|
||||
private static List<string> namespaces = new List<string>();
|
||||
|
||||
static int Main(string[] args)
|
||||
|
@ -106,6 +107,10 @@ static class NetExp
|
|||
{
|
||||
forwarders = true;
|
||||
}
|
||||
else if(s == "-parameters")
|
||||
{
|
||||
includeParameterNames = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unrecognized option, or multiple assemblies, print usage message and exit
|
||||
|
@ -134,6 +139,7 @@ static class NetExp
|
|||
Console.Error.WriteLine(" -lib:<dir> Additional directories to search for references");
|
||||
Console.Error.WriteLine(" -namespace:<ns> Only include types from specified namespace");
|
||||
Console.Error.WriteLine(" -forwarders Export forwarded types too");
|
||||
Console.Error.WriteLine(" -parameters Emit Java 8 classes with parameter names");
|
||||
return 1;
|
||||
}
|
||||
if(File.Exists(assemblyNameOrPath) && nostdlib)
|
||||
|
@ -323,7 +329,7 @@ static class NetExp
|
|||
{
|
||||
zipCount++;
|
||||
MemoryStream mem = new MemoryStream();
|
||||
IKVM.StubGen.StubGenerator.WriteClass(mem, tw, includeNonPublicInterfaces, includeNonPublicMembers, includeSerialVersionUID);
|
||||
IKVM.StubGen.StubGenerator.WriteClass(mem, tw, includeNonPublicInterfaces, includeNonPublicMembers, includeSerialVersionUID, includeParameterNames);
|
||||
ZipEntry entry = new ZipEntry(tw.Name.Replace('.', '/') + ".class");
|
||||
entry.Size = mem.Position;
|
||||
zipFile.PutNextEntry(entry);
|
||||
|
@ -387,6 +393,7 @@ static class NetExp
|
|||
try
|
||||
{
|
||||
ProcessClass(c);
|
||||
WriteClass(c);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
@ -400,7 +407,6 @@ static class NetExp
|
|||
throw;
|
||||
}
|
||||
}
|
||||
WriteClass(c);
|
||||
}
|
||||
}
|
||||
} while(keepGoing);
|
||||
|
@ -497,7 +503,7 @@ static class Intrinsics
|
|||
|
||||
static class StaticCompiler
|
||||
{
|
||||
internal static readonly Universe Universe = new Universe();
|
||||
internal static readonly Universe Universe = new Universe(UniverseOptions.EnableFunctionPointers);
|
||||
internal static readonly AssemblyResolver Resolver = new AssemblyResolver();
|
||||
internal static Assembly runtimeAssembly;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace IKVM.NativeCode.gnu.java.net.protocol.ikvmres
|
|||
MemoryStream mem = new MemoryStream();
|
||||
#if !FIRST_PASS
|
||||
bool includeNonPublicInterfaces = !"true".Equals(global::java.lang.Props.props.getProperty("ikvm.stubgen.skipNonPublicInterfaces"), StringComparison.OrdinalIgnoreCase);
|
||||
IKVM.StubGen.StubGenerator.WriteClass(mem, TypeWrapper.FromClass(c), includeNonPublicInterfaces, false, false);
|
||||
IKVM.StubGen.StubGenerator.WriteClass(mem, TypeWrapper.FromClass(c), includeNonPublicInterfaces, false, false, false);
|
||||
#endif
|
||||
return mem.ToArray();
|
||||
}
|
||||
|
@ -117,11 +117,7 @@ namespace IKVM.NativeCode.java.lang
|
|||
|
||||
public static string getBootClassPath()
|
||||
{
|
||||
#if FIRST_PASS
|
||||
return null;
|
||||
#else
|
||||
return VirtualFileSystem.GetAssemblyClassesPath(JVM.CoreAssembly);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,60 +142,15 @@ namespace IKVM.NativeCode.ikvm.@internal
|
|||
}
|
||||
}
|
||||
|
||||
namespace stubgen
|
||||
static class AnnotationAttributeBase
|
||||
{
|
||||
static class StubGenerator
|
||||
public static object newAnnotationInvocationHandler(jlClass type, object memberValues)
|
||||
{
|
||||
public static int getRealModifiers(jlClass c)
|
||||
{
|
||||
return (int)TypeWrapper.FromClass(c).Modifiers;
|
||||
}
|
||||
|
||||
public static string getAssemblyName(jlClass c)
|
||||
{
|
||||
TypeWrapper wrapper = TypeWrapper.FromClass(c);
|
||||
ClassLoaderWrapper loader = wrapper.GetClassLoader();
|
||||
IKVM.Internal.AssemblyClassLoader acl = loader as IKVM.Internal.AssemblyClassLoader;
|
||||
if(acl != null)
|
||||
{
|
||||
return acl.GetAssembly(wrapper).FullName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((GenericClassLoaderWrapper)loader).GetName();
|
||||
}
|
||||
}
|
||||
|
||||
public static object getFieldConstantValue(object field)
|
||||
{
|
||||
return FieldWrapper.FromField(field).GetConstant();
|
||||
}
|
||||
|
||||
public static bool isFieldDeprecated(object field)
|
||||
{
|
||||
FieldWrapper fieldWrapper = FieldWrapper.FromField(field);
|
||||
FieldInfo fi = fieldWrapper.GetField();
|
||||
if(fi != null)
|
||||
{
|
||||
return fi.IsDefined(typeof(ObsoleteAttribute), false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool isMethodDeprecated(object method)
|
||||
{
|
||||
MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(method);
|
||||
MethodBase mb = mw.GetMethod();
|
||||
return mb != null && mb.IsDefined(typeof(ObsoleteAttribute), false);
|
||||
}
|
||||
|
||||
public static bool isClassDeprecated(jlClass clazz)
|
||||
{
|
||||
Type type = TypeWrapper.FromClass(clazz).TypeAsTBD;
|
||||
// we need to check type for null, because ReflectionOnly
|
||||
// generated delegate inner interfaces don't really exist
|
||||
return type != null && type.IsDefined(typeof(ObsoleteAttribute), false);
|
||||
}
|
||||
#if FIRST_PASS
|
||||
return null;
|
||||
#else
|
||||
return new global::sun.reflect.annotation.AnnotationInvocationHandler(type, (global::java.util.Map)memberValues);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +179,9 @@ namespace IKVM.NativeCode.ikvm.runtime
|
|||
TypeWrapper tw = wrapper.LoadClass(name);
|
||||
if (tw == null)
|
||||
{
|
||||
throw new ClassNotFoundException(name);
|
||||
Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, _this);
|
||||
global::java.lang.Throwable.suppressFillInStackTrace = true;
|
||||
throw new global::java.lang.ClassNotFoundException(name);
|
||||
}
|
||||
Tracer.Info(Tracer.ClassLoading, "Loaded class \"{0}\" from {1}", name, _this);
|
||||
return tw.ClassObject;
|
||||
|
|
|
@ -830,6 +830,31 @@ namespace IKVM.StubGen
|
|||
}
|
||||
}
|
||||
|
||||
sealed class MethodParametersAttribute : ClassFileAttribute
|
||||
{
|
||||
private readonly ClassFileWriter classFile;
|
||||
private readonly ushort[] names;
|
||||
|
||||
internal MethodParametersAttribute(ClassFileWriter classFile, ushort[] names)
|
||||
: base(classFile.AddUtf8("MethodParameters"))
|
||||
{
|
||||
this.classFile = classFile;
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
public override void Write(BigEndianStream bes)
|
||||
{
|
||||
base.Write(bes);
|
||||
bes.WriteUInt32((uint)(1 + names.Length * 4));
|
||||
bes.WriteByte((byte)names.Length);
|
||||
foreach (ushort idx in names)
|
||||
{
|
||||
bes.WriteUInt16(idx);
|
||||
bes.WriteUInt16(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface IAttributeOwner
|
||||
{
|
||||
void AddAttribute(ClassFileAttribute attrib);
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace IKVM.StubGen
|
|||
{
|
||||
static class StubGenerator
|
||||
{
|
||||
internal static void WriteClass(Stream stream, TypeWrapper tw, bool includeNonPublicInterfaces, bool includeNonPublicMembers, bool includeSerialVersionUID)
|
||||
internal static void WriteClass(Stream stream, TypeWrapper tw, bool includeNonPublicInterfaces, bool includeNonPublicMembers, bool includeSerialVersionUID, bool includeParameterNames)
|
||||
{
|
||||
string name = tw.Name.Replace('.', '/');
|
||||
string super = null;
|
||||
|
@ -49,7 +49,7 @@ namespace IKVM.StubGen
|
|||
{
|
||||
super = tw.BaseTypeWrapper.Name.Replace('.', '/');
|
||||
}
|
||||
ClassFileWriter writer = new ClassFileWriter(tw.Modifiers, name, super, 0, 49);
|
||||
ClassFileWriter writer = new ClassFileWriter(tw.Modifiers, name, super, 0, includeParameterNames ? (ushort)52 : (ushort)49);
|
||||
foreach (TypeWrapper iface in tw.Interfaces)
|
||||
{
|
||||
if (iface.IsPublic || includeNonPublicInterfaces)
|
||||
|
@ -185,6 +185,22 @@ namespace IKVM.StubGen
|
|||
{
|
||||
m.AddAttribute(new AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, attr.ConstructorArguments[0])));
|
||||
}
|
||||
if (includeParameterNames)
|
||||
{
|
||||
ParameterInfo[] parameters = mb.GetParameters();
|
||||
if (parameters.Length != 0)
|
||||
{
|
||||
ushort[] names = new ushort[parameters.Length];
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
if (parameters[i].Name != null)
|
||||
{
|
||||
names[i] = writer.AddUtf8(parameters[i].Name);
|
||||
}
|
||||
}
|
||||
m.AddAttribute(new MethodParametersAttribute(writer, names));
|
||||
}
|
||||
}
|
||||
}
|
||||
string sig = tw.GetGenericMethodSignature(mw);
|
||||
if (sig != null)
|
||||
|
@ -252,7 +268,7 @@ namespace IKVM.StubGen
|
|||
{
|
||||
attr = new RuntimeVisibleAnnotationsAttribute(writer);
|
||||
}
|
||||
attr.Add(UnpackArray((IList<CustomAttributeTypedArgument>)cad.ConstructorArguments[0].Value));
|
||||
attr.Add(ann);
|
||||
}
|
||||
}
|
||||
if (attr != null)
|
||||
|
@ -290,7 +306,7 @@ namespace IKVM.StubGen
|
|||
}
|
||||
param = new RuntimeVisibleAnnotationsAttribute(writer);
|
||||
}
|
||||
param.Add(UnpackArray((IList<CustomAttributeTypedArgument>)cad.ConstructorArguments[0].Value));
|
||||
param.Add(ann);
|
||||
}
|
||||
}
|
||||
if (attr != null)
|
||||
|
@ -310,13 +326,84 @@ namespace IKVM.StubGen
|
|||
private static object[] GetAnnotation(CustomAttributeData cad)
|
||||
{
|
||||
if (cad.ConstructorArguments.Count == 1 && cad.ConstructorArguments[0].ArgumentType == typeof(object[]) &&
|
||||
(cad.Constructor.DeclaringType.IsSubclassOf(JVM.Import(typeof(ikvm.@internal.AnnotationAttributeBase)))
|
||||
|| cad.Constructor.DeclaringType == JVM.Import(typeof(DynamicAnnotationAttribute))))
|
||||
(cad.Constructor.DeclaringType.BaseType == typeof(ikvm.@internal.AnnotationAttributeBase)
|
||||
|| cad.Constructor.DeclaringType == typeof(DynamicAnnotationAttribute)))
|
||||
{
|
||||
return UnpackArray((IList<CustomAttributeTypedArgument>)cad.ConstructorArguments[0].Value);
|
||||
}
|
||||
else if (cad.Constructor.DeclaringType.BaseType == typeof(ikvm.@internal.AnnotationAttributeBase))
|
||||
{
|
||||
string annotationType = GetAnnotationInterface(cad);
|
||||
if (annotationType != null)
|
||||
{
|
||||
// this is a custom attribute annotation applied in a non-Java module
|
||||
List<object> list = new List<object>();
|
||||
list.Add(AnnotationDefaultAttribute.TAG_ANNOTATION);
|
||||
list.Add("L" + annotationType.Replace('.', '/') + ";");
|
||||
ParameterInfo[] parameters = cad.Constructor.GetParameters();
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
list.Add(parameters[i].Name);
|
||||
list.Add(EncodeAnnotationValue(cad.ConstructorArguments[i]));
|
||||
}
|
||||
foreach (CustomAttributeNamedArgument arg in cad.NamedArguments)
|
||||
{
|
||||
list.Add(arg.MemberInfo.Name);
|
||||
list.Add(EncodeAnnotationValue(arg.TypedValue));
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetAnnotationInterface(CustomAttributeData cad)
|
||||
{
|
||||
object[] attr = cad.Constructor.DeclaringType.GetCustomAttributes(typeof(IKVM.Attributes.ImplementsAttribute), false);
|
||||
if (attr.Length == 1)
|
||||
{
|
||||
string[] interfaces = ((IKVM.Attributes.ImplementsAttribute)attr[0]).Interfaces;
|
||||
if (interfaces.Length == 1)
|
||||
{
|
||||
return interfaces[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static object EncodeAnnotationValue(CustomAttributeTypedArgument arg)
|
||||
{
|
||||
if (arg.ArgumentType.IsEnum)
|
||||
{
|
||||
// if GetWrapperFromType returns null, we've got an ikvmc synthesized .NET enum nested inside a Java enum
|
||||
TypeWrapper tw = ClassLoaderWrapper.GetWrapperFromType(arg.ArgumentType) ?? ClassLoaderWrapper.GetWrapperFromType(arg.ArgumentType.DeclaringType);
|
||||
return new object[] { AnnotationDefaultAttribute.TAG_ENUM, EncodeTypeName(tw), Enum.GetName(arg.ArgumentType, arg.Value) };
|
||||
}
|
||||
else if (arg.Value is Type)
|
||||
{
|
||||
return new object[] { AnnotationDefaultAttribute.TAG_CLASS, EncodeTypeName(ClassLoaderWrapper.GetWrapperFromType((Type)arg.Value)) };
|
||||
}
|
||||
else if (arg.ArgumentType.IsArray)
|
||||
{
|
||||
IList<CustomAttributeTypedArgument> array = (IList<CustomAttributeTypedArgument>)arg.Value;
|
||||
object[] arr = new object[array.Count + 1];
|
||||
arr[0] = AnnotationDefaultAttribute.TAG_ARRAY;
|
||||
for (int i = 0; i < array.Count; i++)
|
||||
{
|
||||
arr[i + 1] = EncodeAnnotationValue(array[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return arg.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private static string EncodeTypeName(TypeWrapper tw)
|
||||
{
|
||||
return tw.SigName.Replace('.', '/');
|
||||
}
|
||||
#endif
|
||||
|
||||
private static object[] UnpackArray(IList<CustomAttributeTypedArgument> list)
|
||||
|
@ -438,10 +525,31 @@ namespace IKVM.StubGen
|
|||
"value",
|
||||
targets.ToArray()
|
||||
});
|
||||
if (Experimental.JDK_8 && IsRepeatableAnnotation(tw))
|
||||
{
|
||||
annot.Add(new object[] {
|
||||
AnnotationDefaultAttribute.TAG_ANNOTATION,
|
||||
"Ljava/lang/annotation/Repeatable;",
|
||||
"value",
|
||||
new object[] { AnnotationDefaultAttribute.TAG_CLASS, "L" + (tw.Name + DotNetTypeWrapper.AttributeAnnotationMultipleSuffix).Replace('.', '/') + ";" }
|
||||
});
|
||||
}
|
||||
writer.AddAttribute(annot);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsRepeatableAnnotation(TypeWrapper tw)
|
||||
{
|
||||
foreach (TypeWrapper nested in tw.InnerClasses)
|
||||
{
|
||||
if (nested.Name == tw.Name + DotNetTypeWrapper.AttributeAnnotationMultipleSuffix)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static byte[] GetAnnotationDefault(ClassFileWriter classFile, TypeWrapper type)
|
||||
{
|
||||
MemoryStream mem = new MemoryStream();
|
||||
|
|
|
@ -39,6 +39,25 @@ namespace IKVM.Internal
|
|||
|| String.CompareOrdinal(path, 0, RootPath, 0, RootPath.Length) == 0;
|
||||
}
|
||||
|
||||
internal static string GetAssemblyClassesPath(Assembly asm)
|
||||
{
|
||||
#if FIRST_PASS
|
||||
return null;
|
||||
#else
|
||||
// we can't use java.io.File.separatorChar here, because we're invoked by the system property setup code
|
||||
return RootPath + "assembly" + System.IO.Path.DirectorySeparatorChar + VfsAssembliesDirectory.GetName(asm) + System.IO.Path.DirectorySeparatorChar + "classes" + System.IO.Path.DirectorySeparatorChar;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static string GetAssemblyResourcesPath(Assembly asm)
|
||||
{
|
||||
#if FIRST_PASS
|
||||
return null;
|
||||
#else
|
||||
return RootPath + "assembly" + System.IO.Path.DirectorySeparatorChar + VfsAssembliesDirectory.GetName(asm) + System.IO.Path.DirectorySeparatorChar + "resources" + System.IO.Path.DirectorySeparatorChar;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !FIRST_PASS
|
||||
private static VfsDirectory root;
|
||||
|
||||
|
@ -110,25 +129,6 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
internal static string GetAssemblyClassesPath(Assembly asm)
|
||||
{
|
||||
#if FIRST_PASS
|
||||
return null;
|
||||
#else
|
||||
// we can't use java.io.File.separatorChar here, because we're invoked by the system property setup code
|
||||
return RootPath + "assembly" + System.IO.Path.DirectorySeparatorChar + VfsAssembliesDirectory.GetName(asm) + System.IO.Path.DirectorySeparatorChar + "classes" + System.IO.Path.DirectorySeparatorChar;
|
||||
#endif
|
||||
}
|
||||
|
||||
internal static string GetAssemblyResourcesPath(Assembly asm)
|
||||
{
|
||||
#if FIRST_PASS
|
||||
return null;
|
||||
#else
|
||||
return RootPath + "assembly" + System.IO.Path.DirectorySeparatorChar + VfsAssembliesDirectory.GetName(asm) + System.IO.Path.DirectorySeparatorChar + "resources" + System.IO.Path.DirectorySeparatorChar;
|
||||
#endif
|
||||
}
|
||||
|
||||
private sealed class VfsAssembliesDirectory : VfsDirectory
|
||||
{
|
||||
internal override VfsEntry GetEntry(string name)
|
||||
|
@ -577,7 +577,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
System.IO.MemoryStream mem = new System.IO.MemoryStream();
|
||||
bool includeNonPublicInterfaces = !"true".Equals(java.lang.Props.props.getProperty("ikvm.stubgen.skipNonPublicInterfaces"), StringComparison.OrdinalIgnoreCase);
|
||||
IKVM.StubGen.StubGenerator.WriteClass(mem, tw, includeNonPublicInterfaces, false, false);
|
||||
IKVM.StubGen.StubGenerator.WriteClass(mem, tw, includeNonPublicInterfaces, false, false, false);
|
||||
buf = mem.ToArray();
|
||||
}
|
||||
#endif
|
||||
|
@ -985,7 +985,7 @@ namespace IKVM.Internal
|
|||
#if FIRST_PASS
|
||||
return false;
|
||||
#else
|
||||
return access == IKVM.NativeCode.java.io.Win32FileSystem.ACCESS_READ && GetVfsEntry(path) != null;
|
||||
return access == Java_java_io_Win32FileSystem.ACCESS_READ && GetVfsEntry(path) != null;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче