def dire_expose_cmeth(self, name, parm, body): if body is None: body = 'return `concat`(`deleg_prefix,`name)((PyType)getSelf(),`all);' parm, prefix, body = self.expose_meth_body(name, parm, body) expose = self.get_aux('expose_narrow_cmeth') type_class = getattr(self, 'type_class', None) parms = parm.strip().split(None, 1) if len(parms) not in (1, 2): self.invalid(name, parm) if len(parms) == 1: parms.append('') expose_bindings = {} expose_bindings['typ'] = type_class expose_bindings['name'] = JavaTemplate(parms[0]) expose_bindings['deleg_prefix'] = make_name(prefix) # !!! call_meths_bindings = expose_bindings.copy() body_bindings = self.global_bindings.copy() body_bindings.update(expose_bindings) call_meths_bindings['call_meths'] = self.get_aux('call_cmeths').tbind( {'typ': type_class}) inst_call_meths, minargs, maxargs = self.handle_expose_meth_sig( parms[1], call_meths_bindings, body, body_bindings) expose_bindings['call_meths'] = inst_call_meths expose_bindings['minargs'] = JavaTemplate(str(minargs)) expose_bindings['maxargs'] = JavaTemplate(str(maxargs)) self.statements.append(expose.tbind(expose_bindings))
def dire_ctr(self, name, parm, body): if self.ctr_done: return if body is not None: self.invalid(name, "non-empty body") if self.want_dict: self.add_decl(self.get_aux('userdict')) ctr = self.get_aux('ctr_userdict') else: ctr = self.get_aux('ctr') extraargs = JavaTemplate(parm.strip(), start="FormalParameterListOpt") def visit(node): if isinstance(node, jast.VariableDeclaratorId): yield node.Identifier elif hasattr(node, 'children'): for child in node.children: for x in visit(child): yield x extra = jast_make(jast.Expressions, [ jast_make(jast.Primary, Identifier=x, ArgumentsOpt=None) for x in visit(extraargs.fragment) ]) extra = JavaTemplate(extra) self.add_decl( ctr.tbind({ 'base': self.base_class, 'extraargs': extraargs, 'extra': extra })) self.ctr_done = 1
def dire_unary1(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') parms = parm.split() if len(parms) not in (1, 2, 3): self.invalid(name, parm) meth_name = parms[0] if len(parms) == 1: unary_body = self.get_aux('unary') self.add_decl(unary_body.tbind({'unary': JavaTemplate(meth_name)})) else: rettype_name = parms[1] if len(parms) == 3: rettype_class = parms[2] else: rettype_class = 'Py' + rettype_name[0].upper( ) + rettype_name[1:] unary_body = self.get_aux('typed_unary') self.add_decl( unary_body.tbind({ 'unary': JavaTemplate(meth_name), 'rettype_name': JavaTemplate(java_parser.make_qualid(rettype_name)), 'rettype': JavaTemplate(rettype_class) }))
def generate(self): typeinfo0 = self.get_aux("typeinfo0") basic = JavaTemplate("", start="ClassBodyDeclarations") bindings = self.global_bindings.copy() if hasattr(self, "type_as"): basic = basic + JavaTemplate( "public static final Class exposed_as = `as.class;", start="ClassBodyDeclarations" ) bindings["as"] = self.type_as else: basic = basic + JavaTemplate( "public static final String exposed_name = `strfy`(`name);", start="ClassBodyDeclarations" ) bindings["name"] = self.type_name if hasattr(self, "type_base_class"): basic = basic + JavaTemplate( "public static final Class exposed_base = `base.class;", start="ClassBodyDeclarations" ) bindings["base"] = self.type_base_class typeinfo = typeinfo0 setup = JavaTemplate("", start="BlockStatements") if not self.no_setup: typeinfo1 = self.get_aux("typeinfo1") pair = self.get_aux("pair") for statement in self.statements: setup = pair.tbind({"trailer": setup, "last": statement}) typeinfo = typeinfo.tfree() + typeinfo1.tfree() return typeinfo.tnaked().texpand({"basic": basic.tbind(bindings), "setup": setup}, nindent=1)
def dire_expose_getset(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') parms = parm.strip().split() if len(parms) not in (2, 3, 4): self.invalid(name, parm) name = parms[0] get = '"%s"' % parms[1] if len(parms) >= 3: set = '"%s"' % parms[2] else: set = "null" if len(parms) == 4: del_meth = '"%s"' % parms[3] else: del_meth = "null" getset_bindings = self.global_bindings.copy() getset_bindings['name'] = JavaTemplate(make_id(name)) getset_bindings['get'] = JavaTemplate(make_literal(get)) getset_bindings['set'] = JavaTemplate(make_literal(set)) getset_bindings['del'] = JavaTemplate(make_literal(del_meth)) getset = self.get_aux('getset') self.statements.append(getset.tbind(getset_bindings))
def dire_expose_meth(self, name, parm, body): # !!! parm, prefix, body = self.expose_meth_body(name, parm, body) expose = self.get_aux('expose_narrow_meth') type_class = getattr(self, 'type_class', None) type_name = getattr(self, 'type_name', None) if type_class is None or type_name is None: raise Exception, "type_class or type_name not defined" parms = parm.strip().split(None, 1) if len(parms) not in (1, 2): self.invalid(name, parm) if len(parms) == 1: parms.append('') expose_bindings = {} expose_bindings['typ'] = type_class expose_bindings['name'] = JavaTemplate(parms[0]) expose_bindings['deleg_prefix'] = make_name(prefix) # !!! call_meths_bindings = expose_bindings.copy() body_bindings = self.global_bindings.copy() body_bindings.update(expose_bindings) call_meths_bindings['call_meths'] = self.get_aux('call_meths').tbind( {'typ': type_class}) inst_call_meths, minargs, maxargs = self.handle_expose_meth_sig( parms[1], call_meths_bindings, body, body_bindings) expose_bindings['call_meths'] = inst_call_meths expose_bindings['minargs'] = JavaTemplate(str(minargs)) expose_bindings['maxargs'] = JavaTemplate(str(maxargs)) self.statements.append(expose.tbind(expose_bindings))
def handle_expose_meth_sig(self, sig, call_meths_bindings, body, body_bindings): proto_body_jt = JavaTemplate(body) everything, dfls = self.parse_sig("expose_meth", sig) dfls = map(JavaTemplate, dfls) tot = len(everything) rng = len(dfls) + 1 for dflc in range(rng): new_body_bindings = body_bindings.copy() args = self.NOARGS all = self.EMPTYALL j = 0 conv_errors = {} for k, tg in everything[: tot - dflc]: argj = "arg%d" % j args += JavaTemplate("void(PyObject %s)" % argj) new_body_bindings[argj], err = getattr(self, "arg_%s" % k)(argj, j, tg) all += JavaTemplate(jast_make(jast.Expressions, [new_body_bindings[argj].fragment])) if err: conv_errors.setdefault(err, []).append(j) j += 1 new_body_bindings["all"] = all for dv in dfls[rng - 1 - dflc :]: new_body_bindings["arg%d" % j] = dv j += 1 for deleg_templ_name in ( "void", "deleg", "vdeleg", "rdeleg", "ideleg", "ldeleg", "bdeleg", "sdeleg", "udeleg", ): deleg_templ = self.get_aux(deleg_templ_name) new_body_bindings[deleg_templ_name] = deleg_templ.tbind(new_body_bindings) body_jt = proto_body_jt.tbind(new_body_bindings) if conv_errors: cases = JavaTemplate(jast_make(jast.SwitchBlockStatementGroups)) for err, indexes in conv_errors.items(): suite = JavaTemplate('msg = "%s"; break; ' % err).fragment.BlockStatements cases += java_templating.switchgroup(indexes, suite) bindings = {"cases": cases, "unsafe_body": body_jt} body_jt = self.get_aux("conv_error_handling").tbind(bindings) call_meths_bindings["body%d" % dflc] = body_jt call_meths_bindings["args%d" % dflc] = args inst_call_meths = self.make_call_meths(rng, call_meths_bindings) return inst_call_meths, tot - rng + 1, tot
def make_call_meths(self, n, bindings): try: return self.call_meths_cache[n].tbind(bindings) except KeyError: templ = "`call_meths`(`args%d,`body%d);" defs = [] for i in range(n): defs.append(templ % (i, i)) defs = '\n'.join(defs) jtempl = JavaTemplate(defs, start='ClassBodyDeclarations') self.call_meths_cache[n] = jtempl return jtempl.tbind(bindings)
def make_call_meths(self,n,bindings): try: return self.call_meths_cache[n].tbind(bindings) except KeyError: templ = "`call_meths`(`args%d,`body%d);" defs = [] for i in range(n): defs.append(templ % (i,i)) defs = '\n'.join(defs) jtempl = JavaTemplate(defs,start='ClassBodyDeclarations') self.call_meths_cache[n] = jtempl return jtempl.tbind(bindings)
def dire_ibinary(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') meth_names = parm.split() binary_body = self.get_aux('ibinary') for meth_name in meth_names: self.add_decl(binary_body.tbind({'binary': JavaTemplate(meth_name)}))
def dire_expose_new_immutable(self, name, parm, body): expose_new = self.get_aux('expose_new') parms = parm.split() body_bindings = self.global_bindings.copy() if body is not None: self.invalid(name, "non-empty body") body = self.get_aux('immutable_new_body') if not parms: parms = ['-1', '-1'] else: if len(parms) != 2: self.invalid(name, parm) body_bindings['minargs'] = JavaTemplate(parms[0]) body_bindings['maxargs'] = JavaTemplate(parms[1]) body = body.tbind(body_bindings) templ = expose_new.tbind(body_bindings) self.statements.append(templ.tbind({'body': body}))
def dire_expose_new_mutable(self,name,parm,body): expose_new = self.get_aux('expose_new') parms = parm.split() body_bindings = self.global_bindings.copy() if body is None: body = self.get_aux('mutable_new_body') else: body = JavaTemplate(body) if not parms: parms = ['-1','-1'] else: if len(parms) != 2: self.invalid(name,parm) body_bindings['minargs'] = JavaTemplate(parms[0]) body_bindings['maxargs'] = JavaTemplate(parms[1]) body = body.tbind(body_bindings) templ = expose_new.tbind(body_bindings) self.statements.append(templ.tbind({'body': body}))
def dire_expose_new_mutable(self, name, parm, body): expose_new = self.get_aux("expose_new") parms = parm.split() body_bindings = self.global_bindings.copy() if body is None: body = self.get_aux("mutable_new_body") else: body = JavaTemplate(body) if not parms: parms = ["-1", "-1"] else: if len(parms) != 2: self.invalid(name, parm) body_bindings["minargs"] = JavaTemplate(parms[0]) body_bindings["maxargs"] = JavaTemplate(parms[1]) body = body.tbind(body_bindings) templ = expose_new.tbind(body_bindings) self.statements.append(templ.tbind({"body": body}))
def dire_type_as(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') parms = parm.split() if len(parms) not in (1, 2): self.invalid(name, parm) self.type_as = JavaTemplate(parms[0]) if len(parms) == 2: if parms[1] == 'no-setup': self.no_setup = True else: self.invalid(name, parm)
def handle_expose_meth_sig(self, sig, call_meths_bindings, body, body_bindings): proto_body_jt = JavaTemplate(body) everything, dfls = self.parse_sig('expose_meth', sig) dfls = map(JavaTemplate, dfls) tot = len(everything) rng = len(dfls) + 1 for dflc in range(rng): new_body_bindings = body_bindings.copy() args = self.NOARGS all = self.EMPTYALL j = 0 conv_errors = {} for k, tg in everything[:tot - dflc]: argj = "arg%d" % j args += JavaTemplate("void(PyObject %s)" % argj) new_body_bindings[argj], err = getattr(self, 'arg_%s' % k)(argj, j, tg) all += JavaTemplate( jast_make(jast.Expressions, [new_body_bindings[argj].fragment])) if err: conv_errors.setdefault(err, []).append(j) j += 1 new_body_bindings['all'] = all for dv in dfls[rng - 1 - dflc:]: new_body_bindings["arg%d" % j] = dv j += 1 for deleg_templ_name in ('void', 'deleg', 'vdeleg', 'rdeleg', 'ideleg', 'ldeleg', 'bdeleg', 'sdeleg', 'udeleg'): deleg_templ = self.get_aux(deleg_templ_name) new_body_bindings[deleg_templ_name] = deleg_templ.tbind( new_body_bindings) body_jt = proto_body_jt.tbind(new_body_bindings) if conv_errors: cases = JavaTemplate(jast_make( jast.SwitchBlockStatementGroups)) for err, indexes in conv_errors.items(): suite = JavaTemplate('msg = "%s"; break; ' % err).fragment.BlockStatements cases += java_templating.switchgroup(indexes, suite) bindings = {'cases': cases, 'unsafe_body': body_jt} body_jt = self.get_aux('conv_error_handling').tbind(bindings) call_meths_bindings['body%d' % dflc] = body_jt call_meths_bindings['args%d' % dflc] = args inst_call_meths = self.make_call_meths(rng, call_meths_bindings) return inst_call_meths, tot - rng + 1, tot
def generate(self): typeinfo0 = self.get_aux('typeinfo0') basic = JavaTemplate("",start='ClassBodyDeclarations') bindings = self.global_bindings.copy() if hasattr(self,'type_as'): basic = (basic + JavaTemplate("public static final Class exposed_as = `as.class;", start = 'ClassBodyDeclarations')) bindings['as'] = self.type_as else: basic = (basic + JavaTemplate( "public static final String exposed_name = `strfy`(`name);", start='ClassBodyDeclarations')) bindings['name'] = self.type_name if hasattr(self,'type_base_class'): basic = (basic + JavaTemplate( "public static final Class exposed_base = `base.class;", start='ClassBodyDeclarations')) bindings['base'] = self.type_base_class typeinfo = typeinfo0 setup = JavaTemplate("",start='BlockStatements') if not self.no_setup: typeinfo1 = self.get_aux('typeinfo1') pair = self.get_aux('pair') for statement in self.statements: setup = pair.tbind({'trailer': setup, 'last': statement}) typeinfo = typeinfo.tfree() + typeinfo1.tfree() return typeinfo.tnaked().texpand({'basic': basic.tbind(bindings), 'setup': setup},nindent=1)
def dire_define(self, name, parm, body): parms = parm.split() if not parms: self.invalid('define', parm) parsed_name = modif_re.match(parms[0]) if not parsed_name: self.invalid('define', parm) templ_kind = parsed_name.group(1) templ_name = parsed_name.group(2) if templ_kind is None: templ_kind = 'Fragment' templ = JavaTemplate(body, parms=':'.join(parms[1:]), bindings = self.global_bindings, start = templ_kind) self.global_bindings[templ_name] = templ
def __init__(self,bindings=None,priority_order=None): if bindings is None: self.global_bindings = { 'csub': java_templating.csub, 'concat': java_templating.concat, 'strfy': java_templating.strfy } else: self.global_bindings = bindings if priority_order: self.priority_order = priority_order self.decls = JavaTemplate("") self.auxiliary = None self.base_class = None self.want_dict = None self.no_toString = False self.ctr_done = 0
def generate(self): typeinfo0 = self.get_aux('typeinfo0') basic = JavaTemplate("", start='ClassBodyDeclarations') bindings = self.global_bindings.copy() if hasattr(self, 'type_as'): basic = (basic + JavaTemplate( "public static final Class exposed_as = `as.class;", start='ClassBodyDeclarations')) bindings['as'] = self.type_as else: basic = (basic + JavaTemplate( "public static final String exposed_name = `strfy`(`name);", start='ClassBodyDeclarations')) bindings['name'] = self.type_name if hasattr(self, 'type_base_class'): basic = (basic + JavaTemplate( "public static final Class exposed_base = `base.class;", start='ClassBodyDeclarations')) bindings['base'] = self.type_base_class typeinfo = typeinfo0 setup = JavaTemplate("", start='BlockStatements') if not self.no_setup: typeinfo1 = self.get_aux('typeinfo1') pair = self.get_aux('pair') for statement in self.statements: setup = pair.tbind({'trailer': setup, 'last': statement}) typeinfo = typeinfo.tfree() + typeinfo1.tfree() return typeinfo.tnaked().texpand( { 'basic': basic.tbind(bindings), 'setup': setup }, nindent=1)
def dire_expose_wide_meth(self, name, parm, body): # !!! parm, prefix, body = self.expose_meth_body(name, parm, body) parms = parm.split() args = JavaTemplate("void(PyObject[] args,String[] keywords)") all = JavaTemplate("args, keywords", start='Expressions') bindings = self.global_bindings.copy() if len(parms) not in (1, 3): self.invalid(name, parm) bindings['name'] = JavaTemplate(parms[0]) bindings['deleg_prefix'] = make_name(prefix) bindings['all'] = all bindings['args'] = args for deleg_templ_name in ('void', 'deleg', 'vdeleg', 'rdeleg'): deleg_templ = self.get_aux(deleg_templ_name) bindings[deleg_templ_name] = deleg_templ.tbind(bindings) body = JavaTemplate(body).tbind(bindings) bindings['body'] = body call_meths = self.get_aux('call_meths').tbind(bindings) bindings['call_meths'] = call_meths parms = (parms + [-1, -1])[1:3] bindings['minargs'] = JavaTemplate(parms[0]) bindings['maxargs'] = JavaTemplate(parms[1]) expose = self.get_aux('expose_wide_meth').tbind(bindings) self.statements.append(expose)
def arg_i(self, argj, j, tg): if tg: err = "%s must be an integer" % tg else: err = "expected an integer" return JavaTemplate("%s.asInt(%s)" % (argj, j)), err # !!!
def dire_rest(self, name, parm, body): if parm: self.invalid(name, 'non-empty parm') if body is None: return self.add_decl(JavaTemplate(body, start='ClassBodyDeclarations'))
def arg_b(self, argj, j, tg): return JavaTemplate("%s.__bool__()" % (argj)), None
def dire_base_class(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') if self.base_class is None: self.base_class = JavaTemplate(parm.strip()) self.global_bindings['base'] = self.base_class
def arg_o(self, argj, j, tg): return JavaTemplate(argj), None
def dire_type_class(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') self.type_class = JavaTemplate(parm.strip()) self.global_bindings['typ'] = self.type_class
def arg_S(self, argj, j, tg): if tg: err = "%s must be a string or None" % tg else: err = "expected a string or None" return JavaTemplate("%s.asStringOrNull(%s)" % (argj, j)), err # !!!
def arg_n(self, argj, j, tg): if tg: err = "%s must be a string" % tg else: err = "expected a string" return JavaTemplate("%s.asName(%s)" % (argj, j)), err # !!!
def make_name(n): return JavaTemplate( jast_make(jast.QualifiedIdentifier, [java_parser.make_id(n)]))
def dire_rest(self, name, parm, body): if parm: self.invalid(name, 'non-empty parm') if body is None: return self.statements.append(JavaTemplate(body, start='BlockStatements'))
def arg_l(self, argj, j, tg): if tg: err = "%s must be a long" % tg else: err = "expected a long" return JavaTemplate("%s.asLong(%s)" % (argj, j)), err # !!!
def dire_type_base_class(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') self.type_base_class = JavaTemplate(parm.strip())
class Gen: priority_order = [ 'require', 'define', 'type_as', 'type_name', 'type_class', 'type_base_class', 'incl', 'expose_getset', 'expose_unary', 'expose_binary', 'expose_vanilla_cmp', 'expose_vanilla_pow', 'expose_key_getitem', 'expose_index_getitem', 'expose_cmeth', 'expose_meth', 'expose_wide_meth', 'expose_new_mutable', 'expose_new_immutable', 'rest' ] def __init__(self, bindings=None, priority_order=None): if bindings is None: self.global_bindings = { 'csub': java_templating.csub, 'concat': java_templating.concat, 'strfy': java_templating.strfy } else: self.global_bindings = bindings if priority_order: self.priority_order = priority_order self.call_meths_cache = {} self.auxiliary = None self.no_setup = False self.statements = [] def debug(self, bindings): for name, val in bindings.items(): if isinstance(val, JavaTemplate): print "%s:" % name print val.texpand({}) def invalid(self, dire, value): raise Exception, "invalid '%s': %s" % (dire, value) def get_aux(self, name): if self.auxiliary is None: aux_gen = Gen(priority_order=['require', 'define']) directives.execute( directives.load(os.path.join(scriptdir, 'gexpose-defs')), aux_gen) self.auxiliary = aux_gen.global_bindings return self.auxiliary[name] def dire_require(self, name, parm, body): if body is not None: self.invalid('require', 'non-empty body') sub_gen = Gen(bindings=self.global_bindings, priority__order=['require', 'define']) directives.execute(directives.load(parm.strip()), sub_gen) def dire_define(self, name, parm, body): parms = parm.split() if not parms: self.invalid('define', parm) parsed_name = modif_re.match(parms[0]) if not parsed_name: self.invalid('define', parm) templ_kind = parsed_name.group(1) templ_name = parsed_name.group(2) naked = False if templ_kind is None: templ_kind = 'Fragment' templ = JavaTemplate(body, parms=':'.join(parms[1:]), bindings=self.global_bindings, start=templ_kind) self.global_bindings[templ_name] = templ def dire_type_as(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') parms = parm.split() if len(parms) not in (1, 2): self.invalid(name, parm) self.type_as = JavaTemplate(parms[0]) if len(parms) == 2: if parms[1] == 'no-setup': self.no_setup = True else: self.invalid(name, parm) def dire_type_name(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') self.type_name_plain = parm.strip() self.type_name = make_name(self.type_name_plain) self.global_bindings['typname'] = self.type_name def dire_type_class(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') self.type_class = JavaTemplate(parm.strip()) self.global_bindings['typ'] = self.type_class def dire_type_base_class(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') self.type_base_class = JavaTemplate(parm.strip()) def dire_incl(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') directives.execute(directives.load(parm.strip() + '.expose'), self) def dire_expose_getset(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') parms = parm.strip().split() if len(parms) not in (2, 3, 4): self.invalid(name, parm) name = parms[0] get = '"%s"' % parms[1] if len(parms) >= 3: set = '"%s"' % parms[2] else: set = "null" if len(parms) == 4: del_meth = '"%s"' % parms[3] else: del_meth = "null" getset_bindings = self.global_bindings.copy() getset_bindings['name'] = JavaTemplate(make_id(name)) getset_bindings['get'] = JavaTemplate(make_literal(get)) getset_bindings['set'] = JavaTemplate(make_literal(set)) getset_bindings['del'] = JavaTemplate(make_literal(del_meth)) getset = self.get_aux('getset') self.statements.append(getset.tbind(getset_bindings)) NOARGS = JavaTemplate("void()") EMPTYALL = JavaTemplate(jast_make(jast.Expressions)) def parse_sig(self, name, sig): argspecs = [] some_opt = 0 for m in ktg_re.finditer(sig): k = m.group('k') opt = m.group('opt') and 1 or 0 if opt: some_opt = 1 if opt != some_opt: self.invalid(name, "cannot interleave opt and non-opt arguments") dfl = m.group('dfl') if opt and dfl is None: dfl = '' tg = m.group('tg') argspecs.append((k, opt, dfl, tg)) everything = [(k, tg) for k, opt, dfl, tg in argspecs] dfls = [dfl for k, opt, dfl, tg in argspecs if opt] return everything, dfls def arg_i(self, argj, j, tg): if tg: err = "%s must be an integer" % tg else: err = "expected an integer" return JavaTemplate("%s.asInt(%s)" % (argj, j)), err # !!! def arg_l(self, argj, j, tg): if tg: err = "%s must be a long" % tg else: err = "expected a long" return JavaTemplate("%s.asLong(%s)" % (argj, j)), err # !!! def arg_b(self, argj, j, tg): return JavaTemplate("%s.__bool__()" % (argj)), None def arg_o(self, argj, j, tg): return JavaTemplate(argj), None def arg_S(self, argj, j, tg): if tg: err = "%s must be a string or None" % tg else: err = "expected a string or None" return JavaTemplate("%s.asStringOrNull(%s)" % (argj, j)), err # !!! def arg_s(self, argj, j, tg): if tg: err = "%s must be a string" % tg else: err = "expected a string" return JavaTemplate("%s.asString(%s)" % (argj, j)), err # !!! def arg_n(self, argj, j, tg): if tg: err = "%s must be a string" % tg else: err = "expected a string" return JavaTemplate("%s.asName(%s)" % (argj, j)), err # !!! def make_call_meths(self, n, bindings): try: return self.call_meths_cache[n].tbind(bindings) except KeyError: templ = "`call_meths`(`args%d,`body%d);" defs = [] for i in range(n): defs.append(templ % (i, i)) defs = '\n'.join(defs) jtempl = JavaTemplate(defs, start='ClassBodyDeclarations') self.call_meths_cache[n] = jtempl return jtempl.tbind(bindings) def handle_expose_meth_sig(self, sig, call_meths_bindings, body, body_bindings): proto_body_jt = JavaTemplate(body) everything, dfls = self.parse_sig('expose_meth', sig) dfls = map(JavaTemplate, dfls) tot = len(everything) rng = len(dfls) + 1 for dflc in range(rng): new_body_bindings = body_bindings.copy() args = self.NOARGS all = self.EMPTYALL j = 0 conv_errors = {} for k, tg in everything[:tot - dflc]: argj = "arg%d" % j args += JavaTemplate("void(PyObject %s)" % argj) new_body_bindings[argj], err = getattr(self, 'arg_%s' % k)(argj, j, tg) all += JavaTemplate( jast_make(jast.Expressions, [new_body_bindings[argj].fragment])) if err: conv_errors.setdefault(err, []).append(j) j += 1 new_body_bindings['all'] = all for dv in dfls[rng - 1 - dflc:]: new_body_bindings["arg%d" % j] = dv j += 1 for deleg_templ_name in ('void', 'deleg', 'vdeleg', 'rdeleg', 'ideleg', 'ldeleg', 'bdeleg', 'sdeleg', 'udeleg'): deleg_templ = self.get_aux(deleg_templ_name) new_body_bindings[deleg_templ_name] = deleg_templ.tbind( new_body_bindings) body_jt = proto_body_jt.tbind(new_body_bindings) if conv_errors: cases = JavaTemplate(jast_make( jast.SwitchBlockStatementGroups)) for err, indexes in conv_errors.items(): suite = JavaTemplate('msg = "%s"; break; ' % err).fragment.BlockStatements cases += java_templating.switchgroup(indexes, suite) bindings = {'cases': cases, 'unsafe_body': body_jt} body_jt = self.get_aux('conv_error_handling').tbind(bindings) call_meths_bindings['body%d' % dflc] = body_jt call_meths_bindings['args%d' % dflc] = args inst_call_meths = self.make_call_meths(rng, call_meths_bindings) return inst_call_meths, tot - rng + 1, tot def expose_meth_body(self, name, parm, body): parm = parm.strip() if parm.find('>') != -1: prefix, parm = parm.split('>', 1) parm = parm.strip() else: prefix = self.type_name_plain + '_' if body is not None: return parm, prefix, body if parm.startswith(':'): retk, rest = parm.split(None, 1) body = { ":i": "`ideleg;", ":l": "`ldeleg;", ":b": "`bdeleg;", ":s": "`sdeleg;", ":u": "`udeleg;", ":-": "`vdeleg; `void; ", ":o": "`rdeleg;" }.get(retk, None) if not body: self.invalid(name, retk) return rest, prefix, body else: return parm, prefix, "`rdeleg;" def dire_expose_meth(self, name, parm, body): # !!! parm, prefix, body = self.expose_meth_body(name, parm, body) expose = self.get_aux('expose_narrow_meth') type_class = getattr(self, 'type_class', None) type_name = getattr(self, 'type_name', None) if type_class is None or type_name is None: raise Exception, "type_class or type_name not defined" parms = parm.strip().split(None, 1) if len(parms) not in (1, 2): self.invalid(name, parm) if len(parms) == 1: parms.append('') expose_bindings = {} expose_bindings['typ'] = type_class expose_bindings['name'] = JavaTemplate(parms[0]) expose_bindings['deleg_prefix'] = make_name(prefix) # !!! call_meths_bindings = expose_bindings.copy() body_bindings = self.global_bindings.copy() body_bindings.update(expose_bindings) call_meths_bindings['call_meths'] = self.get_aux('call_meths').tbind( {'typ': type_class}) inst_call_meths, minargs, maxargs = self.handle_expose_meth_sig( parms[1], call_meths_bindings, body, body_bindings) expose_bindings['call_meths'] = inst_call_meths expose_bindings['minargs'] = JavaTemplate(str(minargs)) expose_bindings['maxargs'] = JavaTemplate(str(maxargs)) self.statements.append(expose.tbind(expose_bindings)) def dire_expose_cmeth(self, name, parm, body): if body is None: body = 'return `concat`(`deleg_prefix,`name)((PyType)getSelf(),`all);' parm, prefix, body = self.expose_meth_body(name, parm, body) expose = self.get_aux('expose_narrow_cmeth') type_class = getattr(self, 'type_class', None) parms = parm.strip().split(None, 1) if len(parms) not in (1, 2): self.invalid(name, parm) if len(parms) == 1: parms.append('') expose_bindings = {} expose_bindings['typ'] = type_class expose_bindings['name'] = JavaTemplate(parms[0]) expose_bindings['deleg_prefix'] = make_name(prefix) # !!! call_meths_bindings = expose_bindings.copy() body_bindings = self.global_bindings.copy() body_bindings.update(expose_bindings) call_meths_bindings['call_meths'] = self.get_aux('call_cmeths').tbind( {'typ': type_class}) inst_call_meths, minargs, maxargs = self.handle_expose_meth_sig( parms[1], call_meths_bindings, body, body_bindings) expose_bindings['call_meths'] = inst_call_meths expose_bindings['minargs'] = JavaTemplate(str(minargs)) expose_bindings['maxargs'] = JavaTemplate(str(maxargs)) self.statements.append(expose.tbind(expose_bindings)) def dire_expose_unary(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') meth_names = parm.split() if meth_names[0].endswith('>'): meth_names = ["%s %s" % (meth_names[0], n) for n in meth_names[1:]] unary_body = self.get_aux('unary').fragment for meth_name in meth_names: self.dire_expose_meth('expose_unary_1', meth_name, unary_body) def dire_expose_binary(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') meth_names = parm.split() if meth_names[0].endswith('>'): meth_names = ["%s %s" % (meth_names[0], n) for n in meth_names[1:]] binary_body = self.get_aux('binary').fragment for meth_name in meth_names: self.dire_expose_meth('expose_binary_1', "%s o" % meth_name, binary_body) def dire_expose_key_getitem(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') prefix = "" if parm.endswith('>'): prefix = parm key_getitem_body = self.get_aux('key_getitem').fragment self.dire_expose_meth('expose_key_getitem', "%s __getitem__ o" % prefix, key_getitem_body) def dire_expose_index_getitem(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') prefix = "" if parm.endswith('>'): prefix = parm index_getitem_body = self.get_aux('index_getitem').fragment self.dire_expose_meth('expose_index_getitem', "%s __getitem__ o" % prefix, index_getitem_body) def dire_expose_vanilla_pow(self, name, parm, body): if body is not None: self.invalid(name, 'non-empty body') prefix = "" if parm.endswith('>'): prefix = parm vanilla_pow_body = self.get_aux('vanilla_pow').fragment self.dire_expose_meth('expose_vanilla_pow', "%s __pow__ oo?(null)" % prefix, vanilla_pow_body) def dire_expose_wide_meth(self, name, parm, body): # !!! parm, prefix, body = self.expose_meth_body(name, parm, body) parms = parm.split() args = JavaTemplate("void(PyObject[] args,String[] keywords)") all = JavaTemplate("args, keywords", start='Expressions') bindings = self.global_bindings.copy() if len(parms) not in (1, 3): self.invalid(name, parm) bindings['name'] = JavaTemplate(parms[0]) bindings['deleg_prefix'] = make_name(prefix) bindings['all'] = all bindings['args'] = args for deleg_templ_name in ('void', 'deleg', 'vdeleg', 'rdeleg'): deleg_templ = self.get_aux(deleg_templ_name) bindings[deleg_templ_name] = deleg_templ.tbind(bindings) body = JavaTemplate(body).tbind(bindings) bindings['body'] = body call_meths = self.get_aux('call_meths').tbind(bindings) bindings['call_meths'] = call_meths parms = (parms + [-1, -1])[1:3] bindings['minargs'] = JavaTemplate(parms[0]) bindings['maxargs'] = JavaTemplate(parms[1]) expose = self.get_aux('expose_wide_meth').tbind(bindings) self.statements.append(expose) def dire_expose_new_mutable(self, name, parm, body): expose_new = self.get_aux('expose_new') parms = parm.split() body_bindings = self.global_bindings.copy() if body is None: body = self.get_aux('mutable_new_body') else: body = JavaTemplate(body) if not parms: parms = ['-1', '-1'] else: if len(parms) != 2: self.invalid(name, parm) body_bindings['minargs'] = JavaTemplate(parms[0]) body_bindings['maxargs'] = JavaTemplate(parms[1]) body = body.tbind(body_bindings) templ = expose_new.tbind(body_bindings) self.statements.append(templ.tbind({'body': body})) def dire_expose_new_immutable(self, name, parm, body): expose_new = self.get_aux('expose_new') parms = parm.split() body_bindings = self.global_bindings.copy() if body is not None: self.invalid(name, "non-empty body") body = self.get_aux('immutable_new_body') if not parms: parms = ['-1', '-1'] else: if len(parms) != 2: self.invalid(name, parm) body_bindings['minargs'] = JavaTemplate(parms[0]) body_bindings['maxargs'] = JavaTemplate(parms[1]) body = body.tbind(body_bindings) templ = expose_new.tbind(body_bindings) self.statements.append(templ.tbind({'body': body})) def dire_rest(self, name, parm, body): if parm: self.invalid(name, 'non-empty parm') if body is None: return self.statements.append(JavaTemplate(body, start='BlockStatements')) def generate(self): typeinfo0 = self.get_aux('typeinfo0') basic = JavaTemplate("", start='ClassBodyDeclarations') bindings = self.global_bindings.copy() if hasattr(self, 'type_as'): basic = (basic + JavaTemplate( "public static final Class exposed_as = `as.class;", start='ClassBodyDeclarations')) bindings['as'] = self.type_as else: basic = (basic + JavaTemplate( "public static final String exposed_name = `strfy`(`name);", start='ClassBodyDeclarations')) bindings['name'] = self.type_name if hasattr(self, 'type_base_class'): basic = (basic + JavaTemplate( "public static final Class exposed_base = `base.class;", start='ClassBodyDeclarations')) bindings['base'] = self.type_base_class typeinfo = typeinfo0 setup = JavaTemplate("", start='BlockStatements') if not self.no_setup: typeinfo1 = self.get_aux('typeinfo1') pair = self.get_aux('pair') for statement in self.statements: setup = pair.tbind({'trailer': setup, 'last': statement}) typeinfo = typeinfo.tfree() + typeinfo1.tfree() return typeinfo.tnaked().texpand( { 'basic': basic.tbind(bindings), 'setup': setup }, nindent=1)