[java2python] r178 committed - work in progress.

9 views
Skip to first unread message

java2...@googlecode.com

unread,
Aug 12, 2010, 2:21:08 PM8/12/10
to java2pyth...@googlegroups.com
Revision: 178
Author: troy.melhase
Date: Thu Aug 12 11:20:01 2010
Log: work in progress.
http://code.google.com/p/java2python/source/detail?r=178

Added:
/trunk/test/configs/Class10.py
Modified:
/trunk/java2python/compiler/template.py
/trunk/java2python/compiler/visitor.py
/trunk/java2python/config/default.py
/trunk/java2python/mod/basic.py
/trunk/test/Anno1.java
/trunk/test/Class10.java
/trunk/test/Makefile
/trunk/test/ReallyQuickTest.java

=======================================
--- /dev/null
+++ /trunk/test/configs/Class10.py Thu Aug 12 11:20:01 2010
@@ -0,0 +1,8 @@
+
+
+from java2python.config.default import modulePrologueHandlers
+
+modulePrologueHandlers += [
+ 'from configs.overloading import overloaded',
+ 'from abc import ABCMeta, abstractmethod',
+ ]
=======================================
--- /trunk/java2python/compiler/template.py Thu Aug 5 14:17:51 2010
+++ /trunk/java2python/compiler/template.py Thu Aug 12 11:20:01 2010
@@ -319,11 +319,11 @@
def iterBody(self):
""" Yields the items in the body of this template. """
blank, prev = self.factory.expr(), None
- def pred(p, c):
- return (p and not p.isClass) and (c.isClass and not c.isComment)
for child in super(Module, self).iterBody():
- if pred(prev, child):
+ if prev and not prev.isComment:
yield blank
+ if prev and prev.isClass and child and child.isClass:
+ yield blank
yield child
prev = child

=======================================
--- /trunk/java2python/compiler/visitor.py Thu Aug 5 14:17:51 2010
+++ /trunk/java2python/compiler/visitor.py Thu Aug 12 11:20:01 2010
@@ -5,7 +5,7 @@
# Needs some introductory comments.

from functools import reduce, partial
-from itertools import ifilter, izip
+from itertools import ifilter, ifilterfalse, izip, tee
from logging import debug
from re import compile as recompile, sub as resub

@@ -72,6 +72,8 @@
comIns(self, tree, tree.tokenStopIndex, memo)
if tree.isJavaSource:
comIns(self, tree, len(tree.parser.input.tokens), memo)
+ # fixme: we're calling the mutators far too frequently instead
+ # of only once per object after its walk is finished.
for handler in self.configHandlers('PostWalk', suffix='Mutators'):
handler(self)

@@ -80,6 +82,22 @@
for node, visitor in izip(nodes, visitors):
visitor.walk(node, memo)

+ def nodeTypeToString(self, node):
+ """ Returns the TYPE or QUALIFIED_TYPE_IDENT of the given node. """
+ # (TYPE primitiveType
+ # | TYPE qualifiedTypeIdent
+ # | TYPE qualifiedTypeIdentSimplified
+ # ) arrayDeclaratorList?
+ alt = self.altIdent
+ ntype = node.firstChildOfType(tokens.TYPE)
+ nnext = ntype.children[0]
+ if nnext.type == tokens.QUALIFIED_TYPE_IDENT:
+ names = [alt(t.text) for t in nnext.childrenOfType(tokens.IDENT)]
+ stype = '.'.join(names)
+ else:
+ stype = nnext.text
+ return alt(stype)
+

