web/lib/arch/osx/jcc/cpp.py
changeset 29 cc9b7e14412b
--- /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)