2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
15 import os, sys, platform, shutil, _jcc
16 from itertools import izip
18 from cpp import PRIMITIVES, INDENT, HALF_INDENT
19 from cpp import cppname, cppnames, absname, typename, findClass
20 from cpp import line, signature, find_method, split_pkg, sort
21 from cpp import Modifier, Class, Method
22 from config import INCLUDES, CFLAGS, DEBUG_CFLAGS, LFLAGS, IMPLIB_LFLAGS, \
23 SHARED, VERSION as JCC_VER
26 from cpp import ParameterizedType, TypeVariable
30 python_ver = '%d.%d.%d' %(sys.version_info[0:3])
31 if python_ver < '2.4':
32 from sets import Set as set
35 RESULTS = { 'boolean': 'Py_RETURN_BOOL(%s);',
36 'byte': 'return PyInt_FromLong((long) %s);',
37 'char': 'return PyUnicode_FromUnicode((Py_UNICODE *) &%s, 1);',
38 'double': 'return PyFloat_FromDouble((double) %s);',
39 'float': 'return PyFloat_FromDouble((double) %s);',
40 'int': 'return PyInt_FromLong((long) %s);',
41 'long': 'return PyLong_FromLongLong((PY_LONG_LONG) %s);',
42 'short': 'return PyInt_FromLong((long) %s);',
43 'java.lang.String': 'return j2p(%s);' }
45 CALLARGS = { 'boolean': ('O', '(%s ? Py_True : Py_False)', False),
46 'byte': ('O', 'PyInt_FromLong(%s)', True),
47 'char': ('O', 'PyUnicode_FromUnicode((Py_UNICODE *) &%s, 1)', True),
48 'double': ('d', '(double) %s', False),
49 'float': ('f', '(float) %s', False),
50 'int': ('i', '(int) %s', False),
51 'long': ('L', '(long long) %s', False),
52 'short': ('i', '(int) %s', False),
53 'java.lang.String': ('O', 'env->fromJString((jstring) %s, 0)', True) }
55 BOXED = { 'java.lang.Boolean': (True, True),
56 'java.lang.Byte': (True, True),
57 'java.lang.Character': (True, True),
58 'java.lang.CharSequence': (True, False),
59 'java.lang.Double': (True, True),
60 'java.lang.Float': (True, True),
61 'java.lang.Integer': (True, True),
62 'java.lang.Long': (True, True),
63 'java.lang.Number': (True, False),
64 'java.lang.Short': (True, True),
65 'java.lang.String': (True, True) }
68 def is_boxed(clsName):
69 return BOXED.get(clsName, (False, False))[0]
71 def is_unboxed(clsName):
72 return BOXED.get(clsName, (False, False))[1]
75 def getTypeParameters(cls):
78 parameters = cls.getTypeParameters()
81 cls = cls.getDeclaringClass()
86 def getActualTypeArguments(pt):
89 arguments = pt.getActualTypeArguments()
92 pt = pt.getOwnerType()
93 if pt is None or not ParameterizedType.instance_(pt):
95 pt = ParameterizedType.cast_(pt)
98 def parseArgs(params, current, generics, genericParams=None):
100 def signature(cls, genericPT=None):
101 if generics and TypeVariable.instance_(genericPT):
102 if cls.getName() == 'java.lang.Object':
103 gd = TypeVariable.cast_(genericPT).getGenericDeclaration()
105 for clsParam in getTypeParameters(gd):
106 if genericPT == clsParam:
111 cls = cls.getComponentType()
112 clsName = cls.getName()
113 if cls.isPrimitive():
114 return array + PRIMITIVES[clsName]
115 if clsName == 'java.lang.String':
117 if clsName == 'java.lang.Object':
119 if is_boxed(clsName):
121 if generics and getTypeParameters(cls):
126 def checkarg(cls, genericPT=None):
127 if generics and TypeVariable.instance_(genericPT):
128 if cls.getName() == 'java.lang.Object':
129 gd = TypeVariable.cast_(genericPT).getGenericDeclaration()
132 for clsParam in getTypeParameters(gd):
133 if genericPT == clsParam:
134 return ', self->parameters[%d]' %(i)
137 cls = cls.getComponentType()
138 clsName = cls.getName()
139 if (cls.isPrimitive() or
140 clsName in ('java.lang.String', 'java.lang.Object')):
142 if is_boxed(clsName):
143 clsNames = clsName.split('.')
144 return ', &%s::PY_TYPE(%s)' %(absname(cppnames(clsNames[:-1])), cppname(clsNames[-1]))
145 return ', %s::initializeClass' %(typename(cls, current, False))
150 cls = cls.getComponentType()
151 if getTypeParameters(cls):
152 ns, sep, n = rpartition(typename(cls, current, False), '::')
153 return ', &a%d, &p%d, %s%st_%s::parameters_' %(i, i, ns, sep, n)
157 sig = ''.join([signature(param, genericParam)
158 for param, genericParam in izip(params, genericParams)])
159 chk = ''.join([checkarg(param, genericParam)
160 for param, genericParam in izip(params, genericParams)])
162 sig = ''.join([signature(param) for param in params])
163 chk = ''.join([checkarg(param) for param in params])
166 ''.join([callarg(params[i], i) for i in xrange(len(params))]))
169 def declareVars(out, indent, params, current, generics, typeParams):
171 for i in xrange(len(params)):
173 line(out, indent, '%s a%d%s;',
174 typename(param, current, False), i,
175 not param.isPrimitive() and '((jobject) NULL)' or '')
177 while param.isArray():
178 param = param.getComponentType()
179 if getTypeParameters(param):
180 line(out, indent, 'PyTypeObject **p%d;', i)
184 def construct(out, indent, cls, inCase, constructor, names, generics):
187 line(out, indent, '{')
190 params = constructor.getParameterTypes()
198 declareVars(out, indent, params, cls, generics, typeParams)
199 line(out, indent, '%s object((jobject) NULL);', cppname(names[-1]))
203 line(out, indent, 'if (!parseArgs(args, "%s"%s%s))',
204 *parseArgs(params, cls, generics))
205 line(out, indent, '{')
208 line(out, indent, 'INT_CALL(object = %s(%s));',
209 cppname(names[-1]), ', '.join(['a%d' %(i) for i in xrange(count)]))
210 line(out, indent, 'self->object = object;')
212 line(out, indent, 'break;')
216 line(out, indent, '}')
220 line(out, indent, '}')
223 def rpartition(string, sep):
225 if python_ver >= '2.5.0':
226 return string.rpartition(sep)
228 parts = split_pkg(string, sep)
230 return ('', '', parts[0])
231 return (parts[0], sep, parts[1])
234 def fieldValue(cls, value, fieldType):
236 if fieldType.isArray():
237 fieldType = fieldType.getComponentType()
238 if fieldType.isArray():
239 result = 'JArray<jobject>(%s->this$).wrap(NULL)'
240 elif fieldType.isPrimitive():
241 result = '%s->wrap()'
242 elif fieldType.getName() == 'java.lang.String':
243 result = 'JArray<jstring>(%s->this$).wrap()'
245 parts = rpartition(typename(fieldType, cls, False), '::')
246 result = 'JArray<jobject>(%%s->this$).wrap(%s%st_%s::wrap_jobject)' %(parts)
248 elif fieldType.getName() == 'java.lang.String':
251 elif not fieldType.isPrimitive():
252 parts = rpartition(typename(fieldType, cls, False), '::')
253 result = '%s%st_%s::wrap_Object(*%%s)' %(parts)
258 return result %(value)
261 def returnValue(cls, returnType, value, genericRT=None, typeParams=None):
263 result = RESULTS.get(returnType.getName())
265 return result %(value)
267 if returnType.isArray():
268 returnType = returnType.getComponentType()
270 while returnType.isArray():
271 returnType = returnType.getComponentType()
274 return 'return JArray<jobject>(%s.this$).wrap(NULL);' %(value)
275 elif returnType.isPrimitive():
276 return 'return %s.wrap();' %(value)
277 elif returnType.getName() == 'java.lang.String':
278 return 'return JArray<jstring>(%s.this$).wrap();' %(value)
280 ns, sep, n = rpartition(typename(returnType, cls, False), '::')
281 return 'return JArray<jobject>(%s.this$).wrap(%s%st_%s::wrap_jobject);' %(value, ns, sep, n)
283 ns, sep, n = rpartition(typename(returnType, cls, False), '::')
284 if genericRT is not None:
285 if ParameterizedType.instance_(genericRT):
286 genericRT = ParameterizedType.cast_(genericRT)
288 for clsArg in getActualTypeArguments(genericRT):
289 if Class.instance_(clsArg):
290 clsNames = Class.cast_(clsArg).getName().split('.')
291 clsArg = '&%s::PY_TYPE(%s)' %(absname(cppnames(clsNames[:-1])), cppname(clsNames[-1]))
292 clsArgs.append(clsArg)
293 elif TypeVariable.instance_(clsArg):
294 gd = TypeVariable.cast_(clsArg).getGenericDeclaration()
295 if Class.instance_(gd):
297 for clsParam in getTypeParameters(gd):
298 if clsArg == clsParam:
299 clsArgs.append('self->parameters[%d]' %(i))
309 return 'return %s%st_%s::wrap_Object(%s, %s);' %(ns, sep, n, value, ', '.join(clsArgs))
311 elif TypeVariable.instance_(genericRT):
312 gd = TypeVariable.cast_(genericRT).getGenericDeclaration()
314 if Class.instance_(gd):
315 for clsParam in getTypeParameters(gd):
316 if genericRT == clsParam:
317 return 'return self->parameters[%d] != NULL ? wrapType(self->parameters[%d], %s.this$) : %s%st_%s::wrap_Object(%s);' %(i, i, value, ns, sep, n, value)
319 elif Method.instance_(gd):
320 for clsParam in getTypeParameters(gd):
321 if genericRT == clsParam and i in typeParams:
322 return 'return p%d != NULL && p%d[0] != NULL ? wrapType(p%d[0], %s.this$) : %s%st_%s::wrap_Object(%s);' %(i, i, i, value, ns, sep, n, value)
325 return 'return %s%st_%s::wrap_Object(%s);' %(ns, sep, n, value)
328 def call(out, indent, cls, inCase, method, names, cardinality, isExtension,
332 line(out, indent, '{')
335 name = method.getName()
336 modifiers = method.getModifiers()
337 params = method.getParameterTypes()
338 returnType = method.getReturnType()
340 genericRT = method.getGenericReturnType()
341 genericParams = method.getGenericParameterTypes()
349 declareVars(out, indent, params, cls, generics, typeParams)
351 returnName = returnType.getName()
352 if returnName != 'void':
353 line(out, indent, '%s result%s;',
354 typename(returnType, cls, False),
355 not returnType.isPrimitive() and '((jobject) NULL)' or '')
360 if cardinality and (count or not inCase):
361 s = cardinality > 1 and 's' or ''
363 if isExtension and name == 'clone' and Modifier.isNative(modifiers):
364 line(out, indent, 'if (arg)')
366 line(out, indent, 'if (!parseArg%s(arg%s, "%s"%s%s))',
367 s, s, *parseArgs(params, cls, generics, genericParams))
368 line(out, indent, '{')
372 if Modifier.isStatic(modifiers):
373 line(out, indent, 'OBJ_CALL(%s%s::%s(%s));',
374 result, absname(cppnames(names)), name,
375 ', '.join(['a%d' %(i) for i in xrange(count)]))
377 line(out, indent, 'OBJ_CALL(%sself->object.%s(%s));',
378 result, name, ', '.join(['a%d' %(i) for i in xrange(count)]))
380 if isExtension and name == 'clone' and Modifier.isNative(modifiers):
382 line(out, indent, '%s object(result.this$);', typename(cls, cls, False))
383 line(out, indent, 'if (PyObject_TypeCheck(arg, &PY_TYPE(FinalizerProxy)) &&')
384 line(out, indent, ' PyObject_TypeCheck(((t_fp *) arg)->object, self->ob_type))')
385 line(out, indent, '{')
386 line(out, indent + 1, 'PyObject *_arg = ((t_fp *) arg)->object;')
387 line(out, indent + 1, '((t_JObject *) _arg)->object = object;')
388 line(out, indent + 1, 'Py_INCREF(_arg);')
389 line(out, indent + 1, 'object.pythonExtension((jlong) (Py_intptr_t) (void *) _arg);')
390 line(out, indent + 1, 'Py_INCREF(arg);')
391 line(out, indent + 1, 'return arg;')
392 line(out, indent, '}')
393 line(out, indent, 'return PyErr_SetArgsError("%s", arg);' %(name))
394 elif returnName != 'void':
395 line(out, indent, returnValue(cls, returnType, 'result',
396 genericRT, typeParams))
398 line(out, indent, 'Py_RETURN_NONE;')
399 if cardinality and (count or not inCase):
401 line(out, indent, '}')
405 line(out, indent, '}')
408 def methodargs(methods, superMethods):
410 if len(methods) == 1 and methods[0].getName() not in superMethods:
411 count = len(methods[0].getParameterTypes())
415 return ', PyObject *arg', ', arg', 1
417 return ', PyObject *args', ', args', 2
422 if cls.isPrimitive():
435 decls = ', '.join(['%s a%d' %(jniname(params[i]), i)
436 for i in xrange(count)])
443 def extension(env, out, indent, cls, names, name, count, method, generics):
445 line(out, indent, 'jlong ptr = jenv->CallLongMethod(jobj, %s::mids$[%s::mid_pythonExtension_%s]);',
446 cppname(names[-1]), cppname(names[-1]), env.strhash('()J'))
447 line(out, indent, 'PyObject *obj = (PyObject *) (Py_intptr_t) ptr;')
449 if name == 'pythonDecRef':
451 line(out, indent, 'if (obj != NULL)')
452 line(out, indent, '{')
453 line(out, indent + 1, 'jenv->CallVoidMethod(jobj, %s::mids$[%s::mid_pythonExtension_%s], (jlong) 0);',
454 cppname(names[-1]), cppname(names[-1]), env.strhash('(J)V'))
455 line(out, indent + 1, 'env->finalizeObject(jenv, obj);')
456 line(out, indent, '}')
459 line(out, indent, 'PythonGIL gil(jenv);')
461 returnType = method.getReturnType()
462 returnName = returnType.getName()
463 if returnName != 'void':
464 line(out, indent, '%s value%s;',
465 typename(returnType, cls, False),
466 not returnType.isPrimitive() and '((jobject) NULL)' or '')
472 for param in method.getParameterTypes():
473 typeName = param.getName()
474 if typeName in CALLARGS:
475 sig, code, decref = CALLARGS[typeName]
476 elif param.isArray():
477 param = param.getComponentType()
478 if param.isPrimitive():
479 code = 'JArray<j%s>(%%s).wrap()' %(param.getName())
480 elif param.isArray():
481 code = 'JArray<jobject>(%s).wrap(NULL)'
482 elif param.getName() == 'java.lang.String':
483 code = 'JArray<jstring>(%s).wrap()'
485 parts = rpartition(typename(param, cls, False), '::')
486 code = 'JArray<jobject>(%%s).wrap(%s%st_%s::wrap_jobject)' %(parts)
487 sig, decref = 'O', True
488 elif param.getName() == 'java.lang.String':
489 sig, code, decref = 'O', 'j2p(%%s))', True
491 parts = rpartition(typename(param, cls, False), '::')
492 sig, code, decref = 'O', '%s%st_%s::wrap_Object(%s%s%s(%%s))' %(parts*2), True
494 line(out, indent, 'PyObject *o%d = %s;', i, code %('a%d' %(i)))
495 args.append('o%d' %(i))
497 args.append(code %('a%d' %(i)))
499 decrefs.append(decref)
502 args = ', '.join(args)
505 line(out, indent, 'PyObject *result = PyObject_CallMethod(obj, "%s", "%s"%s);',
506 name, ''.join(sigs), args)
508 for decref in decrefs:
510 line(out, indent, 'Py_DECREF(o%d);', i)
512 line(out, indent, 'if (!result)')
513 line(out, indent + 1, 'throwPythonError();')
514 if returnName == 'void':
515 line(out, indent, 'else')
516 line(out, indent + 1, 'Py_DECREF(result);')
518 signature, check, x = parseArgs([returnType], cls, False)
519 line(out, indent, 'else if (parseArg(result, "%s"%s, &value))',
521 line(out, indent, '{')
522 line(out, indent + 1, 'throwTypeError("%s", result);', name)
523 line(out, indent + 1, 'Py_DECREF(result);')
524 line(out, indent, '}')
525 line(out, indent, 'else')
526 line(out, indent, '{')
527 if not returnType.isPrimitive():
528 line(out, indent + 1, 'jobj = jenv->NewLocalRef(value.this$);')
529 line(out, indent + 1, 'Py_DECREF(result);')
530 if returnType.isPrimitive():
531 line(out, indent + 1, 'return value;')
533 line(out, indent + 1, 'return jobj;')
534 line(out, indent, '}')
536 if returnType.isPrimitive():
537 line(out, indent, 'return (j%s) 0;', returnName)
539 line(out, indent, 'return (jobject) NULL;')
542 def python(env, out_h, out, cls, superCls, names, superNames,
543 constructors, methods, protectedMethods, fields, instanceFields,
544 mapping, sequence, rename, declares, typeset, moduleName, generics,
548 line(out_h, 0, '#include <Python.h>')
552 for name in names[:-1]:
553 line(out_h, indent, 'namespace %s {', cppname(name))
555 line(out_h, indent, '%sextern PyTypeObject PY_TYPE(%s);',
556 _dll_export, names[-1])
559 clsParams = getTypeParameters(cls)
564 line(out_h, indent, 'class %st_%s {', _dll_export, names[-1])
565 line(out_h, indent, 'public:')
566 line(out_h, indent + 1, 'PyObject_HEAD')
567 line(out_h, indent + 1, '%s object;', cppname(names[-1]))
569 line(out_h, indent + 1, 'PyTypeObject *parameters[%d];', len(clsParams))
570 line(out_h, indent + 1, 'static PyTypeObject **parameters_(t_%s *self)',
572 line(out_h, indent + 1, '{')
573 line(out_h, indent + 2, 'return (PyTypeObject **) &(self->parameters);')
574 line(out_h, indent + 1, '}')
576 line(out_h, indent + 1, 'static PyObject *wrap_Object(const %s&);',
578 line(out_h, indent + 1, 'static PyObject *wrap_jobject(const jobject&);')
580 _clsParams = ', '.join(['PyTypeObject *'] * len(clsParams))
581 line(out_h, indent + 1, 'static PyObject *wrap_Object(const %s&, %s);',
582 cppname(names[-1]), _clsParams)
583 line(out_h, indent + 1, 'static PyObject *wrap_jobject(const jobject&, %s);', _clsParams)
584 line(out_h, indent + 1, 'static void install(PyObject *module);')
585 line(out_h, indent + 1, 'static void initialize(PyObject *module);')
586 line(out_h, indent, '};')
588 if env.java_version >= '1.5':
589 iterable = findClass('java/lang/Iterable')
590 iterator = findClass('java/util/Iterator')
592 iterable = iterator = None
594 enumeration = findClass('java/util/Enumeration')
598 line(out_h, indent, '}')
601 line(out, 0, '#include "structmember.h"')
602 line(out, 0, '#include "functions.h"')
603 line(out, 0, '#include "macros.h"')
605 for inner in cls.getDeclaredClasses():
606 if inner in typeset and not inner in declares:
607 if Modifier.isStatic(inner.getModifiers()):
608 line(out, 0, '#include "%s.h"',
609 inner.getName().replace('.', '/'))
611 for method in methods:
612 if method.getName() == 'pythonExtension':
620 for name in names[:-1]:
621 line(out, indent, 'namespace %s {', cppname(name))
624 line(out, indent, 'static PyObject *t_%s_cast_(PyTypeObject *type, PyObject *arg);', names[-1])
625 line(out, indent, 'static PyObject *t_%s_instance_(PyTypeObject *type, PyObject *arg);', names[-1])
628 'static PyObject *t_%s_of_(t_%s *self, PyObject *args);',
629 names[-1], names[-1])
632 line(out, indent, 'static int t_%s_init_(t_%s *self, PyObject *args, PyObject *kwds);', names[-1], names[-1])
633 constructorName = 't_%s_init_' %(names[-1])
635 constructorName = 'abstract_init'
638 superMethods = set([method.getName()
639 for method in superCls.getMethods()])
648 for method in methods:
649 modifiers = method.getModifiers()
650 name = method.getName()
651 params = method.getParameterTypes()
653 isNative = Modifier.isNative(modifiers)
654 isStatic = Modifier.isStatic(modifiers)
656 if (isExtension and not isStatic and superCls and isNative):
657 superMethod = find_method(superCls, name, params)
659 if isExtension and isNative and not isStatic:
660 extMethods.setdefault(name, []).append(method)
662 if superMethod or not (isExtension and isNative and not isStatic):
664 if name in allMethods:
665 if Modifier.isStatic(allMethods[name][0].getModifiers()):
666 allMethods[name].append(method)
667 elif name + '_' in allMethods:
668 allMethods[name + '_'].append(method)
670 print >>sys.stderr, " Warning: renaming static method '%s' on class %s to '%s_' since it is shadowed by non-static method of same name." %(name, '.'.join(names), name)
671 allMethods[name + '_'] = [method]
673 allMethods[name] = [method]
675 if name in allMethods:
676 if Modifier.isStatic(allMethods[name][0].getModifiers()):
677 print >>sys.stderr, " Warning: renaming static method '%s' on class %s to '%s_' since it is shadowed by non-static method of same name." %(name, '.'.join(names), name)
678 allMethods[name + '_'] = allMethods[name]
679 allMethods[name] = [method]
681 allMethods[name].append(method)
683 allMethods[name] = [method]
685 if not (isExtension and isNative):
687 paramsLen = len(params)
688 if nameLen > 3 and paramsLen == 0 and name.startswith('get'):
689 if method.getReturnType().getName() != 'void':
690 propMethods.setdefault(name[3].lower() + name[4:],
692 elif nameLen > 3 and paramsLen == 1 and name.startswith('set'):
693 propMethods.setdefault(name[3].lower() + name[4:],
695 elif nameLen > 2 and paramsLen == 0 and name.startswith('is'):
696 if method.getReturnType().getName() != 'void':
697 propMethods.setdefault(name[2].lower() + name[3:],
700 properties = set([name for name in propMethods.iterkeys()
701 if name not in allMethods])
702 propMethods = [(name, propMethods[name]) for name in properties]
703 sort(propMethods, key=lambda x: x[0])
705 extMethods = extMethods.items()
706 sort(extMethods, key=lambda x: x[0])
707 allMethods = allMethods.items()
708 sort(allMethods, key=lambda x: x[0])
710 iteratorMethod = None
714 nextElementMethod = None
715 nextElementExt = False
719 mappingName, mappingSig = mapping.split(':')
721 sequenceLenMethod = None
722 sequenceGetMethod = None
724 sequenceLenName, sequenceLenSig = sequence[0].split(':')
725 sequenceGetName, sequenceGetSig = sequence[1].split(':')
727 for name, methods in allMethods:
728 args, x, cardinality = methodargs(methods, superMethods)
729 sort(methods, key=lambda x: len(x.getParameterTypes()))
731 modifiers = method.getModifiers()
732 if name == 'iterator' and iteratorMethod is None:
733 if (iterable is not None and
734 not method.getParameterTypes() and
735 iterable.isAssignableFrom(cls) and
736 iterator.isAssignableFrom(method.getReturnType())):
737 iteratorMethod = method
738 elif name == 'next' and nextMethod is None:
739 if (not method.getParameterTypes() and
740 not method.getReturnType().isPrimitive()):
742 elif name == 'nextElement' and nextElementMethod is None:
743 if (not method.getParameterTypes() and
744 not method.getReturnType().isPrimitive()):
745 nextElementMethod = method
746 elif mapping and name == mappingName and mappingMethod is None:
747 if signature(method) == mappingSig:
748 mappingMethod = (method, cardinality)
749 elif sequence and name == sequenceLenName and sequenceLenMethod is None:
750 if signature(method) == sequenceLenSig:
751 sequenceLenMethod = (method, cardinality)
752 elif sequence and name == sequenceGetName and sequenceGetMethod is None:
753 if signature(method) == sequenceGetSig:
754 sequenceGetMethod = (method, cardinality)
755 elif isExtension and name == 'clone' and Modifier.isNative(modifiers):
756 args, x, cardinality = ', PyObject *arg', ', arg', 1
758 if Modifier.isStatic(modifiers):
759 line(out, indent, 'static PyObject *t_%s_%s(PyTypeObject *type%s);',
760 names[-1], name, args)
762 line(out, indent, 'static PyObject *t_%s_%s(t_%s *self%s);',
763 names[-1], name, names[-1], args)
765 for name, methods in extMethods:
766 args, x, cardinality = methodargs(methods, superMethods)
767 sort(methods, key=lambda x: len(x.getParameterTypes()))
769 modifiers = method.getModifiers()
770 if name == 'iterator' and iteratorMethod is None:
771 if (iterable is not None and
772 not method.getParameterTypes() and
773 iterable.isAssignableFrom(cls) and
774 iterator.isAssignableFrom(method.getReturnType())):
775 iteratorMethod = method
777 elif name == 'next' and nextMethod is None:
778 if (not method.getParameterTypes() and
779 not method.getReturnType().isPrimitive()):
782 elif name == 'nextElement' and nextElementMethod is None:
783 if (not method.getParameterTypes() and
784 not method.getReturnType().isPrimitive()):
785 nextElementMethod = method
786 nextElementExt = True
790 for name, methods in extMethods:
791 for method in methods:
793 'static %s JNICALL t_%s_%s%d(JNIEnv *jenv, jobject jobj%s);',
794 jniname(method.getReturnType()), names[-1], name, count,
795 jniargs(method.getParameterTypes()))
797 line(out, indent, 'static PyObject *t_%s_get__self(t_%s *self, void *data);', names[-1], names[-1])
800 for field in instanceFields:
801 fieldName = field.getName()
802 if fieldName not in properties:
803 line(out, indent, 'static PyObject *t_%s_get__%s(t_%s *self, void *data);',
804 names[-1], fieldName, names[-1])
805 if not Modifier.isFinal(field.getModifiers()):
806 line(out, indent, 'static int t_%s_set__%s(t_%s *self, PyObject *arg, void *data);',
807 names[-1], field.getName(), names[-1])
810 for fieldName, methods in propMethods:
813 for method in methods:
814 methodName = method.getName()
815 if not getter and (methodName.startswith('get') or
816 methodName.startswith('is')):
818 line(out, indent, 'static PyObject *t_%s_get__%s(t_%s *self, void *data);',
819 names[-1], fieldName, names[-1])
820 elif not setter and methodName.startswith('set'):
822 line(out, indent, 'static int t_%s_set__%s(t_%s *self, PyObject *arg, void *data);',
823 names[-1], fieldName, names[-1])
825 line(out, indent, 'static PyObject *t_%s_get__parameters_(t_%s *self, void *data);', names[-1], names[-1])
827 if instanceFields or propMethods or isExtension or clsParams:
828 line(out, indent, 'static PyGetSetDef t_%s__fields_[] = {', names[-1])
829 for field in instanceFields:
830 fieldName = field.getName()
831 if fieldName not in properties:
832 if Modifier.isFinal(field.getModifiers()):
833 line(out, indent + 1, 'DECLARE_GET_FIELD(t_%s, %s),',
834 names[-1], fieldName)
836 line(out, indent + 1, 'DECLARE_GETSET_FIELD(t_%s, %s),',
837 names[-1], fieldName)
838 for fieldName, methods in propMethods:
841 for method in methods:
842 methodName = method.getName()
843 if not getter and (methodName.startswith('get') or
844 methodName.startswith('is')):
846 elif not setter and methodName.startswith('set'):
848 if getter and setter:
854 line(out, indent + 1, 'DECLARE_%s_FIELD(t_%s, %s),',
855 op, names[-1], fieldName)
857 line(out, indent + 1, 'DECLARE_GET_FIELD(t_%s, self),', names[-1])
859 line(out, indent + 1, 'DECLARE_GET_FIELD(t_%s, parameters_),',
862 line(out, indent + 1, '{ NULL, NULL, NULL, NULL, NULL }')
863 line(out, indent, '};')
866 line(out, indent, 'static PyMethodDef t_%s__methods_[] = {', names[-1])
868 line(out, indent + 1,
869 'DECLARE_METHOD(t_%s, cast_, METH_O | METH_CLASS),', names[-1])
870 line(out, indent + 1,
871 'DECLARE_METHOD(t_%s, instance_, METH_O | METH_CLASS),', names[-1])
873 line(out, indent + 1,
874 'DECLARE_METHOD(t_%s, of_, METH_VARARGS),', names[-1])
876 for name, methods in allMethods:
877 modifiers = methods[0].getModifiers()
878 if len(methods) == 1 and not name in superMethods:
879 count = len(methods[0].getParameterTypes())
885 args = 'METH_VARARGS'
886 elif isExtension and name == 'clone' and Modifier.isNative(modifiers):
889 args = 'METH_VARARGS'
890 if Modifier.isStatic(modifiers):
891 args += ' | METH_CLASS'
893 line(out, indent + 1, 'DECLARE_METHOD(t_%s, %s, %s),',
894 names[-1], name, args)
895 line(out, indent + 1, '{ NULL, NULL, 0, NULL }')
896 line(out, indent, '};')
898 if instanceFields or propMethods or isExtension or clsParams:
899 tp_getset = 't_%s__fields_' %(names[-1])
905 tp_iter = 'get_extension_iterator'
907 tp_iter = '((PyObject *(*)(t_%s *)) get_%siterator< t_%s >)' %(names[-1], clsParams and 'generic_' or '', names[-1])
909 elif nextMethod and iterable is not None and iterator.isAssignableFrom(cls):
910 tp_iter = 'PyObject_SelfIter'
911 returnName = typename(nextMethod.getReturnType(), cls, False)
912 ns, sep, n = rpartition(returnName, '::')
914 tp_iternext = 'get_extension_next'
916 tp_iternext = '((PyObject *(*)(::java::util::t_Iterator *)) get_%siterator_next< ::java::util::t_Iterator,%s%st_%s >)' %(clsParams and 'generic_' or '', ns, sep, n)
917 elif nextElementMethod and enumeration.isAssignableFrom(cls):
918 tp_iter = 'PyObject_SelfIter'
919 returnName = typename(nextElementMethod.getReturnType(), cls, False)
920 ns, sep, n = rpartition(returnName, '::')
922 tp_iternext = 'get_extension_nextElement'
924 tp_iternext = '((PyObject *(*)(::java::util::t_Enumeration *)) get_%senumeration_next< ::java::util::t_Enumeration,%s%st_%s >)' %(clsParams and 'generic_' or '', ns, sep, n)
926 tp_iter = 'PyObject_SelfIter'
927 returnName = typename(nextMethod.getReturnType(), cls, False)
928 ns, sep, n = rpartition(returnName, '::')
930 tp_iternext = 'get_extension_next'
932 tp_iternext = '((PyObject *(*)(t_%s *)) get_%snext< t_%s,%s%st_%s,%s >)' %(names[-1], clsParams and 'generic_' or '', names[-1], ns, sep, n, returnName)
938 method, cardinality = mappingMethod
940 getName = 't_%s_%s_map_' %(names[-1], method.getName())
941 line(out, indent, 'static PyObject *%s(t_%s *self, PyObject *key);',
944 getName = 't_%s_%s' %(names[-1], method.getName())
946 line(out, indent, 'static PyMappingMethods t_%s_as_mapping = {',
948 line(out, indent + 1, '0,')
949 line(out, indent + 1, '(binaryfunc) %s,', getName)
950 line(out, indent + 1, '0,')
951 line(out, indent, '};')
952 tp_as_mapping = '&t_%s_as_mapping' %(names[-1])
956 if sequenceLenMethod or sequenceGetMethod:
957 if sequenceLenMethod:
958 method, cardinality = sequenceLenMethod
959 lenName = 't_%s_%s_seq_' %(names[-1], method.getName())
960 line(out, indent, 'static int %s(t_%s *self);', lenName, names[-1])
964 if sequenceGetMethod:
965 method, cardinality = sequenceGetMethod
966 getName = 't_%s_%s_seq_' %(names[-1], method.getName())
967 line(out, indent, 'static PyObject *%s(t_%s *self, int n);',
973 line(out, indent, 'static PySequenceMethods t_%s_as_sequence = {',
975 if python_ver < '2.5.0':
976 line(out, indent + 1, '(inquiry) %s,', lenName)
977 line(out, indent + 1, '0,')
978 line(out, indent + 1, '0,')
979 line(out, indent + 1, '(intargfunc) %s', getName)
980 line(out, indent, '};')
982 line(out, indent + 1, '(lenfunc) %s,', lenName)
983 line(out, indent + 1, '0,')
984 line(out, indent + 1, '0,')
985 line(out, indent + 1, '(ssizeargfunc) %s', getName)
986 line(out, indent, '};')
987 tp_as_sequence = '&t_%s_as_sequence' %(names[-1])
991 if len(superNames) > 1:
992 base = '::'.join((absname(cppnames(superNames[:-1])), superNames[-1]))
994 base = superNames[-1]
996 line(out, indent, 'DECLARE_TYPE(%s, t_%s, %s, %s, %s, %s, %s, %s, %s, %s);',
997 names[-1], names[-1], base, cppname(names[-1]), constructorName,
998 tp_iter, tp_iternext, tp_getset, tp_as_mapping, tp_as_sequence)
1002 for clsParam in clsParams:
1003 clsArgs.append("PyTypeObject *%s" %(clsParam.getName()))
1005 "PyObject *t_%s::wrap_Object(const %s& object, %s)",
1006 cppname(names[-1]), names[-1], ', '.join(clsArgs))
1007 line(out, indent, "{")
1008 line(out, indent + 1, "PyObject *obj = t_%s::wrap_Object(object);",
1010 line(out, indent + 1, "if (obj != NULL && obj != Py_None)")
1011 line(out, indent + 1, "{")
1012 line(out, indent + 2, "t_%s *self = (t_%s *) obj;",
1013 names[-1], names[-1])
1015 for clsParam in clsParams:
1016 line(out, indent + 2, "self->parameters[%d] = %s;",
1017 i, clsParam.getName())
1019 line(out, indent + 1, "}")
1020 line(out, indent + 1, "return obj;");
1021 line(out, indent, "}")
1025 "PyObject *t_%s::wrap_jobject(const jobject& object, %s)",
1026 cppname(names[-1]), ', '.join(clsArgs))
1027 line(out, indent, "{")
1028 line(out, indent + 1, "PyObject *obj = t_%s::wrap_jobject(object);",
1030 line(out, indent + 1, "if (obj != NULL && obj != Py_None)")
1031 line(out, indent + 1, "{")
1032 line(out, indent + 2, "t_%s *self = (t_%s *) obj;",
1033 names[-1], names[-1])
1035 for clsParam in clsParams:
1036 line(out, indent + 2, "self->parameters[%d] = %s;",
1037 i, clsParam.getName())
1039 line(out, indent + 1, "}")
1040 line(out, indent + 1, "return obj;");
1041 line(out, indent, "}")
1044 line(out, indent, 'void t_%s::install(PyObject *module)', names[-1])
1045 line(out, indent, '{')
1046 line(out, indent + 1, 'installType(&PY_TYPE(%s), module, "%s", %d);',
1047 names[-1], rename or names[-1], isExtension and 1 or 0)
1048 for inner in cls.getDeclaredClasses():
1049 if inner in typeset:
1050 if Modifier.isStatic(inner.getModifiers()):
1051 innerName = inner.getName().split('.')[-1]
1052 line(out, indent + 1, 'PyDict_SetItemString(PY_TYPE(%s).tp_dict, "%s", make_descriptor(&PY_TYPE(%s)));',
1053 names[-1], innerName[len(names[-1])+1:], innerName)
1054 line(out, indent, '}')
1057 line(out, indent, 'void t_%s::initialize(PyObject *module)', names[-1])
1058 line(out, indent, '{')
1059 line(out, indent + 1, 'PyDict_SetItemString(PY_TYPE(%s).tp_dict, "class_", make_descriptor(%s::initializeClass, %s));',
1060 names[-1], cppname(names[-1]), generics and 1 or 0)
1062 if is_unboxed(cls.getName()):
1063 wrapfn_ = "unbox%s" %(names[-1])
1064 boxfn_ = "box%s" %(names[-1])
1066 wrapfn_ = "t_%s::wrap_jobject" %(names[-1])
1067 boxfn_ = "boxObject"
1069 line(out, indent + 1, 'PyDict_SetItemString(PY_TYPE(%s).tp_dict, "wrapfn_", make_descriptor(%s));', names[-1], wrapfn_)
1070 line(out, indent + 1, 'PyDict_SetItemString(PY_TYPE(%s).tp_dict, "boxfn_", make_descriptor(%s));', names[-1], boxfn_)
1073 line(out, indent + 1, 'jclass cls = %s::initializeClass();',
1076 line(out, indent + 1, '%s::initializeClass();', cppname(names[-1]))
1080 line(out, indent + 1, 'JNINativeMethod methods[] = {')
1081 for name, methods in extMethods:
1082 for method in methods:
1083 line(out, indent + 2, '{ "%s", "%s", (void *) t_%s_%s%d },',
1084 name, signature(method), names[-1], name, count)
1086 line(out, indent + 1, '};')
1087 line(out, indent + 1, 'env->registerNatives(cls, methods, %d);',
1090 for field in fields:
1091 fieldType = field.getType()
1092 fieldName = field.getName()
1093 value = '%s::%s' %(cppname(names[-1]), cppname(fieldName))
1094 value = fieldValue(cls, value, fieldType)
1095 line(out, indent + 1, 'PyDict_SetItemString(PY_TYPE(%s).tp_dict, "%s", make_descriptor(%s));',
1096 names[-1], fieldName, value)
1097 line(out, indent, '}')
1100 line(out, indent, 'static PyObject *t_%s_cast_(PyTypeObject *type, PyObject *arg)', names[-1])
1101 line(out, indent, '{')
1102 line(out, indent + 1, 'if (!(arg = castCheck(arg, %s::initializeClass, 1)))', cppname(names[-1]))
1103 line(out, indent + 2, 'return NULL;')
1104 line(out, indent + 1, 'return t_%s::wrap_Object(%s(((t_%s *) arg)->object.this$));', names[-1], cppname(names[-1]), names[-1])
1105 line(out, indent, '}')
1107 line(out, indent, 'static PyObject *t_%s_instance_(PyTypeObject *type, PyObject *arg)', names[-1])
1108 line(out, indent, '{')
1109 line(out, indent + 1, 'if (!castCheck(arg, %s::initializeClass, 0))', cppname(names[-1]))
1110 line(out, indent + 2, 'Py_RETURN_FALSE;')
1111 line(out, indent + 1, 'Py_RETURN_TRUE;')
1112 line(out, indent, '}')
1117 'static PyObject *t_%s_of_(t_%s *self, PyObject *args)',
1118 names[-1], names[-1])
1119 line(out, indent, '{')
1120 line(out, indent + 1,
1121 'if (!parseArg(args, "T", %d, &(self->parameters)))',
1123 line(out, indent + 2, 'Py_RETURN_SELF;');
1124 line(out, indent + 1,
1125 'return PyErr_SetArgsError((PyObject *) self, "of_", args);')
1126 line(out, indent, '}')
1130 line(out, indent, 'static int t_%s_init_(t_%s *self, PyObject *args, PyObject *kwds)', names[-1], names[-1])
1131 line(out, indent, '{')
1132 if len(constructors) > 1:
1134 line(out, indent + 1, 'switch (PyTuple_GET_SIZE(args)) {')
1136 for constructor in constructors:
1137 params = constructor.getParameterTypes()
1138 if len(params) != currLen:
1141 line(out, indent + 2, 'goto err;')
1142 currLen = len(params)
1143 line(out, indent + 1, '%scase %d:', HALF_INDENT, currLen)
1144 construct(out, indent + 2, cls, True, constructor, names,
1146 line(out, indent + 1, '%sdefault:', HALF_INDENT)
1148 line(out, indent + 1, '%serr:', HALF_INDENT)
1149 line(out, indent + 2, 'PyErr_SetArgsError((PyObject *) self, "__init__", args);')
1150 line(out, indent + 2, 'return -1;')
1151 line(out, indent + 1, '}')
1153 construct(out, indent + 1, cls, False, constructors[0], names,
1155 if constructors[0].getParameterTypes():
1156 line(out, indent + 1, 'else')
1157 line(out, indent + 1, '{')
1158 line(out, indent + 2, 'PyErr_SetArgsError((PyObject *) self, "__init__", args);')
1159 line(out, indent + 2, 'return -1;')
1160 line(out, indent + 1, '}')
1164 line(out, indent + 1, 'Py_INCREF((PyObject *) self);')
1165 line(out, indent + 1, 'self->object.pythonExtension((jlong) (Py_intptr_t) (void *) self);')
1168 line(out, indent + 1, 'return 0;')
1169 line(out, indent , '}')
1171 for name, methods in allMethods:
1173 modifiers = methods[0].getModifiers()
1175 if isExtension and name == 'clone' and Modifier.isNative(modifiers):
1176 declargs, args, cardinality = ', PyObject *arg', ', arg', 1
1178 declargs, args, cardinality = methodargs(methods, superMethods)
1180 static = Modifier.isStatic(modifiers)
1182 line(out, indent, 'static PyObject *t_%s_%s(PyTypeObject *type%s)',
1183 names[-1], name, declargs)
1185 line(out, indent, 'static PyObject *t_%s_%s(t_%s *self%s)',
1186 names[-1], name, names[-1], declargs)
1188 line(out, indent, '{')
1189 if len(methods) > 1:
1191 line(out, indent + 1, 'switch (PyTuple_GET_SIZE(args)) {')
1192 for method in methods:
1193 params = method.getParameterTypes()
1194 if len(params) != currLen:
1196 line(out, indent + 2, 'break;')
1197 currLen = len(params)
1198 line(out, indent + 1, '%scase %d:', HALF_INDENT, currLen)
1199 call(out, indent + 2, cls, True, method, names, cardinality,
1200 isExtension, generics)
1201 line(out, indent + 1, '}')
1203 call(out, indent + 1, cls, False, methods[0], names, cardinality,
1204 isExtension, generics)
1208 if name in superMethods:
1210 line(out, indent + 1, 'return callSuper(type, "%s"%s, %d);',
1211 name, args, cardinality)
1213 line(out, indent + 1, 'return callSuper(&PY_TYPE(%s), (PyObject *) self, "%s"%s, %d);',
1214 names[-1], name, args, cardinality)
1216 line(out, indent + 1, 'PyErr_SetArgsError(%s, "%s"%s);',
1217 static and 'type' or '(PyObject *) self', name, args)
1218 line(out, indent + 1, 'return NULL;')
1220 line(out, indent, '}')
1224 for name, methods in extMethods:
1225 for method in methods:
1228 'static %s JNICALL t_%s_%s%d(JNIEnv *jenv, jobject jobj%s)',
1229 jniname(method.getReturnType()), names[-1], name, count,
1230 jniargs(method.getParameterTypes()))
1232 line(out, indent, '{')
1233 extension(env, out, indent + 1, cls, names, name, count, method,
1235 line(out, indent, '}')
1237 line(out, indent, 'static PyObject *t_%s_get__self(t_%s *self, void *data)',
1238 names[-1], names[-1])
1239 line(out, indent, '{')
1241 line(out, indent, 'jlong ptr;')
1242 line(out, indent, 'OBJ_CALL(ptr = self->object.pythonExtension());')
1243 line(out, indent, 'PyObject *obj = (PyObject *) (Py_intptr_t) ptr;')
1245 line(out, indent, 'if (obj != NULL)')
1246 line(out, indent, '{')
1247 line(out, indent + 1, 'Py_INCREF(obj);')
1248 line(out, indent + 1, 'return obj;')
1249 line(out, indent, '}')
1250 line(out, indent, 'else')
1251 line(out, indent + 1, 'Py_RETURN_NONE;')
1253 line(out, indent, '}')
1256 line(out, indent, 'static PyObject *t_%s_get__parameters_(t_%s *self, void *data)', names[-1], names[-1])
1257 line(out, indent, '{')
1258 line(out, indent + 1, 'return typeParameters(self->parameters, sizeof(self->parameters));')
1259 line(out, indent, '}')
1262 for field in instanceFields:
1263 fieldName = field.getName()
1264 if fieldName not in properties:
1266 fieldType = field.getType()
1267 typeName = typename(fieldType, cls, False)
1268 line(out, indent, 'static PyObject *t_%s_get__%s(t_%s *self, void *data)',
1269 names[-1], fieldName, names[-1])
1270 line(out, indent, '{')
1271 line(out, indent + 1, '%s value%s;', typeName,
1272 not fieldType.isPrimitive() and '((jobject) NULL)' or '')
1273 line(out, indent + 1, 'OBJ_CALL(value = self->object._get_%s());',
1275 line(out, indent + 1, returnValue(cls, fieldType, 'value'))
1276 line(out, indent, '}')
1278 if not Modifier.isFinal(field.getModifiers()):
1279 line(out, indent, 'static int t_%s_set__%s(t_%s *self, PyObject *arg, void *data)',
1280 names[-1], fieldName, names[-1])
1281 line(out, indent, '{')
1282 line(out, indent + 1, '%s value%s;', typeName,
1283 not fieldType.isPrimitive() and '((jobject) NULL)' or '')
1284 sig, check, x = parseArgs([fieldType], cls, False)
1285 line(out, indent + 1, 'if (!parseArg(arg, "%s"%s, &value))',
1287 line(out, indent + 1, '{')
1288 line(out, indent + 2, 'INT_CALL(self->object._set_%s(value));',
1290 line(out, indent + 2, 'return 0;')
1291 line(out, indent + 1, '}')
1292 line(out, indent + 1, 'PyErr_SetArgsError((PyObject *) self, "%s", arg);',
1294 line(out, indent + 1, 'return -1;')
1295 line(out, indent, '}')
1298 for fieldName, methods in propMethods:
1302 sort(methods, key=lambda x: x.getName())
1303 for method in methods:
1304 methodName = method.getName()
1305 if not getter and (methodName.startswith('get') or
1306 methodName.startswith('is')):
1308 elif methodName.startswith('set'):
1309 setters.append(method)
1312 methodName = getter.getName()
1313 returnType = getter.getReturnType()
1314 typeName = typename(returnType, cls, False)
1315 line(out, indent, 'static PyObject *t_%s_get__%s(t_%s *self, void *data)',
1316 names[-1], fieldName, names[-1])
1317 line(out, indent, '{')
1318 line(out, indent + 1, '%s value%s;', typeName,
1319 not returnType.isPrimitive() and '((jobject) NULL)' or '')
1320 line(out, indent + 1, 'OBJ_CALL(value = self->object.%s());',
1322 line(out, indent + 1, returnValue(cls, returnType, 'value'))
1323 line(out, indent, '}')
1326 line(out, indent, 'static int t_%s_set__%s(t_%s *self, PyObject *arg, void *data)',
1327 names[-1], fieldName, names[-1])
1328 line(out, indent, '{')
1329 methodName = setters[0].getName()
1330 for method in setters:
1331 argType = method.getParameterTypes()[0]
1332 typeName = typename(argType, cls, False)
1333 line(out, indent + 1, '{')
1334 line(out, indent + 2, '%s value%s;', typeName,
1335 not argType.isPrimitive() and '((jobject) NULL)' or '')
1336 sig, check, x = parseArgs([argType], cls, False)
1337 line(out, indent + 2, 'if (!parseArg(arg, "%s"%s, &value))',
1339 line(out, indent + 2, '{')
1340 line(out, indent + 3, 'INT_CALL(self->object.%s(value));',
1342 line(out, indent + 3, 'return 0;')
1343 line(out, indent + 2, '}')
1344 line(out, indent + 1, '}')
1345 line(out, indent + 1, 'PyErr_SetArgsError((PyObject *) self, "%s", arg);',
1347 line(out, indent + 1, 'return -1;')
1348 line(out, indent, '}')
1351 method, cardinality = mappingMethod
1353 methodName = method.getName()
1354 getName = 't_%s_%s_map_' %(names[-1], methodName)
1356 line(out, indent, 'static PyObject *%s(t_%s *self, PyObject *arg)',
1358 line(out, indent, '{')
1359 call(out, indent + 1, cls, False, method, names, 1, isExtension,
1362 line(out, indent + 1, 'PyErr_SetArgsError((PyObject *) self, "%s", arg);',
1364 line(out, indent + 1, 'return NULL;')
1365 line(out, indent, '}')
1367 if sequenceLenMethod:
1368 method, cardinality = sequenceLenMethod
1369 methodName = method.getName()
1370 lenName = 't_%s_%s_seq_' %(names[-1], methodName)
1372 line(out, indent, 'static int %s(t_%s *self)', lenName, names[-1])
1373 line(out, indent, '{')
1374 line(out, indent + 1, '%s len;',
1375 typename(method.getReturnType(), cls, False))
1376 line(out, indent + 1, 'INT_CALL(len = self->object.%s());', methodName)
1377 line(out, indent + 1, 'return (int) len;')
1378 line(out, indent, '}')
1380 if sequenceGetMethod:
1381 method, cardinality = sequenceGetMethod
1382 methodName = method.getName()
1383 returnType = method.getReturnType()
1384 getName = 't_%s_%s_seq_' %(names[-1], methodName)
1386 line(out, indent, 'static PyObject *%s(t_%s *self, int n)', getName, names[-1])
1387 line(out, indent, '{')
1388 line(out, indent + 1, '%s result%s;',
1389 typename(returnType, cls, False),
1390 not returnType.isPrimitive() and '((jobject) NULL)' or '')
1391 line(out, indent + 1, 'OBJ_CALL(result = self->object.%s((%s) n));',
1392 methodName, typename(method.getParameterTypes()[0], cls, False))
1394 line(out, indent + 1, returnValue(cls, returnType, 'result',
1395 method.getGenericReturnType()))
1397 line(out, indent + 1, returnValue(cls, returnType, 'result'))
1398 line(out, indent, '}')
1402 line(out, indent, '}')
1405 def package(out, allInOne, cppdir, namespace, names):
1408 out = file(os.path.join(os.path.join(cppdir, *names),
1409 '__init__.cpp'), 'w')
1411 if allInOne and not names or not allInOne:
1412 line(out, 0, '#include <jni.h>')
1413 line(out, 0, '#include <Python.h>')
1414 line(out, 0, '#include "JCCEnv.h"')
1415 line(out, 0, '#include "functions.h"')
1419 line(out, 0, 'PyObject *initVM(PyObject *module, PyObject *args, PyObject *kwds);')
1424 namespaces = namespace.items()
1425 sort(namespaces, key=lambda x: x[0])
1426 for name, entries in namespaces:
1429 line(out, 0, '#include "%s/%s.h"', '/'.join(names), name)
1431 line(out, 0, '#include "%s.h"', name)
1434 packages.append((name, entries))
1440 line(out, indent, 'namespace %s {', cppname(name))
1444 for name, entries in packages:
1445 line(out, indent, 'namespace %s {', cppname(name))
1446 line(out, indent + 1, 'void __install__(PyObject *module);')
1447 line(out, indent + 1, 'void __initialize__(PyObject *module);')
1448 line(out, indent, '}')
1451 line(out, indent, 'void __install__(PyObject *module)')
1452 line(out, indent, '{')
1454 line(out, indent + 1, 't_%s::install(module);', name)
1455 for name, entries in packages:
1456 line(out, indent + 1, '%s::__install__(module);', cppname(name))
1457 line(out, indent, '}')
1461 line(out, indent, 'PyObject *__initialize__(PyObject *module, PyObject *args, PyObject *kwds)')
1462 line(out, indent, '{')
1463 line(out, indent + 1, 'PyObject *env = initVM(module, args, kwds);')
1465 line(out, indent + 1, 'if (env == NULL)')
1466 line(out, indent + 2, 'return NULL;')
1468 line(out, indent + 1, 'try {');
1471 line(out, indent, 'void __initialize__(PyObject *module)')
1472 line(out, indent, '{')
1474 line(out, indent + 1, 't_%s::initialize(module);', name)
1475 for name, entries in packages:
1476 line(out, indent + 1, '%s::__initialize__(module);', cppname(name))
1478 line(out, indent + 1, 'return env;')
1480 line(out, indent + 1, '} catch (int e) {')
1481 line(out, indent + 2, 'switch(e) {')
1482 line(out, indent + 2, ' case _EXC_JAVA:')
1483 line(out, indent + 3, 'return PyErr_SetJavaError();')
1484 line(out, indent + 2, ' default:')
1485 line(out, indent + 3, 'throw;')
1486 line(out, indent + 2, '}')
1487 line(out, indent + 1, '}')
1489 line(out, indent, '}')
1493 line(out, indent, '}')
1500 for name, entries in packages:
1501 package(out, allInOne, cppdir, entries, names + (name,))
1504 def module(out, allInOne, classes, imports, cppdir, moduleName,
1507 extname = '_%s' %(moduleName)
1508 line(out, 0, '#include <Python.h>')
1509 line(out, 0, '#include "macros.h"')
1510 line(out, 0, '#include "jccfuncs.h"')
1513 out_init = file(os.path.join(cppdir, '__init__.cpp'), 'w')
1516 for importset in imports.itervalues():
1517 if cls in importset:
1520 namespace = namespaces
1521 classNames = cls.getName().split('.')
1522 for className in classNames[:-1]:
1523 namespace = namespace.setdefault(className, {})
1524 namespace[classNames[-1]] = True
1526 package(out_init, True, cppdir, namespaces, ())
1529 package(None, False, cppdir, namespaces, ())
1532 line(out, 0, 'PyObject *initJCC(PyObject *module);')
1533 line(out, 0, 'void __install__(PyObject *module);')
1534 line(out, 0, 'extern PyTypeObject PY_TYPE(JObject), PY_TYPE(ConstVariableDescriptor), PY_TYPE(FinalizerClass), PY_TYPE(FinalizerProxy);')
1535 line(out, 0, 'extern void _install_jarray(PyObject *);')
1537 line(out, 0, 'extern "C" {')
1540 line(out, 1, 'void init%s(void)', extname)
1542 line(out, 2, 'PyObject *module = Py_InitModule3("%s", jcc_funcs, "");',
1545 line(out, 2, 'initJCC(module);')
1547 line(out, 2, 'INSTALL_TYPE(JObject, module);')
1548 line(out, 2, 'INSTALL_TYPE(ConstVariableDescriptor, module);')
1549 line(out, 2, 'INSTALL_TYPE(FinalizerClass, module);')
1550 line(out, 2, 'INSTALL_TYPE(FinalizerProxy, module);')
1551 line(out, 2, '_install_jarray(module);')
1552 line(out, 2, '__install__(module);')
1557 def compile(env, jccPath, output, moduleName, install, dist, debug, jars,
1558 version, prefix, root, install_dir, home_dir, use_distutils,
1559 shared, compiler, modules, wininst, find_jvm_dll, arch, generics,
1560 resources, imports):
1565 from setuptools import setup, Extension
1566 with_setuptools = True
1567 if shared and not SHARED:
1568 raise NotImplementedError, "JCC was not built with --shared mode support, see JCC's INSTALL file for more information"
1570 if python_ver < '2.4':
1571 raise ImportError, 'setuptools is required when using Python 2.3'
1573 raise ImportError, 'setuptools is required when using --shared'
1574 from distutils.core import setup, Extension
1575 with_setuptools = False
1577 extname = '_%s' %(moduleName)
1579 modulePath = os.path.join(output, moduleName)
1580 if not os.path.isdir(modulePath):
1581 os.makedirs(modulePath)
1583 out = file(os.path.join(modulePath, '__init__.py'), 'w')
1586 line(out, 0, "import os, sys")
1588 line(out, 0, "if sys.platform == 'win32':")
1590 line(out, 1, "from jcc.windows import add_jvm_dll_directory_to_path")
1591 line(out, 1, "add_jvm_dll_directory_to_path()")
1592 line(out, 1, "import jcc, %s", extname)
1593 line(out, 0, "else:")
1594 line(out, 1, "import %s", extname)
1596 line(out, 0, 'import os, %s', extname)
1598 line(out, 0, '__dir__ = os.path.abspath(os.path.dirname(__file__))')
1602 shutil.copy2(jar, modulePath)
1603 package_data.append(os.path.basename(jar))
1605 def copytree(src, dst):
1606 _dst = os.path.join(modulePath, dst)
1607 if not os.path.exists(_dst):
1609 for name in os.listdir(src):
1610 if name.startswith('.'):
1612 _src = os.path.join(src, name)
1613 if os.path.islink(_src):
1615 _dst = os.path.join(dst, name)
1616 if os.path.isdir(_src):
1617 copytree(_src, _dst)
1619 shutil.copy2(_src, os.path.join(modulePath, _dst))
1620 package_data.append(_dst)
1621 for resource in resources:
1622 copytree(resource, os.path.split(resource)[-1])
1624 packages = [moduleName]
1625 package = [moduleName]
1627 for module in modules:
1628 if os.path.isdir(module):
1629 def copytree(src, dst, is_package):
1631 packages.append('.'.join(package))
1632 if not os.path.exists(dst):
1634 for name in os.listdir(src):
1635 if name.startswith('.'):
1637 _src = os.path.join(src, name)
1638 if os.path.islink(_src):
1640 _dst = os.path.join(dst, name)
1641 if os.path.isdir(_src):
1642 package.append(os.path.basename(_src))
1643 copytree(_src, _dst, os.path.exists(os.path.join(_src, '__init__.py')))
1645 elif not is_package or name.endswith('.py'):
1646 shutil.copy2(_src, _dst)
1648 if os.path.exists(os.path.join(module, '__init__.py')):
1649 dst = os.path.join(modulePath, os.path.basename(module))
1650 package.append(os.path.basename(module))
1651 copytree(module, dst, True)
1654 copytree(module, dst, False)
1656 shutil.copy2(module.split('.')[0] + '.py', modulePath)
1659 line(out, 0, 'class JavaError(Exception):')
1660 line(out, 1, 'def getJavaException(self):')
1661 line(out, 2, 'return self.args[0]')
1662 line(out, 1, 'def __str__(self):')
1663 line(out, 2, 'writer = StringWriter()')
1664 line(out, 2, 'self.getJavaException().printStackTrace(PrintWriter(writer))')
1665 line(out, 2, 'return "\\n".join((super(JavaError, self).__str__(), " Java stacktrace:", str(writer)))')
1667 line(out, 0, 'class InvalidArgsError(Exception):')
1668 line(out, 1, 'pass')
1670 line(out, 0, '%s._set_exception_types(JavaError, InvalidArgsError)',
1675 line(out, 0, 'VERSION = "%s"', version)
1677 line(out, 0, 'CLASSPATH = [%s]' %(', '.join(['os.path.join(__dir__, "%s")' %(os.path.basename(jar)) for jar in jars])))
1678 line(out, 0, 'CLASSPATH = os.pathsep.join(CLASSPATH)')
1679 line(out, 0, '%s.CLASSPATH = CLASSPATH', extname)
1680 line(out, 0, '%s._set_function_self(%s.initVM, %s)',
1681 extname, extname, extname)
1684 for import_ in imports:
1685 line(out, 0, 'from %s._%s import *', import_.__name__, import_.__name__)
1686 line(out, 0, 'from %s import *', extname)
1689 includes = [os.path.join(output, extname),
1690 os.path.join(jccPath, 'sources')]
1691 for import_ in imports:
1692 includes.append(os.path.join(import_.__dir__, 'include'))
1694 sources = ['JObject.cpp', 'JArray.cpp', 'functions.cpp', 'types.cpp']
1696 sources.append('jcc.cpp')
1697 sources.append('JCCEnv.cpp')
1698 for source in sources:
1699 shutil.copy2(os.path.join(jccPath, 'sources', source),
1700 os.path.join(output, extname))
1703 def copytree(src, dst):
1704 _dst = os.path.join(modulePath, dst)
1705 if not os.path.exists(_dst):
1707 for name in os.listdir(src):
1708 if name.startswith('.'):
1710 _src = os.path.join(src, name)
1711 if os.path.islink(_src):
1713 _dst = os.path.join(dst, name)
1714 if os.path.isdir(_src):
1715 copytree(_src, _dst)
1716 elif name.endswith('.h'):
1717 shutil.copy2(_src, os.path.join(modulePath, _dst))
1718 package_data.append(_dst)
1719 copytree(os.path.join(output, extname), 'include')
1722 for path, dirs, names in os.walk(os.path.join(output, extname)):
1724 if name.endswith('.cpp'):
1725 sources.append(os.path.join(path, name))
1727 script_args = ['build_ext']
1729 includes[0:0] = INCLUDES
1730 compile_args = CFLAGS
1733 defines=[('PYTHON', None),
1734 ('JCC_VER', '"%s"' %(JCC_VER))]
1736 defines.append(('_jcc_shared', None))
1738 defines.append(('_java_generics', None))
1741 script_args.append('--compiler=%s' %(compiler))
1744 script_args.append('--debug')
1745 compile_args += DEBUG_CFLAGS
1746 elif sys.platform == 'win32':
1748 elif sys.platform == 'sunos5':
1749 link_args.append('-Wl,-s')
1751 link_args.append('-Wl,-S')
1754 script_args.append('install')
1756 script_args.append('--prefix=%s' % prefix)
1758 script_args.append('--root=%s' % root)
1760 script_args.append('--install-lib=%s' % install_dir)
1762 script_args.append('--home=%s' % home_dir)
1766 script_args.append('bdist_wininst')
1767 elif with_setuptools:
1768 script_args.append('bdist_egg')
1770 script_args.append('bdist')
1773 'extra_compile_args': compile_args,
1774 'extra_link_args': link_args,
1775 'include_dirs': includes,
1777 'define_macros': defines
1781 shlibdir = os.path.dirname(os.path.dirname(_jcc.__file__))
1782 if sys.platform == 'darwin': # distutils no good with -R
1783 machine = platform.machine()
1784 if machine.startswith('iPod') or machine.startswith('iPhone'):
1785 args['extra_link_args'] += ['-L' + shlibdir]
1787 args['extra_link_args'] += ['-Wl,-rpath', shlibdir]
1788 args['library_dirs'] = [shlibdir]
1789 args['libraries'] = ['jcc']
1790 elif sys.platform == 'linux2': # distutils no good with -R
1791 args['extra_link_args'] += ['-Wl,-rpath', shlibdir]
1792 args['library_dirs'] = [shlibdir]
1793 args['libraries'] = ['jcc']
1794 args['extra_link_args'] += [
1795 getattr(import_, "_%s" %(import_.__name__)).__file__
1796 for import_ in imports
1798 elif sys.platform == 'win32':
1799 _d = debug and '_d' or ''
1800 libdir = os.path.join(modulePath, 'lib')
1801 if not os.path.exists(libdir):
1803 extlib = os.path.join('lib', "%s%s.lib" %(extname, _d))
1804 package_data.append(extlib)
1805 args['extra_link_args'] += [
1806 os.path.join(shlibdir, 'jcc', 'jcc%s.lib' %(_d)),
1807 ' '.join(IMPLIB_LFLAGS) %(os.path.join(modulePath, extlib))
1809 args['libraries'] = [
1810 os.path.join(import_.__dir__, 'lib',
1811 '_%s%s' %(import_.__name__, _d))
1812 for import_ in imports
1814 args['define_macros'] += [
1815 ("_dll_%s" %(import_.__name__), '__declspec(dllimport)')
1816 for import_ in imports
1817 ] + [("_dll_%s" %(moduleName), '__declspec(dllexport)')]
1819 raise NotImplementedError, "shared mode on %s" %(sys.platform)
1821 if arch and sys.platform == 'darwin':
1822 from distutils import sysconfig
1824 config_vars = sysconfig.get_config_vars()
1825 cflags = config_vars['CFLAGS'].split(' ')
1828 while i < count - 1:
1829 if cflags[i] == '-arch' and cflags[i + 1] not in arch:
1834 config_vars['CFLAGS'] = ' '.join(cflags)
1836 extensions = [Extension('.'.join([moduleName, extname]), **args)]
1840 'packages': packages,
1841 'package_dir': {moduleName: modulePath},
1842 'package_data': {moduleName: package_data},
1844 'ext_modules': extensions,
1845 'script_args': script_args
1848 args['zip_safe'] = False