Skip to content

Commit 6548316

Browse files
author
Troy Melhase
committed
AST transforms for .length() method call. Fixes natural#17.
1 parent 4916ddc commit 6548316

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

java2python/config/default.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@
159159
(Type('TYPE') > Type('LONG'), transform.typeSub),
160160
(Type('TYPE') > Type('DOUBLE'), transform.typeSub),
161161

162+
(Type('METHOD_CALL') > Type('DOT') > Type('IDENT', 'length'),
163+
transform.lengthToLen),
164+
162165
(Type('TYPE') > Type('QUALIFIED_TYPE_IDENT') > Type('IDENT'),
163166
transform.typeSub),
164167

@@ -193,7 +196,6 @@
193196
(r'(\s)(\S*?)(\.toString\(\))', r'\1\2.__str__()'),
194197
(r'(\s)def toString', r'\1def __str__'),
195198
(r'(\s)(\S*?)(\.toLowerCase\(\))', r'\1\2.lower()'),
196-
(r'(\s)(\S*?)(\.length\(\))', r'\1len(\2)'),
197199
(r'(.*?)IndexOutOfBoundsException\((.*?)\)', r'\1IndexError(\2)'),
198200
(r'\.__class__\.getName\(\)', '.__class__.__name__'),
199201
(r'\.getClass\(\)', '.__class__'),

java2python/mod/transform.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import keyword
1515
import types
1616

17+
from java2python.lang import tokens
18+
1719

1820
def invalidPythonNames():
1921
""" Creates a list of valid Java identifiers that are invalid in Python. """
@@ -55,6 +57,38 @@ def syntaxSafeFloatLiteral(node, config):
5557
node.token.text = value
5658

5759

60+
def lengthToLen(node, config):
61+
""" Transforms expressions like 'value.length()' to 'len(value)'.
62+
63+
This method changes AST branches like this:
64+
65+
METHOD_CALL [start=45, stop=49]
66+
DOT . [line=4, start=45, stop=47]
67+
IDENT foo [line=4, start=45]
68+
IDENT length [line=4, start=47]
69+
ARGUMENT_LIST [line=4, start=48, stop=49]
70+
71+
Into branches like this:
72+
73+
IDENT len(foo) [line=4, start=45]
74+
75+
Notice that the resulting IDENT node text is invalid. We can't use a
76+
METHOD_CALL token because those are always bound to a class or instance.
77+
It would be best to add a new token type, and that option will be explored
78+
if we run into this problem again.
79+
80+
"""
81+
dot = node.parent
82+
method = dot.parent
83+
84+
ident = dot.firstChildOfType(tokens.IDENT)
85+
ident.token.text = 'len({})'.format(ident.text)
86+
87+
expr = method.parent
88+
expr.children.remove(method)
89+
expr.addChild(ident)
90+
91+
5892
def typeSub(node, config):
5993
""" Maps specific, well-known Java types to their Python counterparts.
6094

test/Length0.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Length0 {
2+
public static int dummy(int v) {
3+
return v + 1;
4+
}
5+
6+
public static void main(String[] args) {
7+
String foo = "asdf";
8+
System.out.println( dummy(foo.length() ) );
9+
}
10+
11+
}

0 commit comments

Comments
 (0)