class TypeAcceptor(object):
""" TypeAcceptor -> shared visitor method(s) for type declarations.
@@ -125,26 +143,77 @@
"""
def acceptModifierList(self, node, memo):
""" Accept and process class and method modifiers. """
- # modifier lists come with class, interface, enum and
- # annotation declarations. they also come with method and var
- # decls; see those methods in the Class definition.
-
- for branch in [c for c in node.children if c.type==tokens.AT]:
- # TODO: walk annotation correctly
- name = branch.firstChildOfType(tokens.IDENT).text
+ isAnno = lambda token:token.type==tokens.AT
+ for ano in ifilter(isAnno, node.children):
+ self.nodesToAnnos(ano, memo)
+ for mod in ifilterfalse(isAnno, node.children):
+ self.nodesToModifiers(mod, node)
+ return self
+
+ def nodesToAnnos(self, branch, memo):
+ """ Convert the annotations in the given branch to a decorator. """
+ name = branch.firstChildOfType(tokens.IDENT).text
+ init = branch.firstChildOfType(tokens.ANNOTATION_INIT_BLOCK)
+ if not init:
deco = self.factory.expr(left=name, fs='@{left}()')
+ else:
+ defKey = init.firstChildOfType(tokens.ANNOTATION_INIT_DEFAULT_KEY)
+ if defKey:
+ deco = self.factory.expr(left=name, fs='@{left}({right})')
+ deco.right = right = self.factory.expr(parent=deco)
+ right.walk(defKey.firstChild())
+ else:
+ deco = self.factory.expr(left=name, fs='@{left}({right})')
+ arg = deco.right = self.factory.expr(parent=deco)
+ keys = init.firstChildOfType(tokens.ANNOTATION_INIT_KEY_LIST)
+ for child in keys.children:
+ fs, expr = child.text + '={right}', child.firstChild()
+ fs += (', ' if child is not keys.children[-1] else '')
+ arg.left = self.factory.expr(fs=fs, parent=arg)
+ arg.left.walk(expr, memo)
+ arg.right = arg = self.factory.expr(parent=arg)
self.decorators.append(deco)

- for branch in [c for c in node.children if c.type != tokens.AT]:
- if node.parentType in tokens.methodTypes:
- self.modifiers.extend(n.text for n in node.children) # wrong
- if self.isStatic:
- self.parameters[0]['name'] = 'cls'
- self.modifiers.append(branch.text)
+ def nodesToModifiers(self, branch, root):
+ """ Convert the modifiers in the given branch to template modifiers. """
+ if root.parentType in tokens.methodTypes:
+ self.modifiers.extend(n.text for n in root.children)
+ if self.isStatic and self.parameters:
+ self.parameters[0]['name'] = 'cls'
+ self.modifiers.append(branch.text)
+
+
+class VarAcceptor(object):
+ def acceptVarDeclaration(self, node, memo):
+ """ Creates a new expression for a variable declaration. """
+ varDecls = node.firstChildOfType(tokens.VAR_DECLARATOR_LIST)
+ for varDecl in varDecls.childrenOfType(tokens.VAR_DECLARATOR):
+ ident = varDecl.firstChildOfType(tokens.IDENT)
+ self.variables.append(ident.text)
+ identExp = self.factory.expr(left=ident.text, parent=self)
+ declExp = varDecl.firstChildOfType(tokens.EXPR)
+ assgnExp = identExp.pushRight(' = ')
+ declArr = varDecl.firstChildOfType(tokens.ARRAY_INITIALIZER)
+ if declExp:
+ assgnExp.walk(declExp, memo)
+ elif declArr:
+ assgnExp.right = exp = self.factory.expr(fs='['+FS.lr+']',
parent=identExp)
+ children = list(declArr.childrenOfType(tokens.EXPR))
+ for child in children:
+ fs = FS.lr if child is children[-1] else FS.lr + ', '
+ exp.left = self.factory.expr(fs=fs, parent=identExp)
+ exp.left.walk(child, memo)
+ exp.right = exp = self.factory.expr(parent=identExp)
+ else:
+ if
node.firstChildOfType(tokens.TYPE).firstChildOfType(tokens.ARRAY_DECLARATOR_LIST):
+ val = assgnExp.pushRight('[]')
+ else:
+ typ = self.nodeTypeToString(node)
+ val = assgnExp.pushRight('{0}()'.format(typ))
return self


