From ca30900ed6bb148ddc0fb1761dbba64eb8606671 Mon Sep 17 00:00:00 2001 From: Troy Melhase Date: Thu, 3 May 2012 16:19:33 -0400 Subject: [PATCH 01/33] Bump to version 0.5.1. --- bin/j2py | 2 +- doc/install.md | 5 ++--- setup.py | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/bin/j2py b/bin/j2py index a08aadf..6eb1a40 100755 --- a/bin/j2py +++ b/bin/j2py @@ -18,7 +18,7 @@ from java2python.config import Config from java2python.lib import escapes -version = '0.5.0' +version = '0.5.1' def logLevel(value): diff --git a/doc/install.md b/doc/install.md index aa66c79..0a0b8e3 100644 --- a/doc/install.md +++ b/doc/install.md @@ -21,8 +21,8 @@ We need the ANTLR Python runtime before we can install java2python: Now the goodness: - # wget https://github.com/downloads/natural/java2python/java2python-0.5.0.tar.gz - # tar xfz java2python-0.5.0.tar.gz + # wget https://github.com/downloads/natural/java2python/java2python-0.5.1.tar.gz + # tar xfz java2python-0.5.1.tar.gz # cd java2python # python setup.py install @@ -48,4 +48,3 @@ The development dependencies (what you need if you're coding java2python) are [version 3.1.3 of the Python runtime]: http://www.antlr.org/download/antlr-3.1.3.tar.gz [Python runtime]: http://www.antlr.org/wiki/display/ANTLR3/Python+runtime [ANTLR]: http://www.antlr.org - diff --git a/setup.py b/setup.py index 604faa5..fd8cf18 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ def doc_files(): setup( name='java2python', - version='0.5.0', + version='0.5.1', description=description, long_description=long_description, @@ -47,7 +47,7 @@ def doc_files(): author_email='troy@troy.io', url='https://github.com/natural/java2python/', - download_url='https://github.com/downloads/natural/java2python/java2python-0.5.0.tar.gz', + download_url='https://github.com/downloads/natural/java2python/java2python-0.5.1.tar.gz', keywords=['java', 'java2python', 'compiler'], classifiers=filter(None, classifiers.split('\n')), From d5103ae13e286f62de43b06e79e88f2f8624ad6c Mon Sep 17 00:00:00 2001 From: Iulius Curt Date: Fri, 4 May 2012 00:35:52 +0300 Subject: [PATCH 02/33] Added output sub rule for String.format --- java2python/config/default.py | 1 + test/Format.java | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 test/Format.java diff --git a/java2python/config/default.py b/java2python/config/default.py index 6ad0651..ea34f46 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -189,6 +189,7 @@ moduleOutputSubs = [ (r'System\.out\.println\((.*)\)', r'print \1'), (r'System\.out\.print_\((.*?)\)', r'print \1,'), + (r'String\.format\(\"(.*)\" *, *(.*)\)', r'"\1" % (\2)'), (r'(.*?)\.equals\((.*?)\)', r'\1 == \2'), (r'(.*?)\.equalsIgnoreCase\((.*?)\)', r'\1.lower() == \2.lower()'), (r'([\w.]+)\.size\(\)', r'len(\1)'), diff --git a/test/Format.java b/test/Format.java new file mode 100644 index 0000000..5ac5321 --- /dev/null +++ b/test/Format.java @@ -0,0 +1,9 @@ +public class Format { + public static void main(String[] args) { + int i = 22; + String s = "text"; + String r = String.format("> (%d) %s", i, s); + + System.out.println(r); + } +} From a839a715d81d10485d81ef5c470d12616134aaca Mon Sep 17 00:00:00 2001 From: Troy Melhase Date: Thu, 3 May 2012 18:34:12 -0400 Subject: [PATCH 03/33] Renames. --- test/{Format.java => Format0.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{Format.java => Format0.java} (100%) diff --git a/test/Format.java b/test/Format0.java similarity index 100% rename from test/Format.java rename to test/Format0.java From 6a8ded2e52268bd7cf8b1413f9be4f225188add3 Mon Sep 17 00:00:00 2001 From: Iulius Curt Date: Sat, 5 May 2012 00:28:26 +0300 Subject: [PATCH 04/33] String formatting as AST transform (1st iteration) --- java2python/config/default.py | 7 ++++- java2python/mod/transform.py | 49 +++++++++++++++++++++++++++++++++++ test/Format0.java | 4 +-- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/java2python/config/default.py b/java2python/config/default.py index ea34f46..a2cdb67 100644 --- a/java2python/config/default.py +++ b/java2python/config/default.py @@ -162,6 +162,12 @@ (Type('METHOD_CALL') > Type('DOT') > Type('IDENT', 'length'), transform.lengthToLen), + (Type('METHOD_CALL') > Type('DOT') > ( + Type('IDENT', 'String') + + Type('IDENT', 'format') + ), + transform.formatString), + (Type('TYPE') > Type('QUALIFIED_TYPE_IDENT') > Type('IDENT'), transform.typeSub), @@ -189,7 +195,6 @@ moduleOutputSubs = [ (r'System\.out\.println\((.*)\)', r'print \1'), (r'System\.out\.print_\((.*?)\)', r'print \1,'), - (r'String\.format\(\"(.*)\" *, *(.*)\)', r'"\1" % (\2)'), (r'(.*?)\.equals\((.*?)\)', r'\1 == \2'), (r'(.*?)\.equalsIgnoreCase\((.*?)\)', r'\1.lower() == \2.lower()'), (r'([\w.]+)\.size\(\)', r'len(\1)'), diff --git a/java2python/mod/transform.py b/java2python/mod/transform.py index 04fc3f5..fd9bc64 100644 --- a/java2python/mod/transform.py +++ b/java2python/mod/transform.py @@ -11,6 +11,8 @@ # See the java2python.config.default and java2python.lang.selector modules to # understand how and when selectors are associated with these callables. +import re + import keyword import types @@ -89,6 +91,53 @@ def lengthToLen(node, config): expr.addChild(ident) +def formatSyntaxTransf(match): + """ Helper function for formatString AST transform. + + Translates the Java Formatter syntax into Python .format syntax. + + This function gets called by re.sub which matches all the %...$... groups + inside a format specifier string. + """ + groups = match.groupdict() + result = '{' + # TODO: add flags, width and precision + if(groups['idx']): + idx = int(groups['idx'][:-1]) + result += str(idx - 1) # Py starts count from 0 + result += ':' + groups['convers'] + '}' + + return result + +def formatString(node, config): + """ Transforms string formatting like 'String.format("%d %2$s", i, s)' + into '"{:d} {2:s}".format(i, s)'. + """ + dot = node.parent + method = dot.parent + arg_list = method.firstChildOfType(tokens.ARGUMENT_LIST) + call_args = [arg for arg in arg_list.childrenOfType(tokens.EXPR)] + + format = call_args[0].firstChildOfType(tokens.STRING_LITERAL) + args = [arg.firstChildOfType(tokens.IDENT) for arg in call_args[1:]] + + # Translate format syntax + format.token.text = re.sub(r'%(?P\d+\$)?(?P[scdoxefg])', + formatSyntaxTransf, + format.token.text, + flags=re.IGNORECASE) + + left_ident = dot.children[0] + right_ident = dot.children[1] + + # Change AST + arg_list.children.remove(format.parent) + dot.children.remove(left_ident) + dot.children.remove(right_ident) + dot.addChild(format) + dot.addChild(right_ident) + + def typeSub(node, config): """ Maps specific, well-known Java types to their Python counterparts. diff --git a/test/Format0.java b/test/Format0.java index 5ac5321..995aad2 100644 --- a/test/Format0.java +++ b/test/Format0.java @@ -1,8 +1,8 @@ -public class Format { +public class Format0 { public static void main(String[] args) { int i = 22; String s = "text"; - String r = String.format("> (%d) %s", i, s); + String r = String.format("> (%1$d) %2$s", i, s); System.out.println(r); } From 3be801021a1c24efe4fad14fa052de679d465e39 Mon Sep 17 00:00:00 2001 From: Iulius Curt Date: Sun, 6 May 2012 10:33:00 +0300 Subject: [PATCH 05/33] More gracefully degrading string formatting syntax translation --- java2python/mod/transform.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/java2python/mod/transform.py b/java2python/mod/transform.py index fd9bc64..da4c7d9 100644 --- a/java2python/mod/transform.py +++ b/java2python/mod/transform.py @@ -117,15 +117,25 @@ def formatString(node, config): method = dot.parent arg_list = method.firstChildOfType(tokens.ARGUMENT_LIST) call_args = [arg for arg in arg_list.childrenOfType(tokens.EXPR)] - - format = call_args[0].firstChildOfType(tokens.STRING_LITERAL) args = [arg.firstChildOfType(tokens.IDENT) for arg in call_args[1:]] - # Translate format syntax - format.token.text = re.sub(r'%(?P\d+\$)?(?P[scdoxefg])', + # Translate format syntax (if format == string_literal) + format = call_args[0].firstChildOfType(tokens.STRING_LITERAL) + if format: + format.token.text = \ + re.sub(r'%(?P\d+\$)?(?P[scdoxefg])', formatSyntaxTransf, format.token.text, flags=re.IGNORECASE) + else: + # Translation should happen at runtime + format = call_args[0].firstChild() + if format.type == tokens.IDENT: + # String variable + pass + else: + # Function that returns String + pass left_ident = dot.children[0] right_ident = dot.children[1] From 42c3b47bee6defeba4d63a090a1520df22340d91 Mon Sep 17 00:00:00 2001 From: Iulius Curt Date: Mon, 7 May 2012 01:35:24 +0300 Subject: [PATCH 06/33] Added warnings for unhandled string formatting translations --- java2python/mod/transform.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/java2python/mod/transform.py b/java2python/mod/transform.py index da4c7d9..55b49cd 100644 --- a/java2python/mod/transform.py +++ b/java2python/mod/transform.py @@ -12,6 +12,7 @@ # understand how and when selectors are associated with these callables. import re +from logging import warn import keyword import types @@ -132,10 +133,12 @@ def formatString(node, config): format = call_args[0].firstChild() if format.type == tokens.IDENT: # String variable - pass + warn('Formatting string %s is not automatically translated.' + % str(format.token.text)) else: # Function that returns String - pass + warn('Formatting string returned by %s() is not automatically translated.' + % str(format.firstChildOfType(tokens.IDENT).token.text)) left_ident = dot.children[0] right_ident = dot.children[1] From d178ce8a6b06a2392d31e7a8e58786ce6a204b22 Mon Sep 17 00:00:00 2001 From: Iulius Curt Date: Sun, 13 May 2012 17:07:33 +0300 Subject: [PATCH 07/33] String formatting (2nd iteration) handle %n from Java --- java2python/mod/transform.py | 6 +++++- test/Format0.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/java2python/mod/transform.py b/java2python/mod/transform.py index 55b49cd..3565465 100644 --- a/java2python/mod/transform.py +++ b/java2python/mod/transform.py @@ -101,6 +101,10 @@ def formatSyntaxTransf(match): inside a format specifier string. """ groups = match.groupdict() + if groups['convers'] == 'n': + # Means platform-specific line separator + return '\\n' # Py converts \n to os.linesep + result = '{' # TODO: add flags, width and precision if(groups['idx']): @@ -124,7 +128,7 @@ def formatString(node, config): format = call_args[0].firstChildOfType(tokens.STRING_LITERAL) if format: format.token.text = \ - re.sub(r'%(?P\d+\$)?(?P[scdoxefg])', + re.sub(r'%(?P\d+\$)?(?P[scdoxefgn])', formatSyntaxTransf, format.token.text, flags=re.IGNORECASE) diff --git a/test/Format0.java b/test/Format0.java index 995aad2..68a22a4 100644 --- a/test/Format0.java +++ b/test/Format0.java @@ -2,7 +2,7 @@ public class Format0 { public static void main(String[] args) { int i = 22; String s = "text"; - String r = String.format("> (%1$d) %2$s", i, s); + String r = String.format("> (%1$d) %n %2$s", i, s); System.out.println(r); } From 2c82742327aff3d71de64412e07f041e2ee84acd Mon Sep 17 00:00:00 2001 From: Iulius Curt Date: Sun, 13 May 2012 17:48:08 +0300 Subject: [PATCH 08/33] Handle flags, width and precision implemented (string formatting) --- java2python/mod/transform.py | 28 +++++++++++++++++++++++++--- test/Format1.java | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 test/Format1.java diff --git a/java2python/mod/transform.py b/java2python/mod/transform.py index 3565465..d8e2652 100644 --- a/java2python/mod/transform.py +++ b/java2python/mod/transform.py @@ -106,11 +106,33 @@ def formatSyntaxTransf(match): return '\\n' # Py converts \n to os.linesep result = '{' - # TODO: add flags, width and precision + thous_sep = '' + if(groups['idx']): idx = int(groups['idx'][:-1]) result += str(idx - 1) # Py starts count from 0 - result += ':' + groups['convers'] + '}' + result += ':' + + if(groups['flags']): + if ',' in groups['flags']: + thous_sep = ',' + if '+' in groups['flags']: + result += '+' + elif ' ' in groups['flags']: + result += ' ' + if '#' in groups['flags']: + result += '#' + if '0' in groups['flags']: + result += '0' + + if(groups['width']): + result += groups['width'] + result += thous_sep + + if(groups['precision']): + result += groups['precision'] + + result += groups['convers'] + '}' return result @@ -128,7 +150,7 @@ def formatString(node, config): format = call_args[0].firstChildOfType(tokens.STRING_LITERAL) if format: format.token.text = \ - re.sub(r'%(?P\d+\$)?(?P[scdoxefgn])', + re.sub(r'%(?P\d+\$)?(?P[-+# 0,]+)?(?P[0-9]+)?(?P\.[0-9]+)?(?P[scdoxefgn])', formatSyntaxTransf, format.token.text, flags=re.IGNORECASE) diff --git a/test/Format1.java b/test/Format1.java new file mode 100644 index 0000000..29e94ee --- /dev/null +++ b/test/Format1.java @@ -0,0 +1,19 @@ +public class Format1 { + public static void main(String[] args) { + long n = 461012; + String f1 = String.format("%d%n", n); // --> "461012" + String f2 = String.format("%08d%n", n); // --> "00461012" + String f3 = String.format("%+8d%n", n); // --> " +461012" + String f4 = String.format("%,8d%n", n); // --> " 461,012" + String f5 = String.format("%+,8d%n", n); // --> "+461,012" + + System.out.println(f1 + f2 + f3 + f4 + f5); + + double pi = 3.14159265; + String pf1 = String.format("%f%n", pi); // --> "3.141593" + String pf2 = String.format("%.3f%n", pi); // --> "3.142" + String pf3 = String.format("%10.3f%n", pi); // --> " 3.142" + + System.out.println(pf1 + pf2 + pf3); + } +} From 2a4e83d642ac8b9de00c049ed6d4848564b1f62a Mon Sep 17 00:00:00 2001 From: Iulius Curt Date: Wed, 18 Sep 2013 20:48:34 +0300 Subject: [PATCH 09/33] 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 10/33] 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 11/33] 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 12/33] 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 13/33] 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 14/33] 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 15/33] 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 16/33] 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 17/33] 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 18/33] 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 19/33] 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 20/33] 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 21/33] 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 22/33] 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 23/33] 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 24/33] 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 25/33] 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 26/33] 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 27/33] 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 28/33] 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 29/33] 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 30/33] 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 31/33] 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 32/33] 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 33/33] 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