# 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)