src.templates.gderived.py Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
# copyright 2004-2005 Samuele Pedroni
import sys
import os
import re
scriptdir = os.path.dirname(__file__)
import directives
import java_parser
import java_templating
from java_templating import JavaTemplate,jast_make,jast
org_python_dir = os.path.join(os.path.dirname(os.path.abspath(scriptdir)),
'org', 'python')
core_dir = os.path.join(org_python_dir, 'core')
DERIVED_HEADER = """\
/* Generated file, do not modify. See jython/src/templates/gderived.py. */
package org.python.%s;
import java.io.Serializable;
import org.python.core.*;"""
modif_re = re.compile(r"(?:\((\w+)\))?(\w+)")
# os.path.samefile unavailable on Windows before Python v3.2
if hasattr(os.path,"samefile"):
# Good: available on this platform
os_path_samefile = os.path.samefile
else:
def os_path_samefile(a,b):
'Files are considered the same if their absolute paths are equal'
return os.path.abspath(a)==os.path.abspath(b)
class Gen:
priority_order = ['require','define','base_class',
'want_dict',
'ctr',
'incl',
'unary1',
'binary', 'ibinary',
'rest',
'no_toString'
]
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 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,'gderived-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)
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_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 dire_want_dict(self,name,parm,body):
if body is not None:
self.invalid(name,'non-empty body')
if self.want_dict is None:
self.want_dict = {"true": 1, "false": 0}[parm.strip()]
def dire_no_toString(self,name,parm,body):
if body is not None:
self.invalid(name,'non-empty body')
self.no_toString = True
def dire_incl(self,name,parm,body):
if body is not None:
self.invalid(name,'non-empty body')
directives.execute(directives.load(parm.strip()+'.derived'),self)
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 add_decl(self,templ):
pair = self.get_aux('pair')
self.decls = pair.tbind({'trailer': self.decls, 'last': templ})
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 dire_binary(self,name,parm,body):
if body is not None:
self.invalid(name,'non-empty body')
meth_names = parm.split()
binary_body = self.get_aux('binary')
for meth_name in meth_names:
self.add_decl(binary_body.tbind({'binary': JavaTemplate(meth_name)}))
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_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 generate(self):
if not self.no_toString:
self.add_decl(self.get_aux('toString'))
derived_templ = self.get_aux('derived_class')
return derived_templ.texpand({'base': self.base_class, 'decls': self.decls })
def process(fn, outfile, lazy=False):
if lazy and os.stat(fn).st_mtime < os.stat(outfile).st_mtime:
return
print 'Processing %s into %s' % (fn, outfile)
gen = Gen()
directives.execute(directives.load(fn),gen)
result = gen.generate()
result = hack_derived_header(outfile, result)
print >> open(outfile, 'w'), result
#gen.debug()
def hack_derived_header(fn, result):
"""Fix the package and import headers for derived classes outside of
org.python.core
"""
parent = os.path.dirname(fn)
if os_path_samefile(parent, core_dir):
return result
print 'Fixing header for: %s' % fn
dirs = []
while True:
parent, tail = os.path.split(parent)
dirs.insert(0, tail)
if os_path_samefile(parent, org_python_dir) or not tail:
break
result = result.splitlines()
for num, line in enumerate(result):
if line.startswith('public class '):
header = DERIVED_HEADER % '.'.join(dirs)
result[0:num - 1] = header.splitlines()
break
return '\n'.join(result)
if __name__ == '__main__':
from gexpose import load_mappings, usage
lazy = False
if len(sys.argv) > 4:
usage()
sys.exit(1)
if len(sys.argv) >= 2:
if '--help' in sys.argv:
usage()
sys.exit(0)
elif '--lazy' in sys.argv:
lazy = True
sys.argv.remove('--lazy')
if len(sys.argv) == 1:
for template, mapping in load_mappings().items():
if template.endswith('derived'):
process(mapping[0], mapping[1], lazy)
elif len(sys.argv) == 2:
mapping = load_mappings()[sys.argv[1]]
process(mapping[0], mapping[1], lazy)
else:
process(sys.argv[1], sys.argv[2], lazy)