--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/arch/osx/jcc/cpp.py Tue May 25 02:43:45 2010 +0200
@@ -0,0 +1,1053 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os, sys, zipfile, _jcc
+
+python_ver = '%d.%d.%d' %(sys.version_info[0:3])
+if python_ver < '2.4':
+ from sets import Set as set
+
+ def split_pkg(string, sep):
+ parts = string.split(sep)
+ if len(parts) > 1:
+ return sep.join(parts[:-1]), parts[-1]
+ return parts
+
+ def sort(list, fn=None, key=None):
+ if fn:
+ list.sort(fn)
+ elif key:
+ def fn(x, y):
+ return cmp(key(x), key(y))
+ list.sort(fn)
+ else:
+ list.sort()
+
+else:
+ def split_pkg(string, sep):
+ return string.rsplit(sep, 1)
+
+ def sort(list, fn=None, key=None):
+ if fn:
+ list.sort(cmp=fn)
+ elif key:
+ list.sort(key=key)
+ else:
+ list.sort()
+
+
+class JavaError(Exception):
+
+ def getJavaException(self):
+ return self.args[0]
+
+ def __str__(self):
+ writer = StringWriter()
+ self.getJavaException().printStackTrace(PrintWriter(writer))
+
+ return '\n'.join((super(JavaError, self).__str__(),
+ "Java stacktrace:", str(writer)))
+
+
+class InvalidArgsError(Exception):
+ pass
+
+
+_jcc._set_exception_types(JavaError, InvalidArgsError)
+from _jcc import *
+
+
+INDENT = ' '
+HALF_INDENT = ' '
+
+PRIMITIVES = { 'boolean': 'Z',
+ 'byte': 'B',
+ 'char': 'C',
+ 'double': 'D',
+ 'float': 'F',
+ 'int': 'I',
+ 'long': 'J',
+ 'short': 'S',
+ 'void': 'V' }
+
+RESERVED = set(['delete', 'and', 'or', 'not', 'xor', 'union', 'NULL',
+ 'register', 'const', 'bool', 'operator', 'typeof'])
+
+def cppname(name):
+
+ if name in RESERVED:
+ return name + '$'
+
+ return name
+
+
+def cppnames(names):
+
+ return [cppname(name) for name in names]
+
+
+def typename(cls, current, const):
+
+ if cls.isArray():
+ componentType = cls.getComponentType()
+ if componentType.isArray():
+ name = 'JArray< %s >' %(typename(componentType, current, False))
+ else:
+ name = 'JArray<%s>' %(typename(componentType, current, False))
+
+ elif cls.isPrimitive():
+ name = cls.getName()
+ if name != 'void':
+ name = 'j' + name
+ const = False
+
+ elif cls == current:
+ name = cppname(cls.getName().split('.')[-1])
+
+ else:
+ name = '::'.join([cppname(name) for name in cls.getName().split('.')])
+
+ if const:
+ return "const %s&" %(name)
+
+ return name
+
+
+def argnames(params, cls):
+
+ if not params:
+ return '', ''
+
+ count = len(params)
+ decls = ', '.join(["%s a%d" %(typename(params[i], cls, True), i)
+ for i in xrange(count)])
+ args = ', '.join(['a%d%s' %(i, not params[i].isPrimitive() and '.this$' or '')
+ for i in xrange(count)])
+
+ return decls, ', ' + args
+
+
+def line(out, indent=0, string='', *args):
+
+ out.write(INDENT * indent)
+ out.write(string % args)
+ out.write('\n')
+
+
+def known(cls, typeset, declares, packages, excludes, generics):
+
+ if generics:
+ if Class.instance_(cls):
+ cls = Class.cast_(cls)
+ elif ParameterizedType.instance_(cls):
+ pt = ParameterizedType.cast_(cls)
+ if not known(pt.getRawType(), typeset, declares, packages, excludes,
+ True):
+ return False
+ for ta in pt.getActualTypeArguments():
+ if TypeVariable.instance_(ta):
+ continue
+ if not known(ta, typeset, declares, packages, excludes, True):
+ return False
+ return True
+ elif WildcardType.instance_(cls):
+ wc = WildcardType.cast_(cls)
+ for ub in wc.getUpperBounds():
+ if not known(ub, typeset, declares, packages, excludes, True):
+ return False
+ return True
+ elif TypeVariable.instance_(cls):
+ for bounds in TypeVariable.cast_(cls).getBounds():
+ if not known(bounds, typeset, declares, packages, excludes,
+ True):
+ return False
+ return True
+ elif GenericArrayType.instance_(cls):
+ return known(GenericArrayType.cast_(cls).getGenericComponentType(),
+ typeset, declares, packages, excludes, True)
+ else:
+ raise TypeError, (cls, cls.getClass())
+
+ while cls.isArray():
+ cls = cls.getComponentType()
+
+ className = cls.getName()
+ if className in excludes:
+ return False
+
+ if cls.isPrimitive():
+ return True
+
+ if cls in typeset:
+ declares.add(cls)
+ return True
+
+ if split_pkg(className, '.')[0] in packages:
+ typeset.add(cls)
+ declares.add(cls)
+ cls = cls.getSuperclass()
+ while cls and cls not in typeset:
+ typeset.add(cls)
+ cls = cls.getSuperclass()
+ return True
+
+ return False
+
+
+def find_method(cls, name, params):
+
+ declared = False
+ while True:
+ try:
+ if declared:
+ method = cls.getDeclaredMethod(name, params)
+ else:
+ method = cls.getMethod(name, params)
+ break
+ except JavaError, e:
+ if (e.getJavaException().getClass().getName() == 'java.lang.NoSuchMethodException'):
+ if not declared:
+ declared = True
+ else:
+ cls = cls.getSuperclass()
+ if not cls:
+ return None
+ continue
+ raise
+
+ modifiers = method.getModifiers()
+ if Modifier.isAbstract(modifiers):
+ return None
+ if Modifier.isPrivate(modifiers):
+ return None
+
+ return method
+
+
+def signature(fn, argsOnly=False):
+
+ def typename(cls):
+ array = ''
+ while cls.isArray():
+ array += '['
+ cls = cls.getComponentType()
+ if cls.isPrimitive():
+ return array + PRIMITIVES[cls.getName()]
+ return '%sL%s;' %(array, cls.getName().replace('.', '/'))
+
+ if isinstance(fn, Constructor):
+ returnType = 'V'
+ elif isinstance(fn, Method):
+ returnType = typename(fn.getReturnType())
+ elif isinstance(fn, Field):
+ return typename(fn.getType())
+
+ if argsOnly:
+ return '(%s)' %(''.join([typename(param)
+ for param in fn.getParameterTypes()]))
+
+ return '(%s)%s' %(''.join([typename(param)
+ for param in fn.getParameterTypes()]),
+ returnType)
+
+
+def forward(out, namespace, indent):
+
+ for name, entries in namespace.iteritems():
+ if entries is True:
+ line(out, indent, 'class %s;', cppname(name))
+ else:
+ line(out, indent, 'namespace %s {', cppname(name))
+ forward(out, entries, indent + 1)
+ line(out, indent, '}')
+
+
+def expandjar(path):
+
+ jar = zipfile.ZipFile(path, 'r')
+
+ for member in jar.infolist():
+ f = member.filename
+ if f.endswith('.class'):
+ yield f.split('.')[0].replace('/', '.')
+
+ jar.close()
+
+
+def jcc(args):
+
+ classNames = set()
+ packages = set()
+ jars = []
+ classpath = []
+ libpath = []
+ vmargs = ['-Djava.awt.headless=true']
+ moduleName = None
+ modules = []
+ build = False
+ install = False
+ recompile = False
+ output = 'build'
+ debug = False
+ excludes = []
+ version = ''
+ mappings = {}
+ sequences = {}
+ renames = {}
+ env = None
+ wrapperFiles = 1
+ prefix = None
+ root = None
+ install_dir = None
+ home_dir = None
+ use_distutils = False
+ shared = False
+ dist = False
+ wininst = False
+ compiler = None
+ generics = hasattr(_jcc, "Type")
+ arch = []
+
+ i = 1
+ while i < len(args):
+ arg = args[i]
+ if arg.startswith('-'):
+ if arg == '--jar':
+ i += 1
+ classpath.append(args[i])
+ classNames.update(expandjar(args[i]))
+ jars.append(args[i])
+ elif arg == '--include':
+ i += 1
+ classpath.append(args[i])
+ jars.append(args[i])
+ elif arg == '--package':
+ i += 1
+ packages.add(args[i])
+ elif arg == '--classpath':
+ i += 1
+ classpath.append(args[i])
+ elif arg == '--libpath':
+ i += 1
+ libpath.append(args[i])
+ elif arg == '--vmarg':
+ i += 1
+ vmargs.append(args[i])
+ elif arg == '--python':
+ from python import python, module
+ i += 1
+ moduleName = args[i]
+ elif arg == '--module':
+ i += 1
+ modules.append(args[i])
+ elif arg == '--build':
+ from python import compile
+ build = True
+ elif arg == '--install':
+ from python import compile
+ install = True
+ elif arg == '--compile':
+ from python import compile
+ recompile = True
+ elif arg == '--output':
+ i += 1
+ output = args[i]
+ elif arg == '--debug':
+ debug = True
+ elif arg == '--exclude':
+ i += 1
+ excludes.append(args[i])
+ elif arg == '--version':
+ i += 1
+ version = args[i]
+ elif arg == '--mapping':
+ mappings[args[i + 1]] = args[i + 2]
+ i += 2
+ elif arg == '--sequence':
+ sequences[args[i + 1]] = (args[i + 2], args[i + 3])
+ i += 3
+ elif arg == '--rename':
+ i += 1
+ renames.update(dict([arg.split('=')
+ for arg in args[i].split(',')]))
+ elif arg == '--files':
+ i += 1
+ wrapperFiles = args[i]
+ if wrapperFiles != 'separate':
+ wrapperFiles = int(wrapperFiles)
+ elif arg == '--prefix':
+ i += 1
+ prefix = args[i]
+ elif arg == '--root':
+ i += 1
+ root = args[i]
+ elif arg == '--install-dir':
+ i += 1
+ install_dir = args[i]
+ elif arg == '--home':
+ i += 1
+ home_dir = args[i]
+ elif arg == '--use-distutils':
+ use_distutils = True
+ elif arg == '--shared':
+ shared = True
+ elif arg == '--bdist':
+ from python import compile
+ dist = True
+ elif arg == '--wininst':
+ from python import compile
+ wininst = True
+ dist = True
+ elif arg == '--compiler':
+ i += 1
+ compiler = args[i]
+ elif arg == '--reserved':
+ i += 1
+ RESERVED.update(args[i].split(','))
+ elif arg == '--arch':
+ i += 1
+ arch.append(args[i])
+ elif arg == '--no-generics':
+ generics = False
+ else:
+ raise ValueError, "Invalid argument: %s" %(arg)
+ else:
+ classNames.add(arg)
+ i += 1
+
+ if libpath:
+ vmargs.append('-Djava.library.path=' + os.pathsep.join(libpath))
+
+ env = initVM(os.pathsep.join(classpath) or None,
+ maxstack='512k', vmargs=' '.join(vmargs))
+
+ typeset = set()
+ excludes = set(excludes)
+
+ if recompile or not build and (install or dist):
+ if moduleName is None:
+ raise ValueError, 'module name not specified (use --python)'
+ else:
+ compile(env, os.path.dirname(args[0]), output, moduleName,
+ install, dist, debug, jars, version,
+ prefix, root, install_dir, home_dir, use_distutils,
+ shared, compiler, modules, wininst, arch, generics)
+ else:
+ for className in classNames:
+ if className in excludes:
+ continue
+ cls = findClass(className.replace('.', '/'))
+ if cls is None:
+ raise ValueError, className
+ if Modifier.isPublic(cls.getModifiers()):
+ typeset.add(cls)
+ cls = cls.getSuperclass()
+ while cls and cls not in typeset:
+ typeset.add(cls)
+ cls = cls.getSuperclass()
+ typeset.add(findClass('java/lang/Class'))
+ typeset.add(findClass('java/lang/String'))
+ typeset.add(findClass('java/lang/Throwable'))
+ typeset.add(findClass('java/lang/Exception'))
+ typeset.add(findClass('java/lang/RuntimeException'))
+ if moduleName:
+ typeset.add(findClass('java/lang/Number'))
+ typeset.add(findClass('java/lang/Boolean'))
+ typeset.add(findClass('java/lang/Integer'))
+ typeset.add(findClass('java/lang/Long'))
+ typeset.add(findClass('java/lang/Double'))
+ typeset.add(findClass('java/util/Iterator'))
+ typeset.add(findClass('java/util/Enumeration'))
+ typeset.add(findClass('java/io/StringWriter'))
+ typeset.add(findClass('java/io/PrintWriter'))
+ typeset.add(findClass('java/io/Writer'))
+ packages.add('java.lang')
+
+ if moduleName:
+ cppdir = os.path.join(output, '_%s' %(moduleName))
+ else:
+ cppdir = output
+
+ allInOne = wrapperFiles != 'separate'
+ if allInOne:
+ if not os.path.isdir(cppdir):
+ os.makedirs(cppdir)
+ if wrapperFiles <= 1:
+ out_cpp = file(os.path.join(cppdir, '__wrap__.cpp'), 'w')
+ else:
+ fileCount = 1
+ fileName = '__wrap%02d__.cpp' %(fileCount)
+ out_cpp = file(os.path.join(cppdir, fileName), 'w')
+
+ done = set()
+ todo = typeset - done
+ if allInOne and wrapperFiles > 1:
+ classesPerFile = max(1, len(todo) / wrapperFiles)
+ classCount = 0
+ while todo:
+ for cls in todo:
+ classCount += 1
+ className = cls.getName()
+ names = className.split('.')
+ dir = os.path.join(cppdir, *names[:-1])
+ if not os.path.isdir(dir):
+ os.makedirs(dir)
+
+ fileName = os.path.join(dir, names[-1])
+ out_h = file(fileName + '.h', "w")
+ line(out_h, 0, '#ifndef %s_H', '_'.join(names))
+ line(out_h, 0, '#define %s_H', '_'.join(names))
+
+ (superCls, constructors, methods, protectedMethods,
+ fields, instanceFields, declares) = \
+ header(env, out_h, cls, typeset, packages, excludes,
+ generics)
+
+ if not allInOne:
+ out_cpp = file(fileName + '.cpp', 'w')
+ names, superNames = code(env, out_cpp,
+ cls, superCls, constructors,
+ methods, protectedMethods,
+ fields, instanceFields,
+ declares, typeset)
+ if moduleName:
+ python(env, out_h, out_cpp,
+ cls, superCls, names, superNames,
+ constructors, methods, protectedMethods,
+ fields, instanceFields,
+ mappings.get(className), sequences.get(className),
+ renames.get(className),
+ declares, typeset, moduleName, generics)
+
+ line(out_h)
+ line(out_h, 0, '#endif')
+ out_h.close()
+
+ if not allInOne:
+ out_cpp.close()
+ elif wrapperFiles > 1:
+ if classCount >= classesPerFile:
+ out_cpp.close()
+ fileCount += 1
+ fileName = '__wrap%02d__.cpp' %(fileCount)
+ out_cpp = file(os.path.join(cppdir, fileName), 'w')
+ classCount = 0
+
+ done.update(todo)
+ todo = typeset - done
+
+ if allInOne:
+ out_cpp.close()
+
+ if moduleName:
+ out = file(os.path.join(cppdir, moduleName) + '.cpp', 'w')
+ module(out, allInOne, done, cppdir, moduleName, shared, generics)
+ out.close()
+ if build or install or dist:
+ compile(env, os.path.dirname(args[0]), output, moduleName,
+ install, dist, debug, jars, version,
+ prefix, root, install_dir, home_dir, use_distutils,
+ shared, compiler, modules, wininst, arch, generics)
+
+
+def header(env, out, cls, typeset, packages, excludes, generics):
+
+ names = cls.getName().split('.')
+ superCls = cls.getSuperclass()
+ declares = set([cls.getClass()])
+
+ interfaces = []
+ for interface in cls.getInterfaces():
+ if superCls and interface.isAssignableFrom(superCls):
+ continue
+ if known(interface, typeset, declares, packages, excludes, False):
+ interfaces.append(interface)
+
+ if cls.isInterface():
+ if interfaces:
+ superCls = interfaces.pop(0)
+ else:
+ superCls = findClass('java/lang/Object')
+ superClsName = superCls.getName()
+ elif superCls:
+ superClsName = superCls.getName()
+ else:
+ superClsName = 'JObject'
+
+ constructors = []
+ for constructor in cls.getDeclaredConstructors():
+ if Modifier.isPublic(constructor.getModifiers()):
+ if generics:
+ params = constructor.getGenericParameterTypes()
+ if len(params) == 1:
+ if params[0] == cls:
+ continue
+ if ParameterizedType.instance_(params[0]):
+ param = ParameterizedType.cast_(params[0])
+ if param.getRawType() == cls:
+ continue
+ else:
+ params = constructor.getParameterTypes()
+ if len(params) == 1 and params[0] == cls:
+ continue
+ for param in params:
+ if not known(param, typeset, declares, packages, excludes,
+ generics):
+ break
+ else:
+ constructors.append(constructor)
+ sort(constructors, key=lambda x: len(x.getParameterTypes()))
+
+ methods = {}
+ protectedMethods = []
+ for method in cls.getDeclaredMethods():
+ modifiers = method.getModifiers()
+ if Modifier.isPublic(modifiers):
+ if generics:
+ returnType = method.getGenericReturnType()
+ else:
+ returnType = method.getReturnType()
+ if not known(returnType, typeset, declares, packages, excludes,
+ generics):
+ continue
+ sig = "%s:%s" %(method.getName(), signature(method, True))
+ if sig in methods and returnType != cls:
+ continue
+ if generics:
+ params = method.getGenericParameterTypes()
+ else:
+ params = method.getParameterTypes()
+ for param in params:
+ if not known(param, typeset, declares, packages, excludes,
+ generics):
+ break
+ else:
+ methods[sig] = method
+ elif Modifier.isProtected(modifiers):
+ protectedMethods.append(method)
+ for interface in interfaces:
+ for method in interface.getMethods():
+ sig = "%s:%s" %(method.getName(), signature(method, True))
+ if sig not in methods:
+ if generics:
+ param = method.getGenericReturnType()
+ else:
+ param = method.getReturnType()
+ if not known(param, typeset, declares, packages, excludes,
+ generics):
+ continue
+ if generics:
+ params = method.getGenericParameterTypes()
+ else:
+ params = method.getParameterTypes()
+ for param in params:
+ if not known(param, typeset, declares, packages, excludes,
+ generics):
+ break
+ else:
+ methods[sig] = method
+
+ def _compare(m0, m1):
+ value = cmp(m0.getName(), m1.getName())
+ if value == 0:
+ value = len(m0.getParameterTypes()) - len(m1.getParameterTypes())
+ return value
+
+ methods = methods.values()
+ sort(methods, fn=_compare)
+
+ for constructor in constructors:
+ if generics:
+ exceptions = constructor.getGenericExceptionTypes()
+ else:
+ exceptions = constructor.getExceptionTypes()
+ for exception in exceptions:
+ known(exception, typeset, declares, packages, excludes, generics)
+ for method in methods:
+ if generics:
+ exceptions = method.getGenericExceptionTypes()
+ else:
+ exceptions = method.getExceptionTypes()
+ for exception in exceptions:
+ known(exception, typeset, declares, packages, excludes, generics)
+
+ fields = []
+ instanceFields = []
+ for field in cls.getDeclaredFields():
+ modifiers = field.getModifiers()
+ if Modifier.isPublic(modifiers):
+ if generics:
+ fieldType = field.getGenericType()
+ else:
+ fieldType = field.getType()
+ if not known(fieldType, typeset, declares, packages, excludes,
+ generics):
+ continue
+ if Modifier.isStatic(modifiers):
+ fields.append(field)
+ else:
+ instanceFields.append(field)
+ sort(fields, key=lambda x: x.getName())
+ sort(instanceFields, key=lambda x: x.getName())
+
+ line(out)
+ superNames = superClsName.split('.')
+ line(out, 0, '#include "%s.h"', '/'.join(superNames))
+
+ line(out, 0)
+ namespaces = {}
+ for declare in declares:
+ namespace = namespaces
+ if declare not in (cls, superCls):
+ declareNames = declare.getName().split('.')
+ for declareName in declareNames[:-1]:
+ namespace = namespace.setdefault(declareName, {})
+ namespace[declareNames[-1]] = True
+ forward(out, namespaces, 0)
+ line(out, 0, 'template<class T> class JArray;')
+
+ indent = 0;
+ line(out)
+ for name in names[:-1]:
+ line(out, indent, 'namespace %s {', cppname(name))
+ indent += 1
+
+ line(out)
+ if superClsName == 'JObject':
+ line(out, indent, 'class %s : public JObject {', cppname(names[-1]))
+ else:
+ line(out, indent, 'class %s : public %s {',
+ cppname(names[-1]), '::'.join(cppnames(superNames)))
+
+ line(out, indent, 'public:')
+ indent += 1
+
+ if methods or protectedMethods or constructors:
+ line(out, indent, 'enum {')
+ for constructor in constructors:
+ line(out, indent + 1, 'mid_init$_%s,',
+ env.strhash(signature(constructor)))
+ for method in methods:
+ line(out, indent + 1, 'mid_%s_%s,', method.getName(),
+ env.strhash(signature(method)))
+ for method in protectedMethods:
+ line(out, indent + 1, 'mid_%s_%s,', method.getName(),
+ env.strhash(signature(method)))
+ line(out, indent + 1, 'max_mid')
+ line(out, indent, '};')
+
+ if instanceFields:
+ line(out)
+ line(out, indent, 'enum {')
+ for field in instanceFields:
+ line(out, indent + 1, 'fid_%s,', field.getName())
+ line(out, indent + 1, 'max_fid')
+ line(out, indent, '};')
+
+ line(out)
+ line(out, indent, 'static java::lang::Class *class$;');
+ line(out, indent, 'static jmethodID *mids$;');
+ if instanceFields:
+ line(out, indent, 'static jfieldID *fids$;');
+ line(out, indent, 'static jclass initializeClass();');
+ line(out)
+
+ line(out, indent, 'explicit %s(jobject obj) : %s(obj) {',
+ cppname(names[-1]), '::'.join(cppnames(superNames)))
+ line(out, indent + 1, 'if (obj != NULL)');
+ line(out, indent + 2, 'initializeClass();')
+ line(out, indent, '}')
+ line(out, indent, '%s(const %s& obj) : %s(obj) {}',
+ cppname(names[-1]), cppname(names[-1]),
+ '::'.join(cppnames(superNames)))
+
+ if fields:
+ line(out)
+ for field in fields:
+ fieldType = field.getType()
+ fieldName = cppname(field.getName())
+ if fieldType.isPrimitive():
+ line(out, indent, 'static %s %s;',
+ typename(fieldType, cls, False), fieldName)
+ else:
+ line(out, indent, 'static %s *%s;',
+ typename(fieldType, cls, False), fieldName)
+
+ if instanceFields:
+ line(out)
+ for field in instanceFields:
+ fieldType = field.getType()
+ fieldName = field.getName()
+ modifiers = field.getModifiers()
+ line(out, indent, '%s _get_%s() const;',
+ typename(fieldType, cls, False), fieldName)
+ if not Modifier.isFinal(modifiers):
+ line(out, indent, 'void _set_%s(%s) const;',
+ fieldName, typename(fieldType, cls, True))
+
+ if constructors:
+ line(out)
+ for constructor in constructors:
+ params = [typename(param, cls, True)
+ for param in constructor.getParameterTypes()]
+ line(out, indent, '%s(%s);', cppname(names[-1]), ', '.join(params))
+
+ if methods:
+ line(out)
+ for method in methods:
+ modifiers = method.getModifiers()
+ if Modifier.isStatic(modifiers):
+ prefix = 'static '
+ const = ''
+ else:
+ prefix = ''
+ const = ' const'
+ params = [typename(param, cls, True)
+ for param in method.getParameterTypes()]
+ methodName = cppname(method.getName())
+ line(out, indent, '%s%s %s(%s)%s;',
+ prefix, typename(method.getReturnType(), cls, False),
+ methodName, ', '.join(params), const)
+
+ indent -= 1
+ line(out, indent, '};')
+
+ while indent:
+ indent -= 1
+ line(out, indent, '}')
+
+ return (superCls, constructors, methods, protectedMethods,
+ fields, instanceFields, declares)
+
+
+def code(env, out, cls, superCls, constructors, methods, protectedMethods,
+ fields, instanceFields, declares, typeset):
+
+ className = cls.getName()
+ names = className.split('.')
+
+ if superCls:
+ superClsName = superCls.getName()
+ else:
+ superClsName = 'JObject'
+ superNames = superClsName.split('.')
+
+ line(out, 0, '#include <jni.h>')
+ line(out, 0, '#include "JCCEnv.h"')
+ line(out, 0, '#include "%s.h"', className.replace('.', '/'))
+ for declare in declares:
+ if declare not in (cls, superCls):
+ line(out, 0, '#include "%s.h"', declare.getName().replace('.', '/'))
+ line(out, 0, '#include "JArray.h"')
+
+ indent = 0
+ line(out)
+ for name in names[:-1]:
+ line(out, indent, 'namespace %s {', cppname(name))
+ indent += 1
+
+ line(out)
+ line(out, indent, 'java::lang::Class *%s::class$ = NULL;',
+ cppname(names[-1]))
+ line(out, indent, 'jmethodID *%s::mids$ = NULL;', cppname(names[-1]))
+ if instanceFields:
+ line(out, indent, 'jfieldID *%s::fids$ = NULL;', cppname(names[-1]))
+
+ for field in fields:
+ fieldType = field.getType()
+ fieldName = cppname(field.getName())
+ typeName = typename(fieldType, cls, False)
+ if fieldType.isPrimitive():
+ line(out, indent, '%s %s::%s = (%s) 0;',
+ typeName, cppname(names[-1]), fieldName, typeName)
+ else:
+ line(out, indent, '%s *%s::%s = NULL;',
+ typeName, cppname(names[-1]), fieldName)
+
+ line(out)
+ line(out, indent, 'jclass %s::initializeClass()', cppname(names[-1]))
+ line(out, indent, '{')
+ line(out, indent + 1, 'if (!class$)')
+ line(out, indent + 1, '{')
+ line(out)
+ line(out, indent + 2, 'jclass cls = (jclass) env->findClass("%s");',
+ className.replace('.', '/'))
+
+ if methods or protectedMethods or constructors:
+ line(out)
+ line(out, indent + 2, 'mids$ = new jmethodID[max_mid];')
+ for constructor in constructors:
+ sig = signature(constructor)
+ line(out, indent + 2,
+ 'mids$[mid_init$_%s] = env->getMethodID(cls, "<init>", "%s");',
+ env.strhash(sig), sig)
+ isExtension = False
+ for method in methods:
+ methodName = method.getName()
+ if methodName == 'pythonExtension':
+ isExtension = True
+ sig = signature(method)
+ line(out, indent + 2,
+ 'mids$[mid_%s_%s] = env->get%sMethodID(cls, "%s", "%s");',
+ methodName, env.strhash(sig),
+ Modifier.isStatic(method.getModifiers()) and 'Static' or '',
+ methodName, sig)
+ for method in protectedMethods:
+ methodName = method.getName()
+ sig = signature(method)
+ line(out, indent + 2,
+ 'mids$[mid_%s_%s] = env->get%sMethodID(cls, "%s", "%s");',
+ methodName, env.strhash(sig),
+ Modifier.isStatic(method.getModifiers()) and 'Static' or '',
+ methodName, sig)
+
+ if instanceFields:
+ line(out)
+ line(out, indent + 2, 'fids$ = new jfieldID[max_fid];')
+ for field in instanceFields:
+ fieldName = field.getName()
+ line(out, indent + 2,
+ 'fids$[fid_%s] = env->getFieldID(cls, "%s", "%s");',
+ fieldName, fieldName, signature(field))
+
+ line(out)
+ line(out, indent + 2, 'class$ = (java::lang::Class *) new JObject(cls);')
+
+ if fields:
+ line(out, indent + 2, 'cls = (jclass) class$->this$;')
+ line(out)
+ for field in fields:
+ fieldType = field.getType()
+ fieldName = field.getName()
+ if fieldType.isPrimitive():
+ line(out, indent + 2,
+ '%s = env->getStatic%sField(cls, "%s");',
+ cppname(fieldName), fieldType.getName().capitalize(),
+ fieldName)
+ else:
+ line(out, indent + 2,
+ '%s = new %s(env->getStaticObjectField(cls, "%s", "%s"));',
+ cppname(fieldName), typename(fieldType, cls, False),
+ fieldName, signature(field))
+
+ line(out, indent + 1, '}')
+ line(out, indent + 1, 'return (jclass) class$->this$;')
+ line(out, indent, '}')
+
+ for constructor in constructors:
+ line(out)
+ sig = signature(constructor)
+ decls, args = argnames(constructor.getParameterTypes(), cls)
+
+ line(out, indent, "%s::%s(%s) : %s(env->newObject(initializeClass, &mids$, mid_init$_%s%s)) {}",
+ cppname(names[-1]), cppname(names[-1]), decls,
+ '::'.join(cppnames(superNames)),
+ env.strhash(sig), args)
+
+ for method in methods:
+ modifiers = method.getModifiers()
+ returnType = method.getReturnType()
+ params = method.getParameterTypes()
+ methodName = method.getName()
+ superMethod = None
+ isStatic = Modifier.isStatic(modifiers)
+
+ if (isExtension and not isStatic and superCls and
+ Modifier.isNative(modifiers)):
+ superMethod = find_method(superCls, methodName, params)
+ if superMethod is None:
+ continue
+
+ if isStatic:
+ qualifier = 'Static'
+ this = 'cls'
+ midns = ''
+ const = ''
+ else:
+ isStatic = False
+ if superMethod is not None:
+ qualifier = 'Nonvirtual'
+ this = 'this$, (jclass) %s::class$->this$' %('::'.join(cppnames(superNames)))
+ declaringClass = superMethod.getDeclaringClass()
+ midns = '%s::' %(typename(declaringClass, cls, False))
+ else:
+ qualifier = ''
+ this = 'this$'
+ midns = ''
+ const = ' const'
+
+ sig = signature(method)
+ decls, args = argnames(params, cls)
+
+ line(out)
+ line(out, indent, '%s %s::%s(%s)%s',
+ typename(returnType, cls, False), cppname(names[-1]),
+ cppname(methodName), decls, const)
+ line(out, indent, '{')
+ if isStatic:
+ line(out, indent + 1, 'jclass cls = initializeClass();');
+ if returnType.isPrimitive():
+ line(out, indent + 1,
+ '%senv->call%s%sMethod(%s, %smids$[%smid_%s_%s]%s);',
+ not returnType.getName() == 'void' and 'return ' or '',
+ qualifier, returnType.getName().capitalize(), this,
+ midns, midns, methodName, env.strhash(sig), args)
+ else:
+ line(out, indent + 1,
+ 'return %s(env->call%sObjectMethod(%s, %smids$[%smid_%s_%s]%s));',
+ typename(returnType, cls, False), qualifier, this,
+ midns, midns, methodName, env.strhash(sig), args)
+ line(out, indent, '}')
+
+ if instanceFields:
+ for field in instanceFields:
+ fieldType = field.getType()
+ fieldName = field.getName()
+ line(out)
+ line(out, indent, '%s %s::_get_%s() const',
+ typename(fieldType, cls, False), cppname(names[-1]), fieldName)
+ line(out, indent, '{')
+ if fieldType.isPrimitive():
+ line(out, indent + 1,
+ 'return env->get%sField(this$, fids$[fid_%s]);',
+ fieldType.getName().capitalize(), fieldName)
+ else:
+ line(out, indent + 1,
+ 'return %s(env->getObjectField(this$, fids$[fid_%s]));',
+ typename(fieldType, cls, False), fieldName)
+ line(out, indent, '}')
+
+ if not Modifier.isFinal(field.getModifiers()):
+ line(out)
+ line(out, indent, 'void %s::_set_%s(%s a0) const',
+ cppname(names[-1]), fieldName,
+ typename(fieldType, cls, True))
+ line(out, indent, '{')
+ if fieldType.isPrimitive():
+ line(out, indent + 1,
+ 'env->set%sField(this$, fids$[fid_%s], a0);',
+ fieldType.getName().capitalize(), fieldName)
+ else:
+ line(out, indent + 1,
+ 'env->setObjectField(this$, fids$[fid_%s], a0.this$);',
+ fieldName)
+ line(out, indent, '}')
+
+ while indent:
+ indent -= 1
+ line(out, indent, '}')
+
+ return names, superNames
+
+
+if __name__ == '__main__':
+ jcc(sys.argv)