-class Class(TypeAcceptor, ModifiersAcceptor, Base):
+class Class(VarAcceptor, TypeAcceptor, ModifiersAcceptor, Base):
""" Class -> accepts AST branches for class-level objects.

"""
@@ -183,36 +252,6 @@
mods = node.firstChildOfType(tokens.MODIFIER_LIST)
return self.factory.method(name=ident.text, type=type, parent=self)

- def acceptVarDeclaration(self, node, memo):
- """ Creates a new expression for a variable declaration. """
- # this is strikingly similar to
- # MethodContent.acceptVarDeclaration; merge and fix.
- mods = node.firstChildOfType(tokens.MODIFIER_LIST)
- decl = node.firstChildOfType(tokens.VAR_DECLARATOR_LIST)
- for vard in decl.childrenOfType(tokens.VAR_DECLARATOR):
- ident = vard.firstChildOfType(tokens.IDENT)
- self.variables.append(ident.text)
- expr = vard.firstChildOfType(tokens.EXPR)
- child = self.factory.expr(left=ident.text, parent=self)
- assgn = child.pushRight(' = ')
- arinit = vard.firstChildOfType(tokens.ARRAY_INITIALIZER)
- if arinit:
- assgn.right = exp = self.factory.expr(fs='['+FS.lr+']', parent=child)
- children = list(arinit.childrenOfType(tokens.EXPR))
- for c in children:
- fs = FS.lr if c is children[-1] else FS.lr + ', '
- exp.left = self.factory.expr(fs=fs, parent=child)
- exp.left.walk(c, memo)
- exp.right = exp = self.factory.expr(parent=child)
- elif expr:
- assgn.walk(expr, memo)
- else:
- typ = node.firstChildOfType(tokens.TYPE)
- typ = typ.children[0].text
- val = assgn.pushRight()
- val.left = '{0}()'.format(typ) # wrong
- return self
-
def acceptVoidMethodDecl(self, node, memo):
""" Accept and process a void method declaration. """
ident = node.firstChildOfType(tokens.IDENT)
@@ -341,10 +380,17 @@
ifStat.expr.walk(parNode, memo)
breakStat = self.factory.statement('break', parent=ifStat)

+ goodExprParents = (
+ tokens.BLOCK_SCOPE,
+ tokens.CASE,
+ tokens.DEFAULT,
+ tokens.FOR_EACH
+ )
+
def acceptExpr(self, node, memo):
""" Creates a new expression. """
- goodParents = (tokens.BLOCK_SCOPE, tokens.CASE, tokens.DEFAULT,
tokens.FOR_EACH)
- if node.parentType in goodParents: # wrong
+ # this works but isn't precise
+ if node.parentType in self.goodExprParents:
return self.factory.expr(parent=self)

def acceptFor(self, node, memo):
@@ -466,45 +512,19 @@
finStat = self.factory.statement('finally', fs=FS.lc, parent=self)
finStat.walk(finNode, memo)

+ goodReturnParents = (
+ tokens.BLOCK_SCOPE,
+ )
+
def acceptReturn(self, node, memo):
""" Creates a new return expression. """
- if node.parentType == tokens.BLOCK_SCOPE: # wrong
+ # again, this works but isn't as precise as it should be
+ if node.parentType in self.goodReturnParents:
expr = self.factory.expr(left='return', parent=self)
if node.children:
expr.fs, expr.right = FS.lsr, self.factory.expr(parent=expr)
expr.right.walk(node, memo)

