1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
5 # http://www.apache.org/licenses/LICENSE-2.0
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 # See the License for the specific language governing permissions and
11 # limitations under the License.
13 import os, sys, zipfile, _jcc
15 python_ver = '%d.%d.%d' %(sys.version_info[0:3])
16 if python_ver < '2.4':
17 from sets import Set as set
19 def split_pkg(string, sep):
20 parts = string.split(sep)
22 return sep.join(parts[:-1]), parts[-1]
25 def sort(list, fn=None, key=None):
30 return cmp(key(x), key(y))
36 def split_pkg(string, sep):
37 return string.rsplit(sep, 1)
39 def sort(list, fn=None, key=None):
48 class JavaError(Exception):
50 def getJavaException(self):
54 writer = StringWriter()
55 self.getJavaException().printStackTrace(PrintWriter(writer))
57 return '\n'.join((super(JavaError, self).__str__(),
58 "Java stacktrace:", str(writer)))
61 class InvalidArgsError(Exception):
65 _jcc._set_exception_types(JavaError, InvalidArgsError)
66 from _jcc import findClass as _findClass
70 def findClass(className):
73 cls = _findClass(className)
75 print >>sys.stderr, "While loading", className
79 raise ValueError, className
87 PRIMITIVES = { 'boolean': 'Z',
97 RESERVED = set(['delete', 'and', 'or', 'not', 'xor', 'union', 'register',
98 'const', 'bool', 'operator', 'typeof', 'asm',
99 'NULL', 'DOMAIN', 'IGNORE'])
111 return [cppname(name) for name in names]
117 return "::%s" %('::'.join(names))
122 def typename(cls, current, const):
125 componentType = cls.getComponentType()
126 name = 'JArray< %s >' %(typename(componentType, current, False))
128 elif cls.isPrimitive():
135 name = cppname(cls.getName().split('.')[-1])
138 name = absname([cppname(name) for name in cls.getName().split('.')])
141 return "const %s &" %(name)
146 def argnames(params, cls):
152 decls = ', '.join(["%s a%d" %(typename(params[i], cls, True), i)
153 for i in xrange(count)])
154 args = ', '.join(['a%d%s' %(i, not params[i].isPrimitive() and '.this$' or '')
155 for i in xrange(count)])
157 return decls, ', ' + args
160 def line(out, indent=0, string='', *args):
162 out.write(INDENT * indent)
163 out.write(string % args)
167 def known(cls, typeset, declares, packages, excludes, generics):
170 if Class.instance_(cls):
171 cls = Class.cast_(cls)
172 elif ParameterizedType.instance_(cls):
173 pt = ParameterizedType.cast_(cls)
174 if not known(pt.getRawType(), typeset, declares, packages, excludes,
177 for ta in pt.getActualTypeArguments():
178 if TypeVariable.instance_(ta):
180 if not known(ta, typeset, declares, packages, excludes, True):
183 elif WildcardType.instance_(cls):
184 wc = WildcardType.cast_(cls)
185 for ub in wc.getUpperBounds():
186 if not known(ub, typeset, declares, packages, excludes, True):
189 elif TypeVariable.instance_(cls):
190 for bounds in TypeVariable.cast_(cls).getBounds():
191 if not known(bounds, typeset, declares, packages, excludes,
195 elif GenericArrayType.instance_(cls):
196 return known(GenericArrayType.cast_(cls).getGenericComponentType(),
197 typeset, declares, packages, excludes, True)
199 raise TypeError, (cls, cls.getClass())
202 cls = cls.getComponentType()
204 className = cls.getName()
205 if className.split('$', 1)[0] in excludes or className in excludes:
208 if cls.isPrimitive():
215 if split_pkg(className, '.')[0] in packages:
218 cls = cls.getSuperclass()
219 while cls and cls not in typeset:
221 cls = cls.getSuperclass()
227 def addRequiredTypes(cls, typeset, generics):
230 if Class.instance_(cls):
231 cls = Class.cast_(cls)
232 if not (cls.isPrimitive() or cls in typeset):
234 cls = cls.getGenericSuperclass()
236 addRequiredTypes(cls, typeset, True)
237 elif ParameterizedType.instance_(cls):
238 pt = ParameterizedType.cast_(cls)
239 addRequiredTypes(pt.getRawType(), typeset, True)
240 for ta in pt.getActualTypeArguments():
241 addRequiredTypes(ta, typeset, True)
242 elif GenericArrayType.instance_(cls):
243 gat = GenericArrayType.cast_(cls)
244 addRequiredTypes(gat.getGenericComponentType(), typeset, True)
245 elif not (TypeVariable.instance_(cls) or WildcardType.instance_(cls)):
246 raise NotImplementedError, repr(cls)
248 if cls not in typeset:
250 cls = cls.getSuperclass()
252 addRequiredTypes(cls, typeset, False)
255 def find_method(cls, name, params):
261 method = cls.getDeclaredMethod(name, params)
263 method = cls.getMethod(name, params)
266 if (e.getJavaException().getClass().getName() == 'java.lang.NoSuchMethodException'):
270 cls = cls.getSuperclass()
276 modifiers = method.getModifiers()
277 if Modifier.isAbstract(modifiers):
279 if Modifier.isPrivate(modifiers):
285 def signature(fn, argsOnly=False):
291 cls = cls.getComponentType()
292 if cls.isPrimitive():
293 return array + PRIMITIVES[cls.getName()]
294 return '%sL%s;' %(array, cls.getName().replace('.', '/'))
296 if isinstance(fn, Constructor):
298 elif isinstance(fn, Method):
299 returnType = typename(fn.getReturnType())
300 elif isinstance(fn, Field):
301 return typename(fn.getType())
304 return '(%s)' %(''.join([typename(param)
305 for param in fn.getParameterTypes()]))
307 return '(%s)%s' %(''.join([typename(param)
308 for param in fn.getParameterTypes()]),
312 def forward(out, namespace, indent):
314 for name, entries in namespace.iteritems():
316 line(out, indent, 'class %s;', cppname(name))
318 line(out, indent, 'namespace %s {', cppname(name))
319 forward(out, entries, indent + 1)
320 line(out, indent, '}')
325 jar = zipfile.ZipFile(path, 'r')
327 for member in jar.infolist():
329 if f.endswith('.class'):
330 yield f.split('.')[0].replace('/', '.')
338 listedClassNames = set()
341 classpath = [_jcc.CLASSPATH]
343 vmargs = ['-Djava.awt.headless=true']
362 use_distutils = False
368 generics = hasattr(_jcc, "Type")
376 if arg.startswith('-'):
379 classpath.append(args[i])
380 classNames.update(expandjar(args[i]))
382 elif arg == '--include':
384 classpath.append(args[i])
386 elif arg == '--package':
388 packages.add(args[i])
389 elif arg == '--classpath':
391 classpath.append(args[i])
392 elif arg == '--libpath':
394 libpath.append(args[i])
395 elif arg == '--vmarg':
397 vmargs.append(args[i])
398 elif arg == '--python':
399 from python import python, module
402 elif arg == '--module':
404 modules.append(args[i])
405 elif arg == '--build':
406 from python import compile
408 elif arg == '--install':
409 from python import compile
411 elif arg == '--compile':
412 from python import compile
414 elif arg == '--output':
417 elif arg == '--debug':
419 elif arg == '--exclude':
421 excludes.append(args[i])
422 elif arg == '--version':
425 elif arg == '--mapping':
426 mappings[args[i + 1]] = args[i + 2]
428 elif arg == '--sequence':
429 sequences[args[i + 1]] = (args[i + 2], args[i + 3])
431 elif arg == '--rename':
433 renames.update(dict([arg.split('=')
434 for arg in args[i].split(',')]))
435 elif arg == '--files':
437 wrapperFiles = args[i]
438 if wrapperFiles != 'separate':
439 wrapperFiles = int(wrapperFiles)
440 elif arg == '--prefix':
443 elif arg == '--root':
446 elif arg == '--install-dir':
448 install_dir = args[i]
449 elif arg == '--home':
452 elif arg == '--use-distutils':
454 elif arg == '--shared':
456 elif arg == '--bdist':
457 from python import compile
459 elif arg == '--wininst':
460 from python import compile
463 elif arg == '--compiler':
466 elif arg == '--reserved':
468 RESERVED.update(args[i].split(','))
469 elif arg == '--arch':
472 elif arg == '--no-generics':
474 elif arg == '--find-jvm-dll':
476 elif arg == '--resources':
478 resources.append(args[i])
479 elif arg == '--import':
481 imports[args[i]] = ()
483 raise ValueError, "Invalid argument: %s" %(arg)
486 listedClassNames.add(arg)
490 vmargs.append('-Djava.library.path=' + os.pathsep.join(libpath))
492 env = initVM(os.pathsep.join(classpath) or None,
493 maxstack='512k', vmargs=' '.join(vmargs))
496 excludes = set(excludes)
500 imports = dict((__import__(import_), set()) for import_ in imports)
502 raise ValueError, "--shared must be used when using --import"
504 if recompile or not build and (install or dist):
505 if moduleName is None:
506 raise ValueError, 'module name not specified (use --python)'
508 compile(env, os.path.dirname(args[0]), output, moduleName,
509 install, dist, debug, jars, version,
510 prefix, root, install_dir, home_dir, use_distutils,
511 shared, compiler, modules, wininst, find_jvm_dll,
512 arch, generics, resources, imports)
515 def walk((include, importset), dirname, names):
517 if name.endswith('.h'):
518 className = os.path.join(dirname[len(include) + 1:],
520 if os.path.sep != '/':
521 className = className.replace(os.path.sep, '/')
522 importset.add(findClass(className))
523 for import_, importset in imports.iteritems():
524 env._addClassPath(import_.CLASSPATH)
525 include = os.path.join(import_.__dir__, 'include')
526 os.path.walk(include, walk, (include, importset))
527 typeset.update(importset)
528 typeset.add(findClass('java/lang/Object'))
529 typeset.add(findClass('java/lang/Class'))
530 typeset.add(findClass('java/lang/String'))
531 typeset.add(findClass('java/lang/Throwable'))
532 typeset.add(findClass('java/lang/Exception'))
533 typeset.add(findClass('java/lang/RuntimeException'))
535 typeset.add(findClass('java/lang/Number'))
536 typeset.add(findClass('java/lang/Boolean'))
537 typeset.add(findClass('java/lang/Byte'))
538 typeset.add(findClass('java/lang/Character'))
539 typeset.add(findClass('java/lang/Double'))
540 typeset.add(findClass('java/lang/Float'))
541 typeset.add(findClass('java/lang/Integer'))
542 typeset.add(findClass('java/lang/Long'))
543 typeset.add(findClass('java/lang/Short'))
544 typeset.add(findClass('java/util/Iterator'))
545 typeset.add(findClass('java/util/Enumeration'))
546 typeset.add(findClass('java/io/StringWriter'))
547 typeset.add(findClass('java/io/PrintWriter'))
548 typeset.add(findClass('java/io/Writer'))
549 packages.add('java.lang')
551 for className in classNames:
552 if className.split('$', 1)[0] in excludes or className in excludes:
554 cls = findClass(className.replace('.', '/'))
555 if (Modifier.isPublic(cls.getModifiers()) or
556 className in listedClassNames):
557 addRequiredTypes(cls, typeset, generics)
561 cppdir = os.path.join(output, '_%s' %(moduleName))
562 if shared and sys.platform == 'win32':
563 _dll_export = "_dll_%s " %(moduleName)
567 allInOne = wrapperFiles != 'separate'
569 if not os.path.isdir(cppdir):
571 if wrapperFiles <= 1:
572 out_cpp = file(os.path.join(cppdir, '__wrap__.cpp'), 'w')
575 fileName = '__wrap%02d__.cpp' %(fileCount)
576 out_cpp = file(os.path.join(cppdir, fileName), 'w')
579 for importset in imports.itervalues():
580 done.update(importset)
582 todo = typeset - done
583 if allInOne and wrapperFiles > 1:
584 classesPerFile = max(1, len(todo) / wrapperFiles)
589 className = cls.getName()
590 names = className.split('.')
591 dir = os.path.join(cppdir, *names[:-1])
592 if not os.path.isdir(dir):
595 fileName = os.path.join(dir, names[-1])
596 out_h = file(fileName + '.h', "w")
597 line(out_h, 0, '#ifndef %s_H', '_'.join(names))
598 line(out_h, 0, '#define %s_H', '_'.join(names))
600 (superCls, constructors, methods, protectedMethods,
601 fields, instanceFields, declares) = \
602 header(env, out_h, cls, typeset, packages, excludes,
603 generics, _dll_export)
606 out_cpp = file(fileName + '.cpp', 'w')
607 names, superNames = code(env, out_cpp,
608 cls, superCls, constructors,
609 methods, protectedMethods,
610 fields, instanceFields,
613 python(env, out_h, out_cpp,
614 cls, superCls, names, superNames,
615 constructors, methods, protectedMethods,
616 fields, instanceFields,
617 mappings.get(className), sequences.get(className),
618 renames.get(className),
619 declares, typeset, moduleName, generics,
623 line(out_h, 0, '#endif')
628 elif wrapperFiles > 1:
629 if classCount >= classesPerFile:
632 fileName = '__wrap%02d__.cpp' %(fileCount)
633 out_cpp = file(os.path.join(cppdir, fileName), 'w')
637 todo = typeset - done
643 out = file(os.path.join(cppdir, moduleName) + '.cpp', 'w')
644 module(out, allInOne, done, imports, cppdir, moduleName,
647 if build or install or dist:
648 compile(env, os.path.dirname(args[0]), output, moduleName,
649 install, dist, debug, jars, version,
650 prefix, root, install_dir, home_dir, use_distutils,
651 shared, compiler, modules, wininst, find_jvm_dll,
652 arch, generics, resources, imports)
655 def header(env, out, cls, typeset, packages, excludes, generics, _dll_export):
657 names = cls.getName().split('.')
658 superCls = cls.getSuperclass()
659 declares = set([cls.getClass()])
663 for interface in cls.getGenericInterfaces():
664 if Class.instance_(interface):
666 interface = Class.cast_(interface)
667 elif ParameterizedType.instance_(interface):
668 pt = ParameterizedType.cast_(interface)
669 interface = Class.cast_(pt.getRawType())
671 raise NotImplementedError, repr(interface)
672 if superCls and interface.isAssignableFrom(superCls):
674 if known(interface, typeset, declares, packages, excludes, False):
675 interfaces.append(interface)
677 for ta in pt.getActualTypeArguments():
678 addRequiredTypes(ta, typeset, True)
680 for interface in cls.getInterfaces():
681 if superCls and interface.isAssignableFrom(superCls):
683 if known(interface, typeset, declares, packages, excludes, False):
684 interfaces.append(interface)
686 if cls.isInterface():
688 superCls = interfaces.pop(0)
690 superCls = findClass('java/lang/Object')
691 superClsName = superCls.getName()
693 superClsName = superCls.getName()
695 superClsName = 'JObject'
698 for constructor in cls.getDeclaredConstructors():
699 if Modifier.isPublic(constructor.getModifiers()):
701 genericParams = constructor.getGenericParameterTypes()
702 params = constructor.getParameterTypes()
703 # It appears that the implicit instance-of-the-declaring-class
704 # parameter of a non-static inner class is missing from
705 # getGenericParameterTypes()
706 if len(params) == len(genericParams) + 1:
707 params[1:] = genericParams
709 params = genericParams
713 if ParameterizedType.instance_(params[0]):
714 param = ParameterizedType.cast_(params[0])
715 if param.getRawType() == cls:
718 params = constructor.getParameterTypes()
719 if len(params) == 1 and params[0] == cls:
722 if not known(param, typeset, declares, packages, excludes,
726 constructors.append(constructor)
727 sort(constructors, key=lambda x: len(x.getParameterTypes()))
730 protectedMethods = []
731 for method in cls.getDeclaredMethods():
732 modifiers = method.getModifiers()
733 if Modifier.isPublic(modifiers):
735 returnType = method.getGenericReturnType()
737 returnType = method.getReturnType()
738 if not known(returnType, typeset, declares, packages, excludes,
741 sig = "%s:%s" %(method.getName(), signature(method, True))
742 if sig in methods and returnType != cls:
745 params = method.getGenericParameterTypes()
747 params = method.getParameterTypes()
749 if not known(param, typeset, declares, packages, excludes,
753 methods[sig] = method
754 elif Modifier.isProtected(modifiers):
755 protectedMethods.append(method)
757 def _compare(m0, m1):
758 value = cmp(m0.getName(), m1.getName())
760 value = len(m0.getParameterTypes()) - len(m1.getParameterTypes())
763 methods = methods.values()
764 sort(methods, fn=_compare)
766 for constructor in constructors:
768 exceptions = constructor.getGenericExceptionTypes()
770 exceptions = constructor.getExceptionTypes()
771 for exception in exceptions:
772 known(exception, typeset, declares, packages, excludes, generics)
773 for method in methods:
775 exceptions = method.getGenericExceptionTypes()
777 exceptions = method.getExceptionTypes()
778 for exception in exceptions:
779 known(exception, typeset, declares, packages, excludes, generics)
783 for field in cls.getDeclaredFields():
784 modifiers = field.getModifiers()
785 if Modifier.isPublic(modifiers):
787 fieldType = field.getGenericType()
789 fieldType = field.getType()
790 if not known(fieldType, typeset, declares, packages, excludes,
793 if Modifier.isStatic(modifiers):
796 instanceFields.append(field)
797 sort(fields, key=lambda x: x.getName())
798 sort(instanceFields, key=lambda x: x.getName())
801 superNames = superClsName.split('.')
802 line(out, 0, '#include "%s.h"', '/'.join(superNames))
806 for declare in declares:
807 namespace = namespaces
808 if declare not in (cls, superCls):
809 declareNames = declare.getName().split('.')
810 for declareName in declareNames[:-1]:
811 namespace = namespace.setdefault(declareName, {})
812 namespace[declareNames[-1]] = True
813 forward(out, namespaces, 0)
814 line(out, 0, 'template<class T> class JArray;')
818 for name in names[:-1]:
819 line(out, indent, 'namespace %s {', cppname(name))
823 if superClsName == 'JObject':
824 line(out, indent, 'class %s%s : public JObject {',
825 _dll_export, cppname(names[-1]))
827 line(out, indent, 'class %s%s : public %s {',
828 _dll_export, cppname(names[-1]), absname(cppnames(superNames)))
830 line(out, indent, 'public:')
833 if methods or protectedMethods or constructors:
834 line(out, indent, 'enum {')
835 for constructor in constructors:
836 line(out, indent + 1, 'mid_init$_%s,',
837 env.strhash(signature(constructor)))
838 for method in methods:
839 line(out, indent + 1, 'mid_%s_%s,', method.getName(),
840 env.strhash(signature(method)))
841 for method in protectedMethods:
842 line(out, indent + 1, 'mid_%s_%s,', method.getName(),
843 env.strhash(signature(method)))
844 line(out, indent + 1, 'max_mid')
845 line(out, indent, '};')
849 line(out, indent, 'enum {')
850 for field in instanceFields:
851 line(out, indent + 1, 'fid_%s,', field.getName())
852 line(out, indent + 1, 'max_fid')
853 line(out, indent, '};')
856 line(out, indent, 'static ::java::lang::Class *class$;');
857 line(out, indent, 'static jmethodID *mids$;');
859 line(out, indent, 'static jfieldID *fids$;');
860 line(out, indent, 'static jclass initializeClass();');
863 line(out, indent, 'explicit %s(jobject obj) : %s(obj) {',
864 cppname(names[-1]), absname(cppnames(superNames)))
865 line(out, indent + 1, 'if (obj != NULL)');
866 line(out, indent + 2, 'initializeClass();')
867 line(out, indent, '}')
868 line(out, indent, '%s(const %s& obj) : %s(obj) {}',
869 cppname(names[-1]), cppname(names[-1]),
870 absname(cppnames(superNames)))
875 fieldType = field.getType()
876 fieldName = cppname(field.getName())
877 if fieldType.isPrimitive():
878 line(out, indent, 'static %s %s;',
879 typename(fieldType, cls, False), fieldName)
881 line(out, indent, 'static %s *%s;',
882 typename(fieldType, cls, False), fieldName)
886 for field in instanceFields:
887 fieldType = field.getType()
888 fieldName = field.getName()
889 modifiers = field.getModifiers()
890 line(out, indent, '%s _get_%s() const;',
891 typename(fieldType, cls, False), fieldName)
892 if not Modifier.isFinal(modifiers):
893 line(out, indent, 'void _set_%s(%s) const;',
894 fieldName, typename(fieldType, cls, True))
898 for constructor in constructors:
899 params = [typename(param, cls, True)
900 for param in constructor.getParameterTypes()]
901 line(out, indent, '%s(%s);', cppname(names[-1]), ', '.join(params))
905 for method in methods:
906 modifiers = method.getModifiers()
907 if Modifier.isStatic(modifiers):
913 params = [typename(param, cls, True)
914 for param in method.getParameterTypes()]
915 methodName = cppname(method.getName())
916 line(out, indent, '%s%s %s(%s)%s;',
917 prefix, typename(method.getReturnType(), cls, False),
918 methodName, ', '.join(params), const)
921 line(out, indent, '};')
925 line(out, indent, '}')
927 return (superCls, constructors, methods, protectedMethods,
928 fields, instanceFields, declares)
931 def code(env, out, cls, superCls, constructors, methods, protectedMethods,
932 fields, instanceFields, declares, typeset):
934 className = cls.getName()
935 names = className.split('.')
938 superClsName = superCls.getName()
940 superClsName = 'JObject'
941 superNames = superClsName.split('.')
943 line(out, 0, '#include <jni.h>')
944 line(out, 0, '#include "JCCEnv.h"')
945 line(out, 0, '#include "%s.h"', className.replace('.', '/'))
946 for declare in declares:
947 if declare not in (cls, superCls):
948 line(out, 0, '#include "%s.h"', declare.getName().replace('.', '/'))
949 line(out, 0, '#include "JArray.h"')
953 for name in names[:-1]:
954 line(out, indent, 'namespace %s {', cppname(name))
958 line(out, indent, '::java::lang::Class *%s::class$ = NULL;',
960 line(out, indent, 'jmethodID *%s::mids$ = NULL;', cppname(names[-1]))
962 line(out, indent, 'jfieldID *%s::fids$ = NULL;', cppname(names[-1]))
965 fieldType = field.getType()
966 fieldName = cppname(field.getName())
967 typeName = typename(fieldType, cls, False)
968 if fieldType.isPrimitive():
969 line(out, indent, '%s %s::%s = (%s) 0;',
970 typeName, cppname(names[-1]), fieldName, typeName)
972 line(out, indent, '%s *%s::%s = NULL;',
973 typeName, cppname(names[-1]), fieldName)
976 line(out, indent, 'jclass %s::initializeClass()', cppname(names[-1]))
977 line(out, indent, '{')
978 line(out, indent + 1, 'if (!class$)')
979 line(out, indent + 1, '{')
981 line(out, indent + 2, 'jclass cls = (jclass) env->findClass("%s");',
982 className.replace('.', '/'))
984 if methods or protectedMethods or constructors:
986 line(out, indent + 2, 'mids$ = new jmethodID[max_mid];')
987 for constructor in constructors:
988 sig = signature(constructor)
989 line(out, indent + 2,
990 'mids$[mid_init$_%s] = env->getMethodID(cls, "<init>", "%s");',
991 env.strhash(sig), sig)
993 for method in methods:
994 methodName = method.getName()
995 if methodName == 'pythonExtension':
997 sig = signature(method)
998 line(out, indent + 2,
999 'mids$[mid_%s_%s] = env->get%sMethodID(cls, "%s", "%s");',
1000 methodName, env.strhash(sig),
1001 Modifier.isStatic(method.getModifiers()) and 'Static' or '',
1003 for method in protectedMethods:
1004 methodName = method.getName()
1005 sig = signature(method)
1006 line(out, indent + 2,
1007 'mids$[mid_%s_%s] = env->get%sMethodID(cls, "%s", "%s");',
1008 methodName, env.strhash(sig),
1009 Modifier.isStatic(method.getModifiers()) and 'Static' or '',
1014 line(out, indent + 2, 'fids$ = new jfieldID[max_fid];')
1015 for field in instanceFields:
1016 fieldName = field.getName()
1017 line(out, indent + 2,
1018 'fids$[fid_%s] = env->getFieldID(cls, "%s", "%s");',
1019 fieldName, fieldName, signature(field))
1022 line(out, indent + 2, 'class$ = (::java::lang::Class *) new JObject(cls);')
1025 line(out, indent + 2, 'cls = (jclass) class$->this$;')
1027 for field in fields:
1028 fieldType = field.getType()
1029 fieldName = field.getName()
1030 if fieldType.isPrimitive():
1031 line(out, indent + 2,
1032 '%s = env->getStatic%sField(cls, "%s");',
1033 cppname(fieldName), fieldType.getName().capitalize(),
1036 line(out, indent + 2,
1037 '%s = new %s(env->getStaticObjectField(cls, "%s", "%s"));',
1038 cppname(fieldName), typename(fieldType, cls, False),
1039 fieldName, signature(field))
1041 line(out, indent + 1, '}')
1042 line(out, indent + 1, 'return (jclass) class$->this$;')
1043 line(out, indent, '}')
1045 for constructor in constructors:
1047 sig = signature(constructor)
1048 decls, args = argnames(constructor.getParameterTypes(), cls)
1050 line(out, indent, "%s::%s(%s) : %s(env->newObject(initializeClass, &mids$, mid_init$_%s%s)) {}",
1051 cppname(names[-1]), cppname(names[-1]), decls,
1052 absname(cppnames(superNames)),
1053 env.strhash(sig), args)
1055 for method in methods:
1056 modifiers = method.getModifiers()
1057 returnType = method.getReturnType()
1058 params = method.getParameterTypes()
1059 methodName = method.getName()
1061 isStatic = Modifier.isStatic(modifiers)
1063 if (isExtension and not isStatic and superCls and
1064 Modifier.isNative(modifiers)):
1065 superMethod = find_method(superCls, methodName, params)
1066 if superMethod is None:
1070 qualifier = 'Static'
1076 if superMethod is not None:
1077 qualifier = 'Nonvirtual'
1078 this = 'this$, (jclass) %s::class$->this$' %(absname(cppnames(superNames)))
1079 declaringClass = superMethod.getDeclaringClass()
1080 midns = '%s::' %(typename(declaringClass, cls, False))
1087 sig = signature(method)
1088 decls, args = argnames(params, cls)
1091 line(out, indent, '%s %s::%s(%s)%s',
1092 typename(returnType, cls, False), cppname(names[-1]),
1093 cppname(methodName), decls, const)
1094 line(out, indent, '{')
1096 line(out, indent + 1, 'jclass cls = initializeClass();');
1097 if returnType.isPrimitive():
1098 line(out, indent + 1,
1099 '%senv->call%s%sMethod(%s, %smids$[%smid_%s_%s]%s);',
1100 not returnType.getName() == 'void' and 'return ' or '',
1101 qualifier, returnType.getName().capitalize(), this,
1102 midns, midns, methodName, env.strhash(sig), args)
1104 line(out, indent + 1,
1105 'return %s(env->call%sObjectMethod(%s, %smids$[%smid_%s_%s]%s));',
1106 typename(returnType, cls, False), qualifier, this,
1107 midns, midns, methodName, env.strhash(sig), args)
1108 line(out, indent, '}')
1111 for field in instanceFields:
1112 fieldType = field.getType()
1113 fieldName = field.getName()
1115 line(out, indent, '%s %s::_get_%s() const',
1116 typename(fieldType, cls, False), cppname(names[-1]), fieldName)
1117 line(out, indent, '{')
1118 if fieldType.isPrimitive():
1119 line(out, indent + 1,
1120 'return env->get%sField(this$, fids$[fid_%s]);',
1121 fieldType.getName().capitalize(), fieldName)
1123 line(out, indent + 1,
1124 'return %s(env->getObjectField(this$, fids$[fid_%s]));',
1125 typename(fieldType, cls, False), fieldName)
1126 line(out, indent, '}')
1128 if not Modifier.isFinal(field.getModifiers()):
1130 line(out, indent, 'void %s::_set_%s(%s a0) const',
1131 cppname(names[-1]), fieldName,
1132 typename(fieldType, cls, True))
1133 line(out, indent, '{')
1134 if fieldType.isPrimitive():
1135 line(out, indent + 1,
1136 'env->set%sField(this$, fids$[fid_%s], a0);',
1137 fieldType.getName().capitalize(), fieldName)
1139 line(out, indent + 1,
1140 'env->setObjectField(this$, fids$[fid_%s], a0.this$);',
1142 line(out, indent, '}')
1146 line(out, indent, '}')
1148 return names, superNames
1151 if __name__ == '__main__':