2002-12-18 19:00:25 +03:00
|
|
|
/*
|
2004-09-09 15:17:55 +04:00
|
|
|
Copyright (C) 2002, 2004 Jeroen Frijters
|
2002-12-18 19:00:25 +03:00
|
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
|
|
warranty. In no event will the authors be held liable for any damages
|
|
|
|
arising from the use of this software.
|
|
|
|
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
|
|
including commercial applications, and to alter it and redistribute it
|
|
|
|
freely, subject to the following restrictions:
|
|
|
|
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
|
|
claim that you wrote the original software. If you use this software
|
|
|
|
in a product, an acknowledgment in the product documentation would be
|
|
|
|
appreciated but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
|
|
|
|
Jeroen Frijters
|
|
|
|
jeroen@frijters.net
|
|
|
|
|
|
|
|
*/
|
|
|
|
using System;
|
|
|
|
using System.Reflection;
|
|
|
|
using System.IO;
|
|
|
|
using System.Text;
|
2003-10-22 20:34:22 +04:00
|
|
|
using System.Collections;
|
2003-01-08 16:35:05 +03:00
|
|
|
using ICSharpCode.SharpZipLib.Zip;
|
2003-08-21 14:06:34 +04:00
|
|
|
using java.lang;
|
|
|
|
using java.lang.reflect;
|
2004-09-09 15:17:55 +04:00
|
|
|
using IKVM.Attributes;
|
|
|
|
using IKVM.Internal;
|
2002-12-18 19:00:25 +03:00
|
|
|
|
|
|
|
public class NetExp
|
|
|
|
{
|
|
|
|
private static ZipOutputStream zipFile;
|
2003-10-22 20:34:22 +04:00
|
|
|
private static Hashtable privateClasses = new Hashtable();
|
2002-12-18 19:00:25 +03:00
|
|
|
|
|
|
|
public static void Main(string[] args)
|
|
|
|
{
|
2004-03-08 18:18:47 +03:00
|
|
|
Tracer.EnableTraceForDebug();
|
2004-06-07 12:28:57 +04:00
|
|
|
if(args.Length != 1)
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("usage: ikvmstub <assemblyNameOrPath>");
|
|
|
|
return;
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
Assembly assembly = null;
|
2004-06-07 12:28:57 +04:00
|
|
|
FileInfo file = null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
file = new FileInfo(args[0]);
|
|
|
|
}
|
|
|
|
catch(System.Exception x)
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("Error: unable to load \"{0}\"\n {1}", args[0], x.Message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(file != null && file.Exists)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-26 15:24:17 +04:00
|
|
|
try
|
|
|
|
{
|
|
|
|
// If the same assembly can be found in the "Load" context, we prefer to use that
|
|
|
|
// http://blogs.gotdotnet.com/suzcook/permalink.aspx/d5c5e14a-3612-4af1-a9b7-0a144c8dbf16
|
|
|
|
// We use AssemblyName.FullName, because otherwise the assembly will be loaded in the
|
|
|
|
// "LoadFrom" context using the path inside the AssemblyName object.
|
|
|
|
assembly = Assembly.Load(AssemblyName.GetAssemblyName(args[0]).FullName);
|
|
|
|
Console.Error.WriteLine("Warning: Assembly loaded from {0} instead", assembly.Location);
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
}
|
|
|
|
if(assembly == null)
|
|
|
|
{
|
|
|
|
assembly = Assembly.LoadFrom(args[0]);
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
assembly = Assembly.LoadWithPartialName(args[0]);
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
if(assembly == null)
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("Error: Assembly \"{0}\" not found", args[0]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-01-08 16:35:05 +03:00
|
|
|
zipFile = new ZipOutputStream(new FileStream(assembly.GetName().Name + ".jar", FileMode.Create));
|
2004-12-21 13:26:51 +03:00
|
|
|
try
|
|
|
|
{
|
|
|
|
ProcessAssembly(assembly);
|
|
|
|
ProcessPrivateClasses(assembly);
|
|
|
|
}
|
|
|
|
catch(System.Exception x)
|
|
|
|
{
|
|
|
|
java.lang.Throwable.instancehelper_printStackTrace(IKVM.Runtime.Util.MapException(x));
|
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
zipFile.Close();
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2004-05-25 11:14:39 +04:00
|
|
|
// FXBUG if we run a static initializer that starts a thread, we would never end,
|
2003-08-21 14:06:34 +04:00
|
|
|
// so we force an exit here
|
|
|
|
Environment.Exit(0);
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
|
2003-08-21 14:06:34 +04:00
|
|
|
private static void WriteClass(string name, ClassFileWriter c)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
zipFile.PutNextEntry(new ZipEntry(name));
|
|
|
|
c.Write(zipFile);
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
|
2003-08-21 14:06:34 +04:00
|
|
|
private static void ProcessAssembly(Assembly assembly)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
foreach(Type t in assembly.GetTypes())
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
if(t.IsPublic)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2004-10-04 23:30:53 +04:00
|
|
|
Class c;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
c = Class.forName(t.AssemblyQualifiedName, false, null);
|
|
|
|
}
|
|
|
|
catch(ClassNotFoundException)
|
|
|
|
{
|
|
|
|
// types that IKVM doesn't support don't show up
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ProcessClass(assembly.FullName, c, null);
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-17 15:01:50 +03:00
|
|
|
// TODO private classes should also be done handled for interfaces, fields and method arguments/return type
|
2003-10-22 20:34:22 +04:00
|
|
|
private static void ProcessPrivateClasses(Assembly assembly)
|
|
|
|
{
|
|
|
|
Hashtable done = new Hashtable();
|
|
|
|
bool keepGoing;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
Hashtable todo = privateClasses;
|
|
|
|
privateClasses = new Hashtable();
|
|
|
|
keepGoing = false;
|
|
|
|
foreach(Class c in todo.Values)
|
|
|
|
{
|
|
|
|
if(!done.ContainsKey(c.getName()))
|
|
|
|
{
|
|
|
|
keepGoing = true;
|
|
|
|
done.Add(c.getName(), null);
|
|
|
|
ProcessClass(assembly.FullName, c, c.getDeclaringClass());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while(keepGoing);
|
|
|
|
}
|
|
|
|
|
2003-08-21 14:06:34 +04:00
|
|
|
private static void ProcessClass(string assemblyName, Class c, Class outer)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
string name = c.getName().Replace('.', '/');
|
|
|
|
string super = null;
|
|
|
|
if(c.getSuperclass() != null)
|
2003-04-14 13:41:58 +04:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
super = c.getSuperclass().getName().Replace('.', '/');
|
2003-10-22 20:34:22 +04:00
|
|
|
// if the base class isn't public, we still need to export it (!)
|
|
|
|
if(!Modifier.isPublic(c.getSuperclass().getModifiers()))
|
|
|
|
{
|
|
|
|
privateClasses[c.getSuperclass().getName()] = c.getSuperclass();
|
|
|
|
}
|
2003-04-14 13:41:58 +04:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
if(c.isInterface())
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
|
|
|
super = "java/lang/Object";
|
|
|
|
}
|
2004-02-18 16:48:38 +03:00
|
|
|
Modifiers classmods = (Modifiers)c.getModifiers();
|
|
|
|
if(outer != null)
|
|
|
|
{
|
|
|
|
// protected inner classes are actually public and private inner classes are actually package
|
|
|
|
if((classmods & Modifiers.Protected) != 0)
|
|
|
|
{
|
|
|
|
classmods |= Modifiers.Public;
|
|
|
|
}
|
|
|
|
classmods &= ~(Modifiers.Static | Modifiers.Private | Modifiers.Protected);
|
|
|
|
}
|
|
|
|
ClassFileWriter f = new ClassFileWriter(classmods, name, super);
|
2003-08-21 14:06:34 +04:00
|
|
|
f.AddStringAttribute("IKVM.NET.Assembly", assemblyName);
|
2004-11-16 14:11:53 +03:00
|
|
|
if(IKVM.Runtime.Util.IsClassDeprecated(c))
|
|
|
|
{
|
|
|
|
f.AddAttribute(new DeprecatedAttribute(f));
|
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
InnerClassesAttribute innerClassesAttribute = null;
|
|
|
|
if(outer != null)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
innerClassesAttribute = new InnerClassesAttribute(f);
|
2004-02-10 12:53:56 +03:00
|
|
|
string innername = name;
|
|
|
|
int idx = name.LastIndexOf('$');
|
|
|
|
if(idx >= 0)
|
|
|
|
{
|
|
|
|
innername = innername.Substring(idx + 1);
|
|
|
|
}
|
|
|
|
innerClassesAttribute.Add(name, outer.getName().Replace('.', '/'), innername, (ushort)c.getModifiers());
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-11-17 15:01:50 +03:00
|
|
|
Class[] interfaces = c.getInterfaces();
|
|
|
|
for(int i = 0; i < interfaces.Length; i++)
|
|
|
|
{
|
|
|
|
if(Modifier.isPublic(interfaces[i].getModifiers()))
|
|
|
|
{
|
|
|
|
f.AddInterface(interfaces[i].getName().Replace('.', '/'));
|
|
|
|
}
|
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
Class[] innerClasses = c.getDeclaredClasses();
|
|
|
|
for(int i = 0; i < innerClasses.Length; i++)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
Modifiers mods = (Modifiers)innerClasses[i].getModifiers();
|
|
|
|
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
if(innerClassesAttribute == null)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
innerClassesAttribute = new InnerClassesAttribute(f);
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
string namePart = innerClasses[i].getName();
|
|
|
|
namePart = namePart.Substring(namePart.LastIndexOf('$') + 1);
|
|
|
|
innerClassesAttribute.Add(innerClasses[i].getName().Replace('.', '/'), name, namePart, (ushort)innerClasses[i].getModifiers());
|
|
|
|
ProcessClass(assemblyName, innerClasses[i], c);
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
Constructor[] constructors = c.getDeclaredConstructors();
|
2002-12-18 19:00:25 +03:00
|
|
|
for(int i = 0; i < constructors.Length; i++)
|
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
Modifiers mods = (Modifiers)constructors[i].getModifiers();
|
|
|
|
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-11-17 15:01:50 +03:00
|
|
|
// TODO what happens if one of the argument types is non-public?
|
2004-02-10 12:53:56 +03:00
|
|
|
java.lang.Class[] args = constructors[i].getParameterTypes();
|
|
|
|
FieldOrMethod m = f.AddMethod(mods, "<init>", MakeSig(args, java.lang.Void.TYPE));
|
|
|
|
CodeAttribute code = new CodeAttribute(f);
|
2004-07-10 11:19:42 +04:00
|
|
|
code.MaxLocals = (ushort)(args.Length * 2 + 1);
|
2004-02-16 20:23:03 +03:00
|
|
|
code.MaxStack = 3;
|
|
|
|
ushort index1 = f.AddClass("java/lang/UnsatisfiedLinkError");
|
2004-05-27 13:32:35 +04:00
|
|
|
ushort index2 = f.AddString("ikvmstub generated stubs can only be used on IKVM.NET");
|
2004-02-16 20:23:03 +03:00
|
|
|
ushort index3 = f.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
|
|
|
|
};
|
2004-02-10 12:53:56 +03:00
|
|
|
m.AddAttribute(code);
|
2004-11-04 15:50:28 +03:00
|
|
|
AddExceptions(f, m, constructors[i].getExceptionTypes());
|
2004-11-16 14:11:53 +03:00
|
|
|
if(IKVM.Runtime.Util.IsConstructorDeprecated(constructors[i]))
|
|
|
|
{
|
|
|
|
m.AddAttribute(new DeprecatedAttribute(f));
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
Method[] methods = c.getDeclaredMethods();
|
2002-12-18 19:00:25 +03:00
|
|
|
for(int i = 0; i < methods.Length; i++)
|
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
Modifiers mods = (Modifiers)methods[i].getModifiers();
|
|
|
|
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
if((mods & Modifiers.Abstract) == 0)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
mods |= Modifiers.Native;
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-11-17 15:01:50 +03:00
|
|
|
// TODO what happens if one of the argument types (or the return type) is non-public?
|
|
|
|
FieldOrMethod m = f.AddMethod(mods, methods[i].getName(), MakeSig(methods[i].getParameterTypes(), methods[i].getReturnType()));
|
2004-11-04 15:50:28 +03:00
|
|
|
AddExceptions(f, m, methods[i].getExceptionTypes());
|
2004-11-16 14:11:53 +03:00
|
|
|
if(IKVM.Runtime.Util.IsMethodDeprecated(methods[i]))
|
|
|
|
{
|
|
|
|
m.AddAttribute(new DeprecatedAttribute(f));
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
Field[] fields = c.getDeclaredFields();
|
|
|
|
for(int i = 0; i < fields.Length; i++)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
Modifiers mods = (Modifiers)fields[i].getModifiers();
|
2004-11-16 14:11:53 +03:00
|
|
|
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0 ||
|
|
|
|
// Include serialVersionUID field, to make Japitools comparison more acurate
|
|
|
|
((mods & (Modifiers.Static | Modifiers.Final)) == (Modifiers.Static | Modifiers.Final) &&
|
|
|
|
fields[i].getName() == "serialVersionUID" && fields[i].getType() == java.lang.Long.TYPE))
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2004-11-16 14:11:53 +03:00
|
|
|
// HACK we use the IKVM runtime API to get constant value
|
|
|
|
// NOTE we can't use Field.get() because that will run the static initializer and
|
|
|
|
// also won't allow us to see the difference between constants and blank final fields.
|
|
|
|
object constantValue = IKVM.Runtime.Util.GetFieldConstantValue(fields[i]);
|
|
|
|
if(constantValue != null)
|
2003-08-21 14:06:34 +04:00
|
|
|
{
|
2004-11-16 14:11:53 +03:00
|
|
|
if(constantValue is java.lang.Boolean)
|
2003-08-21 14:06:34 +04:00
|
|
|
{
|
2004-11-16 14:11:53 +03:00
|
|
|
constantValue = ((java.lang.Boolean)constantValue).booleanValue();
|
|
|
|
}
|
|
|
|
else if(constantValue is java.lang.Byte)
|
|
|
|
{
|
|
|
|
constantValue = ((java.lang.Byte)constantValue).byteValue();
|
|
|
|
}
|
|
|
|
else if(constantValue is java.lang.Short)
|
|
|
|
{
|
|
|
|
constantValue = ((java.lang.Short)constantValue).shortValue();
|
|
|
|
}
|
|
|
|
else if(constantValue is java.lang.Character)
|
|
|
|
{
|
|
|
|
constantValue = ((java.lang.Character)constantValue).charValue();
|
|
|
|
}
|
|
|
|
else if(constantValue is java.lang.Integer)
|
|
|
|
{
|
|
|
|
constantValue = ((java.lang.Integer)constantValue).intValue();
|
|
|
|
}
|
|
|
|
else if(constantValue is java.lang.Long)
|
|
|
|
{
|
|
|
|
constantValue = ((java.lang.Long)constantValue).longValue();
|
|
|
|
}
|
|
|
|
else if(constantValue is java.lang.Float)
|
|
|
|
{
|
|
|
|
constantValue = ((java.lang.Float)constantValue).floatValue();
|
|
|
|
}
|
|
|
|
else if(constantValue is java.lang.Double)
|
|
|
|
{
|
|
|
|
constantValue = ((java.lang.Double)constantValue).doubleValue();
|
|
|
|
}
|
|
|
|
else if(constantValue is string)
|
|
|
|
{
|
|
|
|
// no conversion needed
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new InvalidOperationException();
|
2003-08-21 14:06:34 +04:00
|
|
|
}
|
|
|
|
}
|
2003-11-17 15:01:50 +03:00
|
|
|
// TODO what happens if the field type is non-public?
|
2004-11-16 14:11:53 +03:00
|
|
|
FieldOrMethod fld = f.AddField(mods, fields[i].getName(), ClassToSig(fields[i].getType()), constantValue);
|
|
|
|
if(IKVM.Runtime.Util.IsFieldDeprecated(fields[i]))
|
|
|
|
{
|
|
|
|
fld.AddAttribute(new DeprecatedAttribute(f));
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
}
|
|
|
|
if(innerClassesAttribute != null)
|
|
|
|
{
|
|
|
|
f.AddAttribute(innerClassesAttribute);
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
WriteClass(name + ".class", f);
|
|
|
|
}
|
|
|
|
|
2004-11-04 15:50:28 +03:00
|
|
|
private static void AddExceptions(ClassFileWriter f, FieldOrMethod m, Class[] exceptions)
|
|
|
|
{
|
|
|
|
if(exceptions.Length > 0)
|
|
|
|
{
|
|
|
|
ExceptionsAttribute attrib = new ExceptionsAttribute(f);
|
|
|
|
foreach(Class x in exceptions)
|
|
|
|
{
|
|
|
|
// TODO what happens if one of the exception types is non-public?
|
|
|
|
attrib.Add(x.getName().Replace('.', '/'));
|
|
|
|
}
|
|
|
|
m.AddAttribute(attrib);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-08-21 14:06:34 +04:00
|
|
|
private static string MakeSig(Class[] args, Class ret)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.Append('(');
|
|
|
|
for(int i = 0; i < args.Length; i++)
|
|
|
|
{
|
|
|
|
sb.Append(ClassToSig(args[i]));
|
|
|
|
}
|
|
|
|
sb.Append(')');
|
|
|
|
sb.Append(ClassToSig(ret));
|
|
|
|
return sb.ToString();
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
|
2003-08-21 14:06:34 +04:00
|
|
|
private static string ClassToSig(Class c)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
if(c.isPrimitive())
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
if(c == java.lang.Void.TYPE)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "V";
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c == java.lang.Byte.TYPE)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "B";
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c == java.lang.Boolean.TYPE)
|
2003-02-15 14:18:53 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "Z";
|
2003-02-15 14:18:53 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c == java.lang.Short.TYPE)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "S";
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c == java.lang.Character.TYPE)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "C";
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c == java.lang.Integer.TYPE)
|
2003-02-15 14:18:53 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "I";
|
2003-02-15 14:18:53 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c == java.lang.Long.TYPE)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "J";
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c == java.lang.Float.TYPE)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "F";
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c == java.lang.Double.TYPE)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "D";
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else
|
2003-03-31 18:54:35 +04:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
throw new InvalidOperationException();
|
2003-03-31 18:54:35 +04:00
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-08-21 14:06:34 +04:00
|
|
|
else if(c.isArray())
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "[" + ClassToSig(c.getComponentType());
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-21 14:06:34 +04:00
|
|
|
return "L" + c.getName().Replace('.', '/') + ";";
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|