From 2a4e83d642ac8b9de00c049ed6d4848564b1f62a Mon Sep 17 00:00:00 2001 From: Iulius Curt Date: Wed, 18 Sep 2013 20:48:34 +0300 Subject: [PATCH 01/25] Update ANTLR remote location As suggested by ekta1007 in #28 --- doc/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install.md b/doc/install.md index 0a0b8e3..fdb7f86 100644 --- a/doc/install.md +++ b/doc/install.md @@ -12,7 +12,7 @@ Kids these days have it easy: We need the ANTLR Python runtime before we can install java2python: - # wget http://www.antlr.org/download/antlr-3.1.3.tar.gz + # wget http://www.antlr3.org/download/antlr-3.1.3.tar.gz # tar xfz antlr-3.1.3.tar.gz # cd antlr-3.1.3/runtime/Python/ # python setup.py install From 2e92c6e0820e9e256c9e211e1db2165d2d37f7d5 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Fri, 10 Oct 2014 06:32:36 -0400 Subject: [PATCH 02/25] only call load_source if path is a file --- java2python/config/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java2python/config/__init__.py b/java2python/config/__init__.py index 72d6c5e..2aa8387 100644 --- a/java2python/config/__init__.py +++ b/java2python/config/__init__.py @@ -27,7 +27,7 @@ def last(self, key, default=None): @staticmethod def load(name): """ Imports and returns a module from dotted form or filename. """ - if path.exists(name): + if path.exists(name) and path.isfile(name): mod = load_source(str(hash(name)), name) else: mod = reduce(getattr, name.split('.')[1:], __import__(name)) From 39a032316b96a4e54fe54d1bbdb8186e3c18c2e8 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Fri, 10 Oct 2014 14:59:57 -0400 Subject: [PATCH 03/25] output switch equals cases with spaces around operator --- java2python/compiler/visitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java2python/compiler/visitor.py b/java2python/compiler/visitor.py index 4109883..127aae4 100644 --- a/java2python/compiler/visitor.py +++ b/java2python/compiler/visitor.py @@ -517,7 +517,7 @@ def acceptSwitch(self, node, memo): # we have at least one node... parExpr = self.factory.expr(parent=self) parExpr.walk(parNode, memo) - eqFs = FS.l + '==' + FS.r + eqFs = FS.l + ' == ' + FS.r for caseIdx, caseNode in enumerate(caseNodes): isDefault, isFirst = caseNode.type==tokens.DEFAULT, caseIdx==0 From 8a758716f3cba47b1bc55f7a26211c43ab0200ae Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Fri, 10 Oct 2014 17:37:37 -0400 Subject: [PATCH 04/25] test and fix vars defined inside blocks --- java2python/compiler/visitor.py | 4 ++-- test/If8.java | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 test/If8.java diff --git a/java2python/compiler/visitor.py b/java2python/compiler/visitor.py index 127aae4..5f55f0b 100644 --- a/java2python/compiler/visitor.py +++ b/java2python/compiler/visitor.py @@ -358,7 +358,7 @@ class Interface(Class): """ Interface -> accepts AST branches for Java interfaces. """ -class MethodContent(Base): +class MethodContent(VarAcceptor, Base): """ MethodContent -> accepts trees for blocks within methods. """ def acceptAssert(self, node, memo): @@ -613,7 +613,7 @@ def acceptWhile(self, node, memo): whileStat.walk(blkNode, memo) -class Method(VarAcceptor, ModifiersAcceptor, MethodContent): +class Method(ModifiersAcceptor, MethodContent): """ Method -> accepts AST branches for method-level objects. """ def acceptFormalParamStdDecl(self, node, memo): diff --git a/test/If8.java b/test/If8.java new file mode 100644 index 0000000..37e1c46 --- /dev/null +++ b/test/If8.java @@ -0,0 +1,8 @@ +class If8 { + public static void main(String[] args) { + if (true) { + int y = 1; + System.out.println(0 + y); + } + } +} From e1fac1545cf2ad496deba791606954ca76f62548 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Fri, 10 Oct 2014 17:43:26 -0400 Subject: [PATCH 05/25] add gitignore file --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2130e0d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.class +*.egg-info +*.pyc From 1d3c3f9a42dbec7fd7ddb4c8154f24df7964de99 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Fri, 10 Oct 2014 19:53:14 -0400 Subject: [PATCH 06/25] add mod.include to setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index fd8cf18..210d623 100644 --- a/setup.py +++ b/setup.py @@ -59,6 +59,7 @@ def doc_files(): 'java2python.lang', 'java2python.lib', 'java2python.mod', + 'java2python.mod.include', ], package_data={ From 28f039a15706c341d051b8fe69b6e5923afe1845 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Mon, 13 Oct 2014 19:29:22 -0400 Subject: [PATCH 07/25] add failing test for class variables with no initial value --- test/BasicTypes3.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 test/BasicTypes3.java diff --git a/test/BasicTypes3.java b/test/BasicTypes3.java new file mode 100644 index 0000000..76821a2 --- /dev/null +++ b/test/BasicTypes3.java @@ -0,0 +1,20 @@ +class Vector {} + +class BasicTypes3 { + Boolean B; + Integer I; + Double D; + + String S; + Vector V; + + public static void main(String[] args) { + BasicTypes3 bt3 = new BasicTypes3(); + System.out.println(bt3.B == null ? 1 : 0); + System.out.println(bt3.I == null ? 1 : 0); + System.out.println(bt3.D == null ? 1 : 0); + System.out.println(bt3.S == null ? 1 : 0); + System.out.println(bt3.V == null ? 1 : 0); + } + +} From 3f2407d16a98e52351fcf301a3acc57169ae2f9e Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Mon, 13 Oct 2014 20:07:34 -0400 Subject: [PATCH 08/25] fix test, class variables with no init value are set to None --- java2python/compiler/visitor.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java2python/compiler/visitor.py b/java2python/compiler/visitor.py index 5f55f0b..c6a66e1 100644 --- a/java2python/compiler/visitor.py +++ b/java2python/compiler/visitor.py @@ -228,7 +228,10 @@ def acceptVarDeclaration(self, node, memo): if node.firstChildOfType(tokens.TYPE).firstChildOfType(tokens.ARRAY_DECLARATOR_LIST): val = assgnExp.pushRight('[]') else: - val = assgnExp.pushRight('{0}()'.format(identExp.type)) + if node.firstChildOfType(tokens.TYPE).firstChild().type != tokens.QUALIFIED_TYPE_IDENT: + val = assgnExp.pushRight('{0}()'.format(identExp.type)) + else: + val = assgnExp.pushRight('None') return self From af2b2e44ded258841035c32ed35f5269663679f9 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Mon, 13 Oct 2014 22:34:19 -0400 Subject: [PATCH 09/25] fix synchronized methods to lock per-instance not per-method --- java2python/mod/include/sync.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/java2python/mod/include/sync.py b/java2python/mod/include/sync.py index 8201698..742fbfd 100644 --- a/java2python/mod/include/sync.py +++ b/java2python/mod/include/sync.py @@ -1,12 +1,11 @@ from threading import RLock -_locks = {} -def lock_for_object(obj, locks=_locks): +def lock_for_object(obj, locks={}): return locks.setdefault(id(obj), RLock()) - def synchronized(call): + assert call.__code__.co_varnames[0] in {'self', 'cls'} def inner(*args, **kwds): - with lock_for_object(call): + with lock_for_object(args[0]): return call(*args, **kwds) return inner From 39d019aa2d3468aa45d3ce050ad81caa8d01b3a5 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Mon, 13 Oct 2014 22:56:12 -0400 Subject: [PATCH 10/25] use functools.wraps for synchronized decorator --- java2python/mod/include/sync.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java2python/mod/include/sync.py b/java2python/mod/include/sync.py index 742fbfd..b3e5130 100644 --- a/java2python/mod/include/sync.py +++ b/java2python/mod/include/sync.py @@ -1,3 +1,4 @@ +from functools import wraps from threading import RLock def lock_for_object(obj, locks={}): @@ -5,6 +6,7 @@ def lock_for_object(obj, locks={}): def synchronized(call): assert call.__code__.co_varnames[0] in {'self', 'cls'} + @wraps(call) def inner(*args, **kwds): with lock_for_object(args[0]): return call(*args, **kwds) From 7120676a728db01c2adfc794b79a673b71954679 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Tue, 14 Oct 2014 00:07:17 -0400 Subject: [PATCH 11/25] test/fix overloaded synchronized methods --- java2python/config/default.py | 2 +- java2python/mod/include/classmethod.py | 6 +++++ test/Synchronized2.java | 36 ++++++++++++++++++++++++++ test/configs/defaults.py | 1 + 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 java2python/mod/include/classmethod.py create mode 100644 test/Synchronized2.java diff --git a/java2python/config/default.py b/java2python/config/default.py index a2cdb67..df2455a 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -97,9 +97,9 @@ methodPrologueHandlers = [ basic.maybeAbstractMethod, basic.maybeClassMethod, + basic.overloadedClassMethods, # NB: synchronized should come after classmethod basic.maybeSynchronizedMethod, - basic.overloadedClassMethods, ] diff --git a/java2python/mod/include/classmethod.py b/java2python/mod/include/classmethod.py new file mode 100644 index 0000000..cb97954 --- /dev/null +++ b/java2python/mod/include/classmethod.py @@ -0,0 +1,6 @@ +class classmethod_(classmethod): + """ Classmethod that provides attribute delegation. + + """ + def __getattr__(self, name): + return getattr(self.__func__, name) diff --git a/test/Synchronized2.java b/test/Synchronized2.java new file mode 100644 index 0000000..3ca9fa5 --- /dev/null +++ b/test/Synchronized2.java @@ -0,0 +1,36 @@ +class Synchronized2 { + + public synchronized void test1() { + System.out.println(1); + } + + public synchronized void test1(String s) { + System.out.println(s); + } + + public static synchronized void test1(int i) { + System.out.println(i); + } + + public static synchronized void test2() { + System.out.println(2); + } + + public static synchronized void test2(String s) { + System.out.println(s); + } + + public synchronized void test2(int i) { + System.out.println(i); + } + + public static void main(String[] args) { + Synchronized2 obj = new Synchronized2(); + obj.test1(); + obj.test1("test1"); + obj.test1(1); + obj.test2(); + obj.test2("test2"); + obj.test2(2); + } +} diff --git a/test/configs/defaults.py b/test/configs/defaults.py index c822d48..0cea861 100644 --- a/test/configs/defaults.py +++ b/test/configs/defaults.py @@ -4,6 +4,7 @@ modulePrologueHandlers = default.modulePrologueHandlers + [ + 'from java2python.mod.include.classmethod import classmethod_ as classmethod', 'from java2python.mod.include.overloading import overloaded', 'from abc import ABCMeta, abstractmethod', 'import zope.interface', From 4353f409e79f73d92119ffe060c4a3487600f806 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Tue, 14 Oct 2014 00:41:39 -0400 Subject: [PATCH 12/25] ensure overloaded methods are registered as synchronized --- java2python/compiler/template.py | 1 + java2python/mod/basic.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/java2python/compiler/template.py b/java2python/compiler/template.py index e117df3..2a189ef 100644 --- a/java2python/compiler/template.py +++ b/java2python/compiler/template.py @@ -119,6 +119,7 @@ def __init__(self, config, name=None, type=None, parent=None): self.children = [] self.config = config self.decorators = [] + self.overloaded = None self.factory = Factory(config) self.modifiers = [] self.name = name diff --git a/java2python/mod/basic.py b/java2python/mod/basic.py index 63c1806..7c2cb27 100644 --- a/java2python/mod/basic.py +++ b/java2python/mod/basic.py @@ -109,11 +109,13 @@ def overloadedClassMethods(method): cls = method.parent methods = [o for o in cls.children if o.isMethod and o.name==method.name] if len(methods) == 1: + if methods[0].overloaded: + yield methods[0].overloaded 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.overloaded = '@{0}.register({1})'.format(method.name, args) m.name = '{0}_{1}'.format(method.name, i) # for this one only: yield '@overloaded' From 2d5e91125d3f33bbc6ce7b398c6c2217e83978dc Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Tue, 14 Oct 2014 03:45:29 -0400 Subject: [PATCH 13/25] print differences when testing --- test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index 64ac2d0..e432679 100644 --- a/test/Makefile +++ b/test/Makefile @@ -43,4 +43,4 @@ parsers: @$(j2py) $(addsuffix .java, $(basename $@)) $@ -c configs.defaults -d configs %: %.py - @bash -c "diff -q <($(python) $(addsuffix .py, $@)) <(java -ea $@)" && echo "[PASS] $@" + @bash -c "diff -u <($(python) $(addsuffix .py, $@)) <(java -ea $@)" && echo "[PASS] $@" From c994f83abdfb041f5c747b1422e9053a9c4fef9e Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Tue, 14 Oct 2014 03:49:25 -0400 Subject: [PATCH 14/25] some changes for py3 compat --- java2python/config/default.py | 5 +++-- java2python/mod/include/overloading.py | 12 +++++++----- test/Self0.java | 3 +++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/java2python/config/default.py b/java2python/config/default.py index df2455a..9b10ccc 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -24,6 +24,7 @@ modulePrologueHandlers = [ basic.shebangLine, basic.simpleDocString, + 'from __future__ import print_function', basic.maybeBsr, basic.maybeSyncHelpers, ] @@ -193,8 +194,8 @@ # module output subs. moduleOutputSubs = [ - (r'System\.out\.println\((.*)\)', r'print \1'), - (r'System\.out\.print_\((.*?)\)', r'print \1,'), + (r'System\.out\.println\((.*)\)', r'print(\1)'), + (r'System\.out\.print_\((.*?)\)', r'print(\1, end="")'), (r'(.*?)\.equals\((.*?)\)', r'\1 == \2'), (r'(.*?)\.equalsIgnoreCase\((.*?)\)', r'\1.lower() == \2.lower()'), (r'([\w.]+)\.size\(\)', r'len(\1)'), diff --git a/java2python/mod/include/overloading.py b/java2python/mod/include/overloading.py index d7baafd..2f8257c 100644 --- a/java2python/mod/include/overloading.py +++ b/java2python/mod/include/overloading.py @@ -36,11 +36,13 @@ """ -import new +from types import MethodType as instancemethod -# Make the environment more like Python 3.0 -__metaclass__ = type -from itertools import izip as zip +import sys +if sys.version_info[0] < 3: + # Make the environment more like Python 3.0 + __metaclass__ = type + from itertools import izip as zip class overloaded: @@ -55,7 +57,7 @@ def __init__(self, default_func): def __get__(self, obj, type=None): if obj is None: return self - return new.instancemethod(self, obj) + return instancemethod(self, obj) def register(self, *types): """Decorator to register an implementation for a specific set of types. diff --git a/test/Self0.java b/test/Self0.java index 269a96e..c7556ba 100644 --- a/test/Self0.java +++ b/test/Self0.java @@ -17,6 +17,9 @@ public static void main(String[] args) { System.out.println("True"); else System.out.println("False"); + System.out.print("test"); + System.out.print("ing"); + System.out.println(); } } From 150e5cee1f35e053846007b279c82aa1100dab10 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Wed, 15 Oct 2014 00:30:31 -0400 Subject: [PATCH 15/25] use config.every rather than config.last for configHandlers --- java2python/compiler/template.py | 2 +- test/configs/Class10.py | 4 +--- test/configs/Interface1.py | 4 +--- test/configs/defaults.py | 5 +---- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/java2python/compiler/template.py b/java2python/compiler/template.py index 2a189ef..4f4dfe1 100644 --- a/java2python/compiler/template.py +++ b/java2python/compiler/template.py @@ -173,7 +173,7 @@ def configHandler(self, part, suffix='Handler', default=None): def configHandlers(self, part, suffix='Handlers'): """ Returns config handlers for this type of template """ name = '{0}{1}{2}'.format(self.typeName, part, suffix) - return imap(self.toIter, self.config.last(name, ())) + return imap(self.toIter, chain(*self.config.every(name, []))) def dump(self, fd, level=0): """ Writes the Python source code for this template to the given file. """ diff --git a/test/configs/Class10.py b/test/configs/Class10.py index 71de720..22ac1a5 100644 --- a/test/configs/Class10.py +++ b/test/configs/Class10.py @@ -1,6 +1,4 @@ -from java2python.config.default import modulePrologueHandlers - -modulePrologueHandlers += [ +modulePrologueHandlers = [ 'from java2python.mod.include.overloading import overloaded', 'from abc import ABCMeta, abstractmethod', ] diff --git a/test/configs/Interface1.py b/test/configs/Interface1.py index 79bd196..bd28c79 100644 --- a/test/configs/Interface1.py +++ b/test/configs/Interface1.py @@ -1,5 +1,3 @@ -from java2python.config.default import modulePrologueHandlers - -modulePrologueHandlers += [ +modulePrologueHandlers = [ "from abc import ABCMeta, abstractmethod", ] diff --git a/test/configs/defaults.py b/test/configs/defaults.py index 0cea861..3ab207e 100644 --- a/test/configs/defaults.py +++ b/test/configs/defaults.py @@ -1,9 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from java2python.config import default - - -modulePrologueHandlers = default.modulePrologueHandlers + [ +modulePrologueHandlers = [ 'from java2python.mod.include.classmethod import classmethod_ as classmethod', 'from java2python.mod.include.overloading import overloaded', 'from abc import ABCMeta, abstractmethod', From 0b669980de5f406d3f010287ef1ec39d8e581821 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Wed, 15 Oct 2014 00:34:23 -0400 Subject: [PATCH 16/25] use config.every rather than config.last for typeSubs --- java2python/mod/transform.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/java2python/mod/transform.py b/java2python/mod/transform.py index d8e2652..c420012 100644 --- a/java2python/mod/transform.py +++ b/java2python/mod/transform.py @@ -184,6 +184,7 @@ def typeSub(node, config): mapping and further discussion. """ ident = node.token.text - subs = config.last('typeSubs') - if ident in subs: - node.token.text = subs[ident] + for subs in reversed(config.every('typeSubs', {})): + if ident in subs: + node.token.text = subs[ident] + return From daced34e702971ba542695d5747f5750559e7375 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Wed, 15 Oct 2014 01:10:04 -0400 Subject: [PATCH 17/25] add abc imports when defining interfaces --- java2python/compiler/visitor.py | 7 ++++++- java2python/config/default.py | 1 + java2python/mod/basic.py | 7 +++++-- test/configs/Class10.py | 1 - test/configs/Interface1.py | 3 --- test/configs/defaults.py | 1 - 6 files changed, 12 insertions(+), 8 deletions(-) delete mode 100644 test/configs/Interface1.py diff --git a/java2python/compiler/visitor.py b/java2python/compiler/visitor.py index c6a66e1..8b05b32 100644 --- a/java2python/compiler/visitor.py +++ b/java2python/compiler/visitor.py @@ -129,7 +129,12 @@ def acceptType(self, node, memo): acceptAt = makeAcceptType('at') acceptClass = makeAcceptType('klass') acceptEnum = makeAcceptType('enum') - acceptInterface = makeAcceptType('interface') + _acceptInterface = makeAcceptType('interface') + + def acceptInterface(self, node, memo): + module = self.parents(lambda x:x.isModule).next() + module.needsAbstractHelpers = True + return self._acceptInterface(node, memo) class Module(TypeAcceptor, Base): diff --git a/java2python/config/default.py b/java2python/config/default.py index 9b10ccc..2c2a0ef 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -26,6 +26,7 @@ basic.simpleDocString, 'from __future__ import print_function', basic.maybeBsr, + basic.maybeAbstractHelpers, basic.maybeSyncHelpers, ] diff --git a/java2python/mod/basic.py b/java2python/mod/basic.py index 7c2cb27..ae7b58c 100644 --- a/java2python/mod/basic.py +++ b/java2python/mod/basic.py @@ -133,8 +133,6 @@ def maybeAbstractMethod(method): def maybeSynchronizedMethod(method): if 'synchronized' in method.modifiers: - module = method.parents(lambda x:x.isModule).next() - module.needsSyncHelpers = True yield '@synchronized' @@ -160,6 +158,11 @@ def maybeBsr(module): yield line +def maybeAbstractHelpers(module): + if getattr(module, 'needsAbstractHelpers', False): + yield 'from abc import ABCMeta, abstractmethod' + + def maybeSyncHelpers(module): if getattr(module, 'needsSyncHelpers', False): for line in getSyncHelpersSrc().split('\n'): diff --git a/test/configs/Class10.py b/test/configs/Class10.py index 22ac1a5..0b340ee 100644 --- a/test/configs/Class10.py +++ b/test/configs/Class10.py @@ -1,4 +1,3 @@ modulePrologueHandlers = [ 'from java2python.mod.include.overloading import overloaded', - 'from abc import ABCMeta, abstractmethod', ] diff --git a/test/configs/Interface1.py b/test/configs/Interface1.py deleted file mode 100644 index bd28c79..0000000 --- a/test/configs/Interface1.py +++ /dev/null @@ -1,3 +0,0 @@ -modulePrologueHandlers = [ - "from abc import ABCMeta, abstractmethod", - ] diff --git a/test/configs/defaults.py b/test/configs/defaults.py index 3ab207e..7a5d639 100644 --- a/test/configs/defaults.py +++ b/test/configs/defaults.py @@ -3,7 +3,6 @@ modulePrologueHandlers = [ 'from java2python.mod.include.classmethod import classmethod_ as classmethod', 'from java2python.mod.include.overloading import overloaded', - 'from abc import ABCMeta, abstractmethod', 'import zope.interface', ] From 04dd59cede80c667f22c5bdb4988acd24da5cf22 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Wed, 15 Oct 2014 01:17:12 -0400 Subject: [PATCH 18/25] handle String.valueOf() --- java2python/config/default.py | 2 +- test/String0.java | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/String0.java diff --git a/java2python/config/default.py b/java2python/config/default.py index 2c2a0ef..c6661ac 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -209,7 +209,7 @@ (r'\.getClass\(\)', '.__class__'), (r'\.getName\(\)', '.__name__'), (r'\.getInterfaces\(\)', '.__bases__'), - #(r'String\.valueOf\((.*?)\)', r'str(\1)'), + (r'String\.valueOf\((.*?)\)', r'str(\1)'), #(r'(\s)(\S*?)(\.toString\(\))', r'\1str(\2)'), ] diff --git a/test/String0.java b/test/String0.java new file mode 100644 index 0000000..e4ed565 --- /dev/null +++ b/test/String0.java @@ -0,0 +1,9 @@ +class String0 { + static void test(String s) { + System.out.println(s); + } + + public static void main(String[] args) { + test(String.valueOf(42)); + } +} From 96897b99fff9d303e903404ccb34cba0576b4b98 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Wed, 15 Oct 2014 01:26:04 -0400 Subject: [PATCH 19/25] convert IOException to IOError, test --- java2python/config/default.py | 4 +++- java2python/mod/basic.py | 2 +- test/Exception0.java | 17 +++++++++++++++++ test/configs/UsePackage0.py | 3 +++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 test/Exception0.java create mode 100644 test/configs/UsePackage0.py diff --git a/java2python/config/default.py b/java2python/config/default.py index c6661ac..159ebc9 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -133,7 +133,7 @@ # This handler is turns java imports into python imports. No mapping # of packages is performed: -moduleImportDeclarationHandler = basic.simpleImports +# moduleImportDeclarationHandler = basic.simpleImports # This import decl. handler can be used instead to produce comments # instead of import statements: @@ -243,5 +243,7 @@ 'java.lang.String' : 'str', 'Object' : 'object', + 'IndexOutOfBoundsException' : 'IndexError', + 'IOException': 'IOError', } diff --git a/java2python/mod/basic.py b/java2python/mod/basic.py index ae7b58c..02e2f57 100644 --- a/java2python/mod/basic.py +++ b/java2python/mod/basic.py @@ -36,7 +36,7 @@ def simpleDocString(obj): def commentedImports(module, expr): - module.factory.comment(parent=module, left=expr, fs='import: {left}') + module.factory.comment(parent=module, left=expr, fs='#import {left}') def simpleImports(module, expr): diff --git a/test/Exception0.java b/test/Exception0.java new file mode 100644 index 0000000..f784749 --- /dev/null +++ b/test/Exception0.java @@ -0,0 +1,17 @@ +import java.io.IOException; + +class Exception0 { + static void test() throws IOException { + throw new IOException("test"); + } + + public static void main(String[] args) { + try { + test(); + } catch (IOException e) { + System.out.println("catch"); + } finally { + System.out.println("done"); + } + } +} diff --git a/test/configs/UsePackage0.py b/test/configs/UsePackage0.py new file mode 100644 index 0000000..243c245 --- /dev/null +++ b/test/configs/UsePackage0.py @@ -0,0 +1,3 @@ +from java2python.mod import basic + +moduleImportDeclarationHandler = basic.simpleImports From 34630360cd395ce43a6241bbcfca5498516c202c Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Wed, 15 Oct 2014 01:40:25 -0400 Subject: [PATCH 20/25] remove Math. prefix, test --- java2python/config/default.py | 1 + test/Math0.java | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 test/Math0.java diff --git a/java2python/config/default.py b/java2python/config/default.py index 159ebc9..316083a 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -211,6 +211,7 @@ (r'\.getInterfaces\(\)', '.__bases__'), (r'String\.valueOf\((.*?)\)', r'str(\1)'), #(r'(\s)(\S*?)(\.toString\(\))', r'\1str(\2)'), + (r'Math\.', ''), ] diff --git a/test/Math0.java b/test/Math0.java new file mode 100644 index 0000000..67ae731 --- /dev/null +++ b/test/Math0.java @@ -0,0 +1,6 @@ +class Math0 { + public static void main(String[] args) { + System.out.println(Math.abs(-42)); + System.out.println(Math.abs(-0.5)); + } +} From 0c6ee8e1a9dafd6ed39d4119b8be0543e6d37dca Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Wed, 15 Oct 2014 04:16:02 -0400 Subject: [PATCH 21/25] fix continue in for loops --- java2python/compiler/visitor.py | 4 ++++ test/Continue0.java | 10 +++++----- test/Continue1.java | 13 +++++++++++++ test/Continue2.java | 14 ++++++++++++++ test/ForLoop2.java | 9 +++++++++ 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 test/Continue1.java create mode 100644 test/Continue2.java create mode 100644 test/ForLoop2.java diff --git a/java2python/compiler/visitor.py b/java2python/compiler/visitor.py index 8b05b32..89f1dc7 100644 --- a/java2python/compiler/visitor.py +++ b/java2python/compiler/visitor.py @@ -407,6 +407,10 @@ def acceptCatch(self, node, memo): def acceptContinue(self, node, memo): """ Accept and process a continue statement. """ + parent = node.parents(lambda x: x.type in {tokens.FOR, tokens.FOR_EACH, tokens.DO, tokens.WHILE}).next() + if parent.type == tokens.FOR: + updateStat = self.factory.expr(parent=self) + updateStat.walk(parent.firstChildOfType(tokens.FOR_UPDATE), memo) contStat = self.factory.statement('continue', fs=FS.lsr, parent=self) if len(node.children): warn('Detected unhandled continue statement with label; generated code incorrect.') diff --git a/test/Continue0.java b/test/Continue0.java index 727eaef..d7bc322 100644 --- a/test/Continue0.java +++ b/test/Continue0.java @@ -3,12 +3,12 @@ public static void main(String[] args) { int x = 0; while (x < 10) { System.out.println(x); - if (x==6) { - break ; + if (x == 6) { + break; } else { - x+=2; - continue ; + x += 2; + continue; } - } + } } } diff --git a/test/Continue1.java b/test/Continue1.java new file mode 100644 index 0000000..a3e1443 --- /dev/null +++ b/test/Continue1.java @@ -0,0 +1,13 @@ +class Continue1 { + public static void main(String[] args) { + int[] ints = {1, 2, 3, 4, 5, 6, 7}; + for (int x : ints) { + if (x == 6) { + break; + } else if (x == 3) { + continue; + } + System.out.println(x); + } + } +} diff --git a/test/Continue2.java b/test/Continue2.java new file mode 100644 index 0000000..506e10f --- /dev/null +++ b/test/Continue2.java @@ -0,0 +1,14 @@ +class Continue2 { + public static void main(String[] args) { + int x = 0; + do { + System.out.println(x); + if (x == 6) { + break; + } else { + x += 2; + continue; + } + } while (x < 10); + } +} diff --git a/test/ForLoop2.java b/test/ForLoop2.java new file mode 100644 index 0000000..6c72ee2 --- /dev/null +++ b/test/ForLoop2.java @@ -0,0 +1,9 @@ +class ForLoop2 { + public static void main(String[] args) { + for (int i = 0; i < 3; i++) { + if (i == 1) + continue; + System.out.println(i); + } + } +} From 153da8b82e072ecc870e17667ff1a7c5454ab4a3 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Wed, 15 Oct 2014 07:15:39 -0400 Subject: [PATCH 22/25] put space in static array creator --- java2python/compiler/visitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java2python/compiler/visitor.py b/java2python/compiler/visitor.py index 89f1dc7..f62e53e 100644 --- a/java2python/compiler/visitor.py +++ b/java2python/compiler/visitor.py @@ -847,7 +847,7 @@ def acceptThisConstructorCall(self, node, memo): def acceptStaticArrayCreator(self, node, memo): """ Accept and process a static array expression. """ - self.right = self.factory.expr(fs='[None]*{left}') + self.right = self.factory.expr(fs='[None] * {left}') self.right.left = self.factory.expr() self.right.left.walk(node.firstChildOfType(tokens.EXPR), memo) From a7a3d5436e4a59db8dbb77402e6017e803f9b422 Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Thu, 16 Oct 2014 03:18:41 -0400 Subject: [PATCH 23/25] don't put L suffix on literals --- java2python/config/default.py | 1 + java2python/mod/transform.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/java2python/config/default.py b/java2python/config/default.py index 316083a..92c4a27 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -150,6 +150,7 @@ (Type('TRUE'), transform.true2True), (Type('IDENT'), transform.keywordSafeIdent), + (Type('DECIMAL_LITERAL'), transform.syntaxSafeDecimalLiteral), (Type('FLOATING_POINT_LITERAL'), transform.syntaxSafeFloatLiteral), (Type('TYPE') > Type('BOOLEAN'), transform.typeSub), diff --git a/java2python/mod/transform.py b/java2python/mod/transform.py index c420012..9b2e567 100644 --- a/java2python/mod/transform.py +++ b/java2python/mod/transform.py @@ -48,6 +48,14 @@ def xform(node, config): true2True = makeConst('True') +def syntaxSafeDecimalLiteral(node, config): + """ Ensures a Java decimal literal is a valid Python decimal literal. """ + value = node.token.text + if value.endswith(('l', 'L')): + value = value[:-1] + node.token.text = value + + def syntaxSafeFloatLiteral(node, config): """ Ensures a Java float literal is a valid Python float literal. """ value = node.token.text @@ -55,8 +63,6 @@ def syntaxSafeFloatLiteral(node, config): value = '0' + value if value.lower().endswith(('f', 'd')): value = value[:-1] - elif value.endswith(('l', 'L')): - value = value[:-1] + 'L' node.token.text = value From 408deeca0db7b9b6bd44a5e3edf3674ca04014eb Mon Sep 17 00:00:00 2001 From: Brian Kearns Date: Thu, 23 Oct 2014 03:18:52 -0400 Subject: [PATCH 24/25] change sync helper to be py26 friendly --- java2python/mod/include/sync.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java2python/mod/include/sync.py b/java2python/mod/include/sync.py index b3e5130..ddac055 100644 --- a/java2python/mod/include/sync.py +++ b/java2python/mod/include/sync.py @@ -5,7 +5,7 @@ def lock_for_object(obj, locks={}): return locks.setdefault(id(obj), RLock()) def synchronized(call): - assert call.__code__.co_varnames[0] in {'self', 'cls'} + assert call.__code__.co_varnames[0] in ['self', 'cls'] @wraps(call) def inner(*args, **kwds): with lock_for_object(args[0]): From 6f563f74ad8aeb5dca4348aba4b0abe156538fb4 Mon Sep 17 00:00:00 2001 From: Shyam Saladi Date: Tue, 10 May 2016 00:47:31 -0700 Subject: [PATCH 25/25] Erroneous link --- doc/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install.md b/doc/install.md index fdb7f86..bd2cf6e 100644 --- a/doc/install.md +++ b/doc/install.md @@ -45,6 +45,6 @@ The development dependencies (what you need if you're coding java2python) are [ANTLR][], also version 3.1.3, GNU make, and a JVM. -[version 3.1.3 of the Python runtime]: http://www.antlr.org/download/antlr-3.1.3.tar.gz +[version 3.1.3 of the Python runtime]: http://www.antlr3.org/download/antlr-3.1.3.tar.gz [Python runtime]: http://www.antlr.org/wiki/display/ANTLR3/Python+runtime [ANTLR]: http://www.antlr.org