- def acceptVarDeclaration(self, node, memo):
- """ Creates a new expression for a variable declaration. """
- varDecls = node.firstChildOfType(tokens.VAR_DECLARATOR_LIST)
- for varDecl in varDecls.childrenOfType(tokens.VAR_DECLARATOR):
- ident = varDecl.firstChildOfType(tokens.IDENT)
- self.variables.append(ident.text)
- identExp = self.factory.expr(left=ident.text, parent=self)
- assgnExp = identExp.pushRight(' = ')
- declExp = varDecl.firstChildOfType(tokens.EXPR)
- declArr = varDecl.firstChildOfType(tokens.ARRAY_INITIALIZER)
- if declExp:
- assgnExp.walk(declExp, memo)
- elif declArr:
- assgnExp.right = exp = self.factory.expr(fs='['+FS.lr+']')
- children = list(declArr.childrenOfType(tokens.EXPR))
- for child in children:
- fs = FS.lr if child is children[-1] else FS.lr + ', '
- exp.left = self.factory.expr(fs=fs)
- exp.left.walk(child, memo)
- exp.right = exp = self.factory.expr()
- else:
- if
node.firstChildOfType(tokens.TYPE).firstChildOfType(tokens.ARRAY_DECLARATOR_LIST):
- val = assgnExp.pushRight()
- val.left = '[]'
- else:
- typ = node.firstChildOfType(tokens.TYPE)
- typ = typ.children[0].text
- val = assgnExp.pushRight()
- val.left = '{0}()'.format(typ) # wrong
- return self
-
def acceptWhile(self, node, memo):
""" Accept and process a while block. """
# WHILE - PARENTESIZED_EXPR - BLOCK_SCOPE
@@ -514,18 +534,14 @@
whileStat.walk(blkNode, memo)


-class Method(ModifiersAcceptor, MethodContent):
+class Method(VarAcceptor, ModifiersAcceptor, MethodContent):
""" Method -> accepts AST branches for method-level objects.

"""
def acceptFormalParamStdDecl(self, node, memo):
""" Accept and process a single parameter declaration. """
ident = node.firstChildOfType(tokens.IDENT)
- ptype = list(node.findChildrenOfType(tokens.TYPE))[0] # wrong
- try:
- ptype = list(ptype.findChildrenOfType(tokens.IDENT))[0].text
- except (IndexError, ):
- ptype = ptype.firstChild().text
+ ptype = self.nodeTypeToString(node)
self.parameters.append(self.makeParam(ident.text, ptype))
return self

@@ -596,7 +612,7 @@
return acceptPreformatted

acceptArrayElementAccess = makeNodePreformattedExpr(FS.l + '[' + FS.r
+ ']')
- acceptCastExpr = makeNodePreformattedExpr(FS.l + '(' + FS.r + ')' ) #
wrong.
+ acceptCastExpr = makeNodePreformattedExpr(FS.l + '(' + FS.r + ')' ) #
problem?
acceptDiv = makeNodePreformattedExpr(FS.l + ' / ' + FS.r)
acceptLogicalAnd = makeNodePreformattedExpr(FS.l + ' and ' + FS.r)
acceptLogicalNot = makeNodePreformattedExpr('not ' + FS.l)
@@ -655,11 +671,11 @@

def acceptClassConstructorCall(self, node, memo):
""" Accept and process a class constructor call. """
- self.acceptMethodCall(node, memo) # probably wrong
+ self.acceptMethodCall(node, memo)
typeIdent = node.firstChildOfType(tokens.QUALIFIED_TYPE_IDENT)
if typeIdent and typeIdent.children:
- ids = [self.altIdent(child.text) for child in typeIdent.children]
- self.left = '.'.join(ids) # wrong
+ names = [self.altIdent(child.text) for child in typeIdent.children]
+ self.left = '.'.join(names)

def acceptDot(self, node, memo):
""" Accept and process a dotted expression. """
@@ -674,7 +690,7 @@

def acceptIdent(self, node, memo):
""" Accept and process an ident expression. """
- self.left = name = self.altIdent(node.text)
+ self.left = self.altIdent(node.text)

def acceptInstanceof(self, node, memo):
""" Accept and process an instanceof expression. """
=======================================
--- /trunk/java2python/config/default.py Fri Jul 30 23:35:02 2010
+++ /trunk/java2python/config/default.py Thu Aug 12 11:20:01 2010
@@ -56,12 +56,18 @@
basic.simpleDocString,
]

+
interfaceHeadHandlers = [
basic.simpleDocString,
'__metaclass__ = ABCMeta',
]


