Added:
/branches/0.5/java2python/lang/JavaDoc.g
/branches/0.5/java2python/mod/basic.py
/branches/0.5/java2python/mod/transform.py
/branches/0.5/test/Array4.java
/branches/0.5/test/Expr2.java
/branches/0.5/test/Ternary1.java
Deleted:
/branches/0.5/java2python/mod/transforms.py
/branches/0.5/test/QuickArray.java
/branches/0.5/test/QuickTest.java
Modified:
/branches/0.5/java2python/compiler/__init__.py
/branches/0.5/java2python/compiler/block.py
/branches/0.5/java2python/compiler/template.py
/branches/0.5/java2python/compiler/visitor.py
/branches/0.5/java2python/config/default.py
/branches/0.5/java2python/lang/Java.g
/branches/0.5/java2python/lang/base.py
/branches/0.5/java2python/mod/__init__.py
/branches/0.5/test/Class4.java
/branches/0.5/test/Expr1.java
/branches/0.5/test/Makefile
/branches/0.5/test/ReallyQuickTest.java
=======================================
--- /dev/null
+++ /branches/0.5/java2python/lang/JavaDoc.g Sat Jul 24 01:19:21 2010
@@ -0,0 +1,133 @@
+/*
+ * Javadoc.g
+ * Copyright (c) 2007 David Holroyd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+grammar JavaDoc;
+
+
+options {
+ k=3;
+ output=AST;
+ language=Python;
+ ASTLabelType=CommonTree;
+}
+
+
+tokens {
+ JAVADOC;
+ INLINE_TAG;
+ DESCRIPTION;
+ PARA_TAG;
+ TEXT_LINE;
+}
+
+
+commentBody
+ : d=description paragraphTag* EOF
+ -> ^(JAVADOC description paragraphTag*)
+ ;
+
+
+description
+ : textLine*
+ -> ^(DESCRIPTION textLine*)
+ ;
+
+
+textLine
+ : textLineStart textLineContent* (NL | EOF!)
+ | NL
+ ;
+
+
+textLineStart
+ : (LBRACE ATWORD)=> inlineTag
+ | WORD | STARS | WS | LBRACE | RBRACE | AT
+ ;
+
+
+textLineContent
+ : (LBRACE ATWORD)=> inlineTag
+ | WORD | STARS | WS | LBRACE | RBRACE | AT | ATWORD
+ ;
+
+
+inlineTag
+ : LBRACE ATWORD inlineTagContent* RBRACE
+ -> ^(INLINE_TAG ATWORD inlineTagContent*)
+ ;
+
+
+inlineTagContent
+ : WORD | STARS | WS | AT | NL
+ ;
+
+
+paragraphTag
+ : ATWORD paragraphTagTail
+ -> ^(PARA_TAG ATWORD paragraphTagTail)
+ ;
+
+
+paragraphTagTail
+ : textLineContent* (NL textLine* | EOF)
+ -> textLineContent* NL? textLine*
+ ;
+
+
+STARS
+ : '*'+
+ ;
+
+
+LBRACE
+ : '{'
+ ;
+
+
+RBRACE
+ : '}'
+ ;
+
+
+AT
+ : '@'
+ ;
+
+
+WS
+ : (' ' | '\t')+
+ ;
+
+
+NL options {k=*;}
+ : ('\r\n' | '\r' | '\n') WS? (STARS WS?)?
+ ;
+
+
+ATWORD
+ : '@' WORD WORD_TAIL
+ ;
+
+
+WORD
+ : ~('\n' | ' ' | '\r' | '\t' | '{' | '}' | '@') WORD_TAIL
+ ;
+
+
+fragment WORD_TAIL
+ : (~('\n' | ' ' | '\r' | '\t' | '{' | '}'))*
+ ;
=======================================
--- /dev/null
+++ /branches/0.5/java2python/mod/basic.py Sat Jul 24 01:19:21 2010
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from itertools import count
+from re import sub as rxsub
+
+
+def simpleShebang(module):
+ yield '#!/usr/bin/env python'
+
+
+def simpleDocString(obj):
+ yield '""" generated source for {0} {1}'.format(obj.typeName, obj.name)
+ yield ''
+ yield '"""'
+
+
+def configImports(module):
+ if 0:
+ yield ''
+
+
+def commentedImports(module):
+ if 0:
+ yield ''
+
+
+def commentedPackageName(module):
+ if 0:
+ yield ''
+
+
+def enumConstInts(enum, index, name):
+ return str(index)
+
+
+def enumConstStrings(enum, index, name):
+ return repr(name)
+
+
+scriptTemplate = """\n
+if __name__ == '__main__':
+{indent}import sys
+{indent}{name}.main(sys.argv)"""
+
+
+def scriptMainStanza(module):
+ def filterClass(x):
+ return x.isClass and x.name==module.name
+
+ def filterMethod(x):
+ return x.isMethod and x.isPublic and x.isStatic and \
+ x.isVoid and x.name=='main'
+
+ for cls in [c for c in module.children if filterClass(c)]:
+ if [m for m in cls.children if filterMethod(m)]:
+ yield scriptTemplate.format(indent=module.indent, name=module.name)
+ break
+
+
+def outputSubs(obj, text):
+ subsname = '{0}OutputSubs'.format(obj.typeName)
+ subs = obj.config.every(subsname, [])
+ for sub in subs:
+ for pattern, repl in sub:
+ text = rxsub(pattern, repl, text)
+ return text
+
+
+def mapClassType(obj):
+ bases = obj.bases or ('object', )
+ for name in bases:
+ yield name
+
+
+def overloadedClassMethods(method):
+ """
+ NB: this implementation does not handle overloaded static (or
+ class) methods, only instance methods.
+ """
+ cls = method.parent
+ methods = [o for o in cls.children if o.isMethod and
o.name==method.name]
+ if len(methods) == 1:
+ return
+ for i, m in enumerate(methods[1:]):
+ args = [p['type'] for p in m.parameters]
+ args = ', '.join(args)
+ m.decorators.append('{0}.register({1})'.format(method.name, args))
+ m.name = '{0}_{1}'.format(method.name, i)
+ # for this one only:
+ yield 'overloaded'
+
+
+def maybeClassMethod(method):
+ if method.isStatic and 'classmethod' not in method.decorators:
+ yield 'classmethod'
+
+
+def simpleInterfaces(method):
+ mkExpr = partial(Expression, module.config,
+ format='raise NotImplementedError({left})')
+ for iface in module.interfaces:
+ for method in iface.methods:
+ expr = mkExpr(left='"Method \'%s\' is abstract"' % method.name)
+ method.children.insert(0, expr)
+
+
+def globalNameCounter(original, counter=count()):
+ return '__{0}_{1}'.format(original, counter.next())
+
=======================================
--- /dev/null
+++ /branches/0.5/java2python/mod/transform.py Sat Jul 24 01:19:21 2010
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import types
+from keyword import kwlist
+
+
+def renameIdents():
+ typs = [getattr(types, n) for n in dir(types) if not n.startswith('_')]
+ names = [t.__name__ for t in typs if isinstance(t, type)]
+ return ['None', 'True', 'False', ] + names + kwlist
+
+
+renameIdents = renameIdents()
+
+
+def keywordSafeIdent(node, config):
+ ident = node.token.text
+ if ident in renameIdents:
+ node.token.text = '%s_' % ident
+
+
+def constXform(v):
+ def xform(node, config):
+ node.token.text = v
+ return xform
+
+
+null2None = constXform('None')
+false2False = constXform('False')
+true2True = constXform('True')
+
+
+def syntaxSafeFloatLiteral(node, config):
+ value = node.token.text
+ if value.startswith('.'):
+ value = '0' + value
+ if value.endswith(('f', 'd')):
+ value = value[:-1]
+ elif value.endswith(('l', 'L')):
+ value = value[:-1] + 'L'
+ node.token.text = value
+
+
+def typeSub(node, config):
+ ident = node.token.text
+ subs = config.last('typeSubs')
+ if ident in subs:
+ node.token.text = subs[ident]
=======================================
--- /dev/null
+++ /branches/0.5/test/Array4.java Sat Jul 24 01:19:21 2010
@@ -0,0 +1,11 @@
+public class Array4 {
+ public static void main(String[] args) {
+ Integer b[] = {4, 5, 6, 12};
+ int x = 0;
+int y = 1;
+
+ System.out.println(b[y+x+x+1+x+y].toString());
+ System.out.println(b[1].toString());
+ System.out.println(b[2].toString());
+ }
+}
=======================================
--- /dev/null
+++ /branches/0.5/test/Expr2.java Sat Jul 24 01:19:21 2010
@@ -0,0 +1,36 @@
+class Expr2 {
+ public static void main(String[] args) {
+ int x = 0;
+ if (x++ == 0) {
+ System.out.println(x);
+ }
+ System.out.println(x);
+
+
+ int y = 0;
+ if (++y == 1) {
+ System.out.println(y);
+ }
+ System.out.println(y);
+
+
+ int z = 0;
+ if (--z == -1) {
+ System.out.println(z);
+ }
+ System.out.println(z);
+
+
+ int w = 0;
+ if (w-- == 0) {
+ System.out.println(w);
+ }
+ System.out.println(w);
+
+
+ for (int i = 0; i<3; ++i) {
+ System.out.println(i);
+ }
+
+ }
+}
=======================================
--- /dev/null
+++ /branches/0.5/test/Ternary1.java Sat Jul 24 01:19:21 2010
@@ -0,0 +1,6 @@
+final class Ternary1 extends Object {
+ public static void main(String[] args) {
+ System.out.println(1 > 0 ? 'a' : 'b');
+ System.out.println(1 == 0 ? 'a' : 'b');
+ }
+}
=======================================
--- /branches/0.5/java2python/mod/transforms.py Mon Jul 19 16:53:47 2010
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import types
-from keyword import kwlist
-
-
-def renameIdents():
- typs = [getattr(types, n) for n in dir(types) if not n.startswith('_')]
- names = [t.__name__ for t in typs if isinstance(t, type)]
- return ['None', 'True', 'False', ] + names + kwlist
-
-
-renameIdents = renameIdents()
-
-
-def keywordSafeIdent(node, config):
- ident = node.token.text
- if ident in renameIdents:
- node.token.text = '%s_' % ident
-
-
-def constXform(v):
- def xform(node, config):
- node.token.text = v
- return xform
-
-
-null2None = constXform('None')
-false2False = constXform('False')
-true2True = constXform('True')
-
-
-def syntaxSafeFloatLiteral(node, config):
- value = node.token.text
- if value.startswith('.'):
- value = '0' + value
- if value.endswith(('f', 'd')):
- value = value[:-1]
- elif value.endswith(('l', 'L')):
- value = value[:-1] + 'L'
- node.token.text = value
-
-
-def typeSub(node, config):
- ident = node.token.text
- subs = config.last('typeSubs')
- if ident in subs:
- node.token.text = subs[ident]
=======================================
--- /branches/0.5/test/QuickArray.java Fri Jul 9 00:50:21 2010
+++ /dev/null
@@ -1,11 +0,0 @@
-public class QuickArray {
- public static void main(String[] args) {
- Integer b[] = {4, 5, 6, 12};
- int x = 0;
-int y = 1;
-
- System.out.println(b[y+x+x+1+x+y].toString());
- System.out.println(b[1].toString());
- System.out.println(b[2].toString());
- }
-}
=======================================
--- /branches/0.5/test/QuickTest.java Thu Jul 1 15:12:49 2010
+++ /dev/null
@@ -1,6 +0,0 @@
-final class QuickTest extends Object {
- public static void main(String[] args) {
- System.out.println(1 > 0 ? 'a' : 'b');
- System.out.println(1 == 0 ? 'a' : 'b');
- }
-}
=======================================
--- /branches/0.5/java2python/compiler/__init__.py Mon Jul 19 16:53:47 2010
+++ /branches/0.5/java2python/compiler/__init__.py Sat Jul 24 01:19:21 2010
@@ -3,7 +3,8 @@
from java2python.compiler.block import Module
from java2python.lang import (
- Lexer, Parser, LocalSourceStream, LocalTokenStream, LocalTreeAdaptor,
+ Lexer, Parser,
+ LocalSourceStream, LocalTokenStream, LocalTreeAdaptor,
walkTreeSelector,
)
@@ -22,11 +23,27 @@
def transformAST(tree, config):
- for selector, call in config.handlers('transforms'):
+ for selector, call in config.handlers('astTransforms'):
for node in walkTreeSelector(tree, selector):
call(node, config)
+
+def buildJavaDocAST(source):
+ from java2python.lang.JavaDocLexer import JavaDocLexer
+ from java2python.lang.JavaDocParser import JavaDocParser
+
+ lexer = JavaDocLexer(LocalSourceStream(source))
+ parser = JavaDocParser(LocalTokenStream(lexer))
+
+ scope = parser.commentBody()
+ return scope.tree
+
+
+def walkJavaDoc(tree, callback=lambda x:None):
+ pass
+
+
if __name__ == '__main__':
import sys
tree = buildAST(open(sys.argv[1]).read())
=======================================
--- /branches/0.5/java2python/compiler/block.py Mon Jul 19 16:53:47 2010
+++ /branches/0.5/java2python/compiler/block.py Sat Jul 24 01:19:21 2010
@@ -112,6 +112,8 @@
yield item
prev = item
body = list(super(ClassTemplate, self).iterBody())
+ if self.config.last('reorderClassDefs'):
+ body.sort(lambda x, y:-1 if x.isClass else 1)
docs = list(iterDocString())
more = [self.factory.expr(left='pass')] if not (body or docs) else []
return chain(docs, iter(body) if more else intersperseLines(body), more)
@@ -128,10 +130,10 @@
""" Accept and ignore an annotation declaration. """
## this overrides the TypeDeclVisitorMixin implementation and
## ignores AT tokens; they're sent within the class modifier
- ## list and we have to use for them here.
+ ## list and we have no use for them here.
def acceptAnnotationMethodDecl(self, node, memo):
- """ Accept and process a typed method declaration. """
+ """ Accept and process an annotation method declaration. """
ident = node.firstChildOfType(tokens.IDENT)
type = node.firstChildOfType(tokens.TYPE).children[0].text
return self.factory.method(name=ident.text, type=type, parent=self)
@@ -167,14 +169,17 @@
for mod in node.children:
if mod.type == tokens.AT:
## needs args, too
- self.decorators.append(mod.firstChildOfType(tokens.IDENT).text)
+ deco = '{0}()'.format(mod.firstChildOfType(tokens.IDENT).text)
+ self.decorators.append(deco)
else:
self.modifiers.append(mod.text)
return self
def acceptVarDeclaration(self, node, memo):
""" Creates a new expression for a variable declaration. """
- #mods = node.childrenOfType(tokens.MODIFIER_LIST)
+ ## this is strikingly similar to
+ ## MethodContentVisitor.acceptVarDeclaration; merge and fix.
+
decl = node.firstChildOfType(tokens.VAR_DECLARATOR_LIST)
for vard in decl.childrenOfType(tokens.VAR_DECLARATOR):
ident = vard.firstChildOfType(tokens.IDENT)
@@ -182,7 +187,16 @@
expr = vard.firstChildOfType(tokens.EXPR)
child = self.factory.expr(left=ident.text, parent=self)
assgn = child.pushRight(' = ')
- if expr:
+ 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)
@@ -199,7 +213,18 @@
class AnnotationTemplate(ClassTemplate):
""" AnnotationTemplate -> formatting for annotations converted to
Python classes. """
-
+ def __init__(self, config, name=None, type=None, parent=None):
+ super(AnnotationTemplate, self).__init__(config, name, type, parent)
+
+ m = self.factory.method(parent=self, name='__init__')
+ m.parameters.append(self.makeParam('*args', 'list'))
+ m.parameters.append(self.makeParam('**kwds', 'dict'))
+ ## set attributes from kwds?
+
+ m = self.factory.method(parent=self, name='__call__')
+ m.parameters.append(self.makeParam('klass', 'type'))
+ self.factory.expr(parent=m, fs='setattr(klass, self.__class__.__name__,
self)')
+ self.factory.expr(parent=m, fs='return klass')
class AnnotationVisitor(ClassVisitor):
""" AnnotationVisitor -> accepts AST branches for Java annotations. """
@@ -431,6 +456,7 @@
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)
@@ -446,10 +472,14 @@
exp.left.walk(child, memo)
exp.right = exp = self.factory.expr()
else:
- typ = node.firstChildOfType(tokens.TYPE)
- typ = typ.children[0].text
- val = assgnExp.pushRight()
- val.left = '{0}()'.format(typ) # wrong
+ 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 acceptForEach(self, node, memo):
@@ -542,6 +572,12 @@
acceptLessOrEqual = equalityExpression
acceptLessThan = equalityExpression
acceptNotEqual = equalityExpression
+ acceptOr = equalityExpression
+ acceptXor = equalityExpression
+ acceptAnd = equalityExpression
+ acceptShiftRight = equalityExpression
+ acceptShiftLeft = equalityExpression
+ acceptMod = equalityExpression
def assignExpression(self, node, memo):
""" Accept and processes an assignment expression (Python statement). """
@@ -570,6 +606,15 @@
""" Accept and process an ident expression. """
self.left = name = self.altIdent(node.text)
+ def acceptInstanceof(self, node, memo):
+ """ Accept and process an instanceof expression. """
+ self.fs = 'isinstance({right}, ({left}, ))'
+ self.right = self.factory.expr(parent=self)
+ self.right.walk(node.firstChildOfType(tokens.IDENT), memo)
+ self.left = self.factory.expr(parent=self)
+ self.left.walk(node.firstChildOfType(tokens.TYPE), memo)
+
+
def acceptClassConstructorCall(self, node, memo):
""" Accept and process a class constructor call. """
self.acceptMethodCall(node, memo) # probably wrong
@@ -581,35 +626,69 @@
self.fs = FS.l + '(' + FS.r + ')'
self.left = expr(parent=self)
self.left.walk(node.firstChild(), memo)
+ children = node.firstChildOfType(tokens.ARGUMENT_LIST).children
self.right = arg = expr(parent=self)
- nodes = node.firstChildOfType(tokens.ARGUMENT_LIST).children
- for tree in nodes:
- fs = FS.r + (', ' if tree is not nodes[-1] else '')
- arg.walk(tree, memo)
+ for child in children:
+ fs = FS.r + (', ' if child is not children[-1] else '')
arg.left = expr(fs=fs, parent=self)
- arg.left.walk(tree, memo)
- arg.right = arg = expr()
-
- def acceptPostInc(self, node, memo):
- """ """
- self.fs = FS.l + ' += 1'
- self.left = self.factory.expr()
- return self.left
+ arg.left.walk(child, memo)
+ arg.right = arg = expr(parent=self)
+
+ def acceptDot(self, node, memo):
+ expr = self.factory.expr
+ self.fs = FS.l + '.' + FS.r
+ self.left, self.right = visitors = expr(), expr()
+ self.zipWalk(node.children, visitors, memo)
def makeAcceptPreFormatted(fs):
def accept(self, node, memo):
expr = self.factory.expr
self.fs = fs
- self.left, self.right = visitors = expr(), expr()
- self.zipWalk(node.children, visitors, memo)
+ self.left, self.right = vs = expr(parent=self), expr(parent=self)
+ self.zipWalk(node.children, vs, memo)
return accept
- acceptDot = makeAcceptPreFormatted(FS.l + '.' + FS.r)
- acceptDiv = makeAcceptPreFormatted(FS.l + ' / ' +FS.r)
- acceptMinus = makeAcceptPreFormatted(FS.l + ' - ' +FS.r)
- acceptPlus = makeAcceptPreFormatted(FS.l + ' + ' +FS.r)
- acceptStar = makeAcceptPreFormatted(FS.l + ' *' +FS.r)
acceptArrayElementAccess = makeAcceptPreFormatted(FS.l + '[' + FS.r
+ ']')
+ acceptDiv = makeAcceptPreFormatted(FS.l + ' / ' + FS.r)
+ acceptLogicalAnd = makeAcceptPreFormatted(FS.l + ' and ' + FS.r)
+ acceptLogicalOr = makeAcceptPreFormatted(FS.l + ' or ' + FS.r)
+ acceptLogicalNot = makeAcceptPreFormatted('not ' + FS.l)
+
+ acceptMinus = makeAcceptPreFormatted(FS.l + ' - ' + FS.r)
+ acceptPlus = makeAcceptPreFormatted(FS.l + ' + ' + FS.r)
+ acceptStar = makeAcceptPreFormatted(FS.l + ' * ' + FS.r)
+ acceptUnaryPlus = makeAcceptPreFormatted('+' + FS.l)
+ acceptUnaryMinus = makeAcceptPreFormatted('-' + FS.l)
+ acceptNot = makeAcceptPreFormatted('~' + FS.l)
+
+ ## wrong.
+ acceptCastExpr = makeAcceptPreFormatted(FS.l + '(' + FS.r + ')' )
+
+ def makeAcceptPrePost(suffix, pre=False):
+ def accept(self, node, memo):
+ expr = self.factory.expr
+ if node.withinExpr:
+ ident = node.firstChildOfType(tokens.IDENT).text
+ handler = self.configHandler('VariableNaming')
+ name = handler(ident)
+ block = self.parents(lambda x:x.isMethod).next()
+ if pre:
+ left = ident
+ else:
+ left = name
+ block.insertChild(expr(fs=FS.l+' = '+FS.r, left=name, right=ident))
+ self.left = expr(parent=self, fs=FS.l, left=left)
+ block.insertChild(expr(fs=FS.l + suffix, left=ident))
+ else:
+ self.fs = FS.l + suffix
+ self.left, self.right = vs = expr(parent=self), expr(parent=self)
+ self.zipWalk(node.children, vs, memo)
+ return accept
+
+ acceptPostInc = makeAcceptPrePost(' += 1')
+ acceptPreInc = makeAcceptPrePost(' += 1', pre=True)
+ acceptPostDec = makeAcceptPrePost(' -= 1')
+ acceptPreDec = makeAcceptPrePost(' -= 1', pre=True)
def acceptSuperConstructorCall(self, node, memo):
cls = self.parents(lambda c:c.isClass).next()
@@ -617,6 +696,11 @@
self.right = self.factory.expr(fs=fs, left=cls.name)
return self.right
+ def acceptStaticArrayCreator(self, node, memo):
+ self.right = self.factory.expr(fs='[None]*{left}')
+ self.right.left = self.factory.expr()
+ self.right.left.walk(node.firstChildOfType(tokens.EXPR), memo)
+
def acceptThis(self, node, memo):
self.pushRight('self')
=======================================
--- /branches/0.5/java2python/compiler/template.py Mon Jul 19 16:53:47 2010
+++ /branches/0.5/java2python/compiler/template.py Sat Jul 24 01:19:21 2010
@@ -72,6 +72,10 @@
if self.isMethod:
self.parameters.append(self.makeParam('self', 'object'))
+ def insertChild(self, child, index=-1):
+ self.children.insert(index, child)
+ child.parent = self
+
def __repr__(self):
""" Returns the debug string representation of this template. """
name = white('name:') + cyan(self.name) if self.name else ''
@@ -116,11 +120,13 @@
""" Writes the Python source code for this template to the given file. """
indent, isNotNone = level * self.indent, lambda x:x is not None
for line in ifilter(isNotNone, self.iterPrologue()):
- fd.write('{0}{1}\n'.format(indent, line))
+ line = '{0}{1}\n'.format(indent, line)
+ fd.write(line if line.strip() else '\n')
for item in self.iterBody():
item.dump(fd, level+1)
for line in ifilter(isNotNone, self.iterEpilogue()):
- fd.write('{0}{1}\n'.format(indent, line))
+ line = '{0}{1}\n'.format(indent, line)
+ fd.write(line if line.strip() else '\n')
def dumps(self, level=0):
""" Dumps this template to a string. """
@@ -196,13 +202,17 @@
def __repr__(self):
""" Returns the debug string representation of this template. """
- parts = [blue(self.typeName)]
+ parts, parent, showfs = [blue(self.typeName)], self.parent, True
if isinstance(self.left, (basestring, )) and self.left:
- parts.append(white('left:')+yellow(self.left))
+ parts.append(white('left:') + yellow(self.left))
+ showfs = False
if isinstance(self.right, (basestring, )) and self.right:
- parts.append(white('right:')+yellow(self.right))
+ parts.append(white('right:') + yellow(self.right))
+ showfs = False
+ if showfs:
+ parts.append(white('format:') + yellow(self.fs))
if self.tail:
- parts.append(white('tail:')+yellow(self.tail))
+ parts.append(white('tail:') + yellow(self.tail))
return ' '.join(parts)
def __str__(self):
@@ -211,7 +221,8 @@
def dump(self, fd, level=0):
""" Writes the Python source code for this template to the given file. """
- fd.write('{0}{1}\n'.format(self.indent*level, self))
+ line = '{0}{1}\n'.format(self.indent*level, self)
+ fd.write(line if line.strip() else '\n')
def dumpRepr(self, fd, level=0):
""" Writes a debug string for this template to the given file. """
@@ -230,7 +241,7 @@
class BaseCommentTemplate(BaseExpressionTemplate):
- """ BaseStatementTemplate -> base class for formatting Python
comments. """
+ """ BaseCommentTemplate -> base class for formatting Python
comments. """
def __repr__(self):
""" Returns the debug string representation of this comment. """
@@ -247,6 +258,7 @@
super(BaseStatementTemplate, self).__init__(config, parent=parent)
self.keyword = keyword
self.expr = self.factory.expr(left=keyword, fs=fs)
+ self.expr.parent = self
def __repr__(self):
""" Returns the debug string representation of this statement. """
=======================================
--- /branches/0.5/java2python/compiler/visitor.py Mon Jul 19 15:02:15 2010
+++ /branches/0.5/java2python/compiler/visitor.py Sat Jul 24 01:19:21 2010
@@ -65,7 +65,7 @@
#pred = lambda k:k.type in tokens.commentTypes and k.index not in cache
#for token in ifilter(pred, parser.input.tokens[0:index]):
for token in parser.input.tokens[memo.last:index]:
- if (token.type != 181 and token.type != 182) or token.index in cache:
+ if token.type not in tokens.commentTypes or token.index in cache:
continue
cache.add(token.index)
isexp = getattr(block, 'isExpression', False)
=======================================
--- /branches/0.5/java2python/config/default.py Mon Jul 19 16:53:47 2010
+++ /branches/0.5/java2python/config/default.py Sat Jul 24 01:19:21 2010
@@ -1,126 +1,145 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-#
+
# This is the default configuration file for java2python. Unless
# explicity disabled with the '-n' or '--nodefaults' options, the j2py
-# script will reference this file for runtime configuration.
-#
-import java2python.mod
-
-
-## leading indent character or characters.
-indentPrefix = ' '
-
-
-## prefix for comments.
-commentPrefix = '## '
-
-
-## generator-functions that yield lines for a module prologue.
+# script will import this module for runtime configuration.
+
+from java2python.mod import basic, transform
+from java2python.lang.selector import *
+
+
+# Leading indent character or characters. Read PEP 8 before you
+# override this.
+indentPrefix = ' '*4
+
+
+# Prefix character or characters for comments. Again, you should read
+# PEP 8 before you override this.
+commentPrefix = '# '
+
+
+# When true, class definitions will be bubbled to the top of their
+# container (outer class or module).
+reorderClassDefs = True
+
+
+# These generator-functions yield lines for a module prologue.
modulePrologueHandlers = [
- java2python.mod.simpleShebang,
- java2python.mod.simpleDocString,
- java2python.mod.configImports,
- java2python.mod.commentedImports,
- java2python.mod.commentedPackageName,
+ basic.simpleShebang,
+ basic.simpleDocString,
+ basic.configImports,
+ basic.commentedImports,
+ basic.commentedPackageName,
]
-## generator-functions that yield lines for a module epilogue.
+# These generator-functions yield lines for a module epilogue.
moduleEpilogueHandlers = [
- java2python.mod.scriptMainStanza,
+ basic.scriptMainStanza,
]
-## generator-functions that yield (possibly modified) source strings
-## for a module.
+# These generator-functions yield (possibly modified) source strings
+# for a module. The 'outputSubs' handler references the list of
+# regular expression substitutions near the end of this module.
moduleOutputHandlers = [
- java2python.mod.outputSubs,
+ basic.outputSubs,
]
-## generator-functions that yield doc strings for classes.
+# These generator-functions yield doc strings for classes.
classDocStringHandlers = [
- java2python.mod.simpleDocString,
+ basic.simpleDocString,
]
-## generator-functions that yield doc strings for enums.
+# These generator-functions yield doc strings for enums.
enumDocStringHandlers = [
- java2python.mod.simpleDocString,
+ basic.simpleDocString,
]
-## generator-functions that yield doc strings for methods.
+# These generator-functions yield doc strings for methods.
methodDocStringHandlers = [
- java2python.mod.simpleDocString,
+ basic.simpleDocString,
]
-## generator-functions that yield extra method decorators.
+# These generator-functions yield extra method decorators.
methodExtraDecoratorHandlers = [
- java2python.mod.maybeClassMethod,
- java2python.mod.overloadedClassMethods,
+ basic.maybeClassMethod,
+ basic.overloadedClassMethods,
]
-## generator-functions that yield base types for classes.
+# These generator-functions yield base types for classes.
classBaseHandlers = [
- java2python.mod.mapClassType,
+ basic.mapClassType,
]
-## generator-functions that yield base types for enums.
+# These generator-functions yield base types for enums.
enumBaseHandlers = [
- java2python.mod.mapClassType
+ basic.mapClassType
]
-## generator-functions that yield base types for interfaces.
+# generator-functions that yield base types for interfaces.
interfaceBaseHandlers = [
- java2python.mod.mapClassType
+ basic.mapClassType
]
-##
-# Note that the following two enum value handlers are only called for
-# basic enumerations, not enumerations that take arguments in a
-# constructor. When those kinds of enum values are detected, the
-# package will create the enum values as instance of the enum class,
-# and these handlers will not be invoked.
-
# This handler creates enum values on enum classes after they've been
# defined. The handler matches Java semantics fairly closely by using
-# strings.
-enumValueHandler = java2python.mod.enumConstStrings
+# strings. Refer to the documentation for details.
+enumValueHandler = basic.enumConstStrings
# Alternatively, you can use this handler to construct enum values as
# integers.
-#enumValueHandler = 'java2python.mod.enumConstInts'
+#enumValueHandler = basic.enumConstInts
-## not implemented:
-
-## move inner class definitions to the top of their outer class.
-## allows the outer class to reference the inner class definition
-#bubbleInnerClasses = True
-
-## minimum parameter count to trigger indentation of parameter names
-## in method declarations. set to 0 to disable.
+expressionVariableNamingHandler = basic.globalNameCounter
+
+
+# The AST transformation function uses these declarations to modify an
+# AST before compiling it to python source. Having these declarations
+# in a config file gives clients an opportunity to change the
+# transformation behavior.
+
+astTransforms = [
+ (Type('NULL'), transform.null2None),
+ (Type('FALSE'), transform.false2False),
+ (Type('TRUE'), transform.true2True),
+ (Type('IDENT'), transform.keywordSafeIdent),
+
+ (Type('FLOATING_POINT_LITERAL'),
+ transform.syntaxSafeFloatLiteral),
+
+ (Type('TYPE') > Type('QUALIFIED_TYPE_IDENT') > Type('IDENT'),
+ transform.typeSub)
+]
+
+
+# not implemented:
+
+# minimum parameter count to trigger indentation of parameter names
+# in method declarations. set to 0 to disable.
#minIndentParams = 5
-## these handle shift right and bit shift right assignments.
-#bsrHandler = 'java2python.mod.functionBsr'
-#bsrHandlerAssign = 'java2python.mod.functionBsrAssign'
+# these handle shift right and bit shift right assignments.
+#bsrHandler = 'basic.functionBsr'
+#bsrHandlerAssign = 'basic.functionBsrAssign'
-##
-# Below are values used by the handlers. They're here for
+# Values below are used by the handlers. They're here for
# convenience.
-## module output subs.
+# module output subs.
moduleOutputSubs = [
(r'System\.out\.println\((.*)\)', r'print \1'),
(r'System\.out\.print_\((.*?)\)', r'print \1,'),
@@ -136,32 +155,18 @@
(r'\.getClass\(\)', '.__class__'),
(r'\.getName\(\)', '.__name__'),
(r'\.getInterfaces\(\)', '.__bases__'),
- #(r'(\.self\.)', '.'),
#(r'String\.valueOf\((.*?)\)', r'str(\1)'),
#(r'(\s)(\S*?)(\.toString\(\))', r'\1str(\2)'),
]
typeSubs = {
- 'Boolean' : 'bool',
- 'Object' : 'object',
- 'String' : 'str',
- 'char' : 'str',
- 'double' : 'float',
- 'java.lang.String' : 'str',
+ 'Boolean' : 'bool',
'IndexOutOfBoundsException' : 'IndexError',
-}
-
-
-from java2python.lang.selector import *
-from java2python.mod import transforms
-
-
-transforms = [
- (Type('NULL'), transforms.null2None),
- (Type('FALSE'), transforms.false2False),
- (Type('TRUE'), transforms.true2True),
- (Type('IDENT'), transforms.keywordSafeIdent),
- (Type('FLOATING_POINT_LITERAL'), transforms.syntaxSafeFloatLiteral),
- (Type('TYPE') > Type('QUALIFIED_TYPE_IDENT') > Type('IDENT'),
transforms.typeSub)
-]
+ 'Integer' : 'int',
+ 'Object' : 'object',
+ 'String' : 'str',
+ 'char' : 'str',
+ 'double' : 'float',
+ 'java.lang.String' : 'str',
+}
=======================================
--- /branches/0.5/java2python/lang/Java.g Wed Jul 14 11:32:04 2010
+++ /branches/0.5/java2python/lang/Java.g Sat Jul 24 01:19:21 2010
@@ -1083,7 +1083,7 @@
;
COMMENT
- : '/*' ( options {greedy=false;} : . )* '*/'
+ : '/*' ~('*') ( options {greedy=false;} : . )* '*/'
{
$channel = HIDDEN
}
@@ -1095,3 +1095,10 @@
$channel = HIDDEN
}
;
+
+JAVADOC_COMMENT
+ : '/**' ( options {greedy=false;} : . )* '*/'
+ {
+ $channel = HIDDEN
+ }
+ ;
=======================================
--- /branches/0.5/java2python/lang/base.py Mon Jul 19 15:02:15 2010
+++ /branches/0.5/java2python/lang/base.py Sat Jul 24 01:19:21 2010
@@ -40,7 +40,8 @@
@property
def commentTypes(self):
- return (self.module.COMMENT, self.module.LINE_COMMENT, )
+ mod = self.module
+ return (mod.COMMENT, mod.LINE_COMMENT, mod.JAVADOC_COMMENT, )
@property
def methodTypes(self):
@@ -182,6 +183,14 @@
""" Depth-first search that yields nodes of the given type. """
return self.findChildren(lambda c:c.type==type)
+ @property
+ def withinExpr(self):
+ parent = getattr(self.parent, 'parent', None) # skip first expr
+ while parent:
+ if parent.type in (tokens.EXPR, ):
+ return True
+ parent = parent.parent
+
@property
def parentType(self):
""" Returns the type of the parent node. """
=======================================
--- /branches/0.5/java2python/mod/__init__.py Wed Jul 7 22:26:47 2010
+++ /branches/0.5/java2python/mod/__init__.py Sat Jul 24 01:19:21 2010
@@ -1,103 +1,2 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-from re import sub as rxsub
-
-
-def simpleShebang(module):
- yield '#!/usr/bin/env python'
-
-
-def simpleDocString(obj):
- yield '""" generated source for {0} {1}'.format(obj.typeName, obj.name)
- yield ''
- yield '"""'
-
-
-def configImports(module):
- if 0:
- yield ''
-
-
-def commentedImports(module):
- if 0:
- yield ''
-
-
-def commentedPackageName(module):
- if 0:
- yield ''
-
-
-def enumConstInts(enum, index, name):
- return str(index)
-
-
-def enumConstStrings(enum, index, name):
- return repr(name)
-
-
-scriptTemplate = """\n
-if __name__ == '__main__':
-{indent}import sys
-{indent}{name}.main(sys.argv)"""
-
-
-def scriptMainStanza(module):
- def filterClass(x):
- return x.isClass and x.name==module.name
-
- def filterMethod(x):
- return x.isMethod and x.isPublic and x.isStatic and \
- x.isVoid and x.name=='main'
-
- for cls in [c for c in module.children if filterClass(c)]:
- if [m for m in cls.children if filterMethod(m)]:
- yield scriptTemplate.format(indent=module.indent, name=module.name)
- break
-
-
-def outputSubs(obj, text):
- subsname = '{0}OutputSubs'.format(obj.typeName)
- subs = obj.config.every(subsname, [])
- for sub in subs:
- for pattern, repl in sub:
- text = rxsub(pattern, repl, text)
- return text
-
-
-def mapClassType(obj):
- bases = obj.bases or ('object', )
- for name in bases:
- yield name
-
-
-def overloadedClassMethods(method):
- """
- NB: this implementation does not handle overloaded static (or
- class) methods, only instance methods.
- """
- cls = method.parent
- methods = [o for o in cls.children if o.isMethod and
o.name==method.name]
- if len(methods) == 1:
- return
- for i, m in enumerate(methods[1:]):
- args = [p['type'] for p in m.parameters]
- args = ', '.join(args)
- m.decorators.append('{0}.register({1})'.format(method.name, args))
- m.name = '{0}_{1}'.format(method.name, i)
- # for this one only:
- yield 'overloaded'
-
-
-def maybeClassMethod(method):
- if method.isStatic and 'classmethod' not in method.decorators:
- yield 'classmethod'
-
-
-def simpleInterfaces(method):
- mkExpr = partial(Expression, module.config,
- format='raise NotImplementedError({left})')
- for iface in module.interfaces:
- for method in iface.methods:
- expr = mkExpr(left='"Method \'%s\' is abstract"' % method.name)
- method.children.insert(0, expr)
=======================================
--- /branches/0.5/test/Class4.java Thu Jul 1 15:12:49 2010
+++ /branches/0.5/test/Class4.java Sat Jul 24 01:19:21 2010
@@ -3,10 +3,14 @@
static class StaticInner {
public static String x = "notnull";
}
+
+ int foo = 3;
class NestedInner {
public String y = "somenull";
}
+
+ int bar = 4;
public static void main(String[] args) {
Class4 c4 = new Class4();
=======================================
--- /branches/0.5/test/Expr1.java Thu Jul 1 15:12:49 2010
+++ /branches/0.5/test/Expr1.java Sat Jul 24 01:19:21 2010
@@ -27,6 +27,7 @@
x &= 3;
System.out.println(x);
+
// and assign
x = 444;
x &= 0x0bc;
@@ -42,6 +43,7 @@
x %= 5;
System.out.println(x);
+
// bit shift right assign
// shift right assign
// shift left assign
@@ -50,6 +52,8 @@
x = 3;
System.out.println(x==3 ? 1 : 0);
System.out.println(x!=3 ? 1 : 0);
+
+
String y = new String();
System.out.println(y instanceof String ? "object" : "notobject");
System.out.println(x <= 0 ? 1 : 0);
@@ -62,6 +66,8 @@
// logical and
System.out.println(1 < 3 && 3 > 1 ? 1 : 0);
+
+
// or
System.out.println(4 | 2);
@@ -71,6 +77,7 @@
// and
System.out.println(3 & 2);
+
// equal
System.out.println(3 == 3 ? 1 : 0);
System.out.println(3 == 4 ? 1 : 0);
@@ -80,22 +87,28 @@
System.out.println(3 != 4 ? 1 : 0);
+
System.out.println(44 >> 3);
System.out.println(44 > 3 ? 1 : 0);
System.out.println(44 << 3);
System.out.println(44 < 3 ? 1 : 0);
+
x = 33;
System.out.println(x+1);
System.out.println(x-1);
- System.out.println(x*2);
+ System.out.println(x*x*x);
System.out.println(x/2);
System.out.println(x%2);
+
+
x = -33;
System.out.println(-x);
System.out.println(+x);
+
+
// NB: these tests side-step the issue of using pre/post inc in
// expressions
x = 55;
@@ -108,11 +121,15 @@
x--;
System.out.println(x);
+
x = 55;
System.out.println(~x);
+
System.out.println(!false ? 1 : 0);
System.out.println( (Integer) x );
+/*
+*/
}
}
=======================================
--- /branches/0.5/test/Makefile Wed Jul 14 11:56:45 2010
+++ /branches/0.5/test/Makefile Sat Jul 24 01:19:21 2010
@@ -11,7 +11,7 @@
all: package_1 $(java_sources)
package_1:
- cd Package1 && ../../bin/j2py -i Class1.java -o Class1.py
+ #@echo cd Package1 && ../../bin/j2py -i Class1.java -o Class1.py
$(java_sources):
@javac $@ && ../bin/j2py -i $@ -o $(basename $@).py -c testconfig
=======================================
--- /branches/0.5/test/ReallyQuickTest.java Fri Jul 9 00:50:21 2010
+++ /branches/0.5/test/ReallyQuickTest.java Sat Jul 24 01:19:21 2010
@@ -1,8 +1,8 @@
class ReallyQuickTest {
- public foo() {
- int b[] = {1, 2, 3};
- int x;
- int y = 3;
+ public eggs() {
+
+ fu(a+1, b+2, c+3);
+
}
}