+interfacePostWalkMutators = [
+ basic.zopeInterfaceMethodMutator,
+]
+
+
methodHeadHandlers = [
basic.simpleDocString,
]
=======================================
--- /trunk/java2python/mod/basic.py Fri Jul 30 23:35:02 2010
+++ /trunk/java2python/mod/basic.py Thu Aug 12 11:20:01 2010
@@ -23,6 +23,7 @@
def simpleImports(module, expr):
module.factory.expr(parent=module, left=expr, fs='import {left}')

+
def commentedPackages(module, expr):
module.factory.comment(parent=module, left=expr, fs='package: {left}')

@@ -39,7 +40,7 @@
with open(initname, 'w') as initfile:
initfile.write('from pkgutil import extend_path\n')
initfile.write('__path__ = extend_path(__path__, __name__)\n')
- ## wrong
+ # wrong
initfile.write('\nfrom {0} import {0}\n'.format(module.name))
info('created __init__.py file for package %s.', expr)

@@ -124,15 +125,12 @@
yield line


-# this function implies that there should be a separate modification
-# stage where client code like this can mutate the templates generated
-# by the compiler. this works, but it not really what the prologue
-# handlers are meant to do. the various interface functions fall into
-# the category of mutators also.
-
-# also, the output handers seem to be a special case of this
-# desired mutator-function.
-
def classContentSort(obj):
obj.children.sort(lambda x, y:-1 if x.isClass else 1)

+
+def zopeInterfaceMethodMutator(obj):
+ for method in [c for c in obj.children if c.isMethod]:
+ if method.parameters and method.parameters[0]['name'] == 'self':
+ method.parameters.pop(0)
+
=======================================
--- /trunk/test/Anno1.java Thu Aug 5 14:17:51 2010
+++ /trunk/test/Anno1.java Thu Aug 12 11:20:01 2010
@@ -1,17 +1,27 @@
-@interface AnnotationExample {
- int id();
+@interface AnnoEx {
String title() default "simple string";
+ int value() default 0;
}


-@AnnotationExample(id=1)
+
+
+
+@AnnoEx(value=3, title="asdf")
class Anno1 {
+
+ @AnnoEx
+ public static void zero() {}
+
+ @AnnoEx(1)
+ public static void one() {}
+
+ @AnnoEx(value=2, title="bar")
+ public static void two() {}
+
public static void main(String[] args) {
System.out.println("a");
}

- @AnnotationExample(id=2, title="test method")
- public static int foo(int a) {
- return 2;
- }
-}
+
+}
=======================================
--- /trunk/test/Class10.java Mon Jul 12 16:39:08 2010
+++ /trunk/test/Class10.java Thu Aug 12 11:20:01 2010
@@ -10,6 +10,12 @@
public int move(int dx, int dy) {
return 0;
}
+
+ public void other(Class10 v) {
+ }
+
+ public void other() {
+ }

public static void main(String[] args) {
Class10 i = new Class10();
=======================================
--- /trunk/test/Makefile Thu Aug 5 14:17:51 2010
+++ /trunk/test/Makefile Thu Aug 12 11:20:01 2010
@@ -34,7 +34,7 @@


%.py: %.class
- @$(j2py) -i $(addsuffix .java, $(basename $@)) -o $@
-c ./configs/__init__.py
+ @$(j2py) -i $(addsuffix .java, $(basename $@)) -o $@ -d configs

%: %.py
@bash -c "diff -q <($(python) $(addsuffix .py, $@)) <(java -ea $@)" &&
echo "[PASS] $@"
=======================================
--- /trunk/test/ReallyQuickTest.java Sat Jul 24 01:19:21 2010
+++ /trunk/test/ReallyQuickTest.java Thu Aug 12 11:20:01 2010
@@ -1,8 +1,7 @@
class ReallyQuickTest {
- public eggs() {
-
- fu(a+1, b+2, c+3);
-
+ public void method() {
+ Fu.Bar.Baz a, b, c;
+ Eggs z = new Eggs(44, 33);
}

}

Reply all
Reply to author
Forward
0 new messages