Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8c515bd

Browse files
author
Troy Melhase
committed
Merge pull request natural#19 from iuliux/master
String formatting as AST transform (1st iteration)
2 parents a839a71 + 42c3b47 commit 8c515bd

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed

java2python/config/default.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@
162162
(Type('METHOD_CALL') > Type('DOT') > Type('IDENT', 'length'),
163163
transform.lengthToLen),
164164

165+
(Type('METHOD_CALL') > Type('DOT') > (
166+
Type('IDENT', 'String') +
167+
Type('IDENT', 'format')
168+
),
169+
transform.formatString),
170+
165171
(Type('TYPE') > Type('QUALIFIED_TYPE_IDENT') > Type('IDENT'),
166172
transform.typeSub),
167173

@@ -189,7 +195,6 @@
189195
moduleOutputSubs = [
190196
(r'System\.out\.println\((.*)\)', r'print \1'),
191197
(r'System\.out\.print_\((.*?)\)', r'print \1,'),
192-
(r'String\.format\(\"(.*)\" *, *(.*)\)', r'"\1" % (\2)'),
193198
(r'(.*?)\.equals\((.*?)\)', r'\1 == \2'),
194199
(r'(.*?)\.equalsIgnoreCase\((.*?)\)', r'\1.lower() == \2.lower()'),
195200
(r'([\w.]+)\.size\(\)', r'len(\1)'),

java2python/mod/transform.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
# See the java2python.config.default and java2python.lang.selector modules to
1212
# understand how and when selectors are associated with these callables.
1313

14+
import re
15+
from logging import warn
16+
1417
import keyword
1518
import types
1619

@@ -89,6 +92,65 @@ def lengthToLen(node, config):
8992
expr.addChild(ident)
9093

9194

95+
def formatSyntaxTransf(match):
96+
""" Helper function for formatString AST transform.
97+
98+
Translates the Java Formatter syntax into Python .format syntax.
99+
100+
This function gets called by re.sub which matches all the %...$... groups
101+
inside a format specifier string.
102+
"""
103+
groups = match.groupdict()
104+
result = '{'
105+
# TODO: add flags, width and precision
106+
if(groups['idx']):
107+
idx = int(groups['idx'][:-1])
108+
result += str(idx - 1) # Py starts count from 0
109+
result += ':' + groups['convers'] + '}'
110+
111+
return result
112+
113+
def formatString(node, config):
114+
""" Transforms string formatting like 'String.format("%d %2$s", i, s)'
115+
into '"{:d} {2:s}".format(i, s)'.
116+
"""
117+
dot = node.parent
118+
method = dot.parent
119+
arg_list = method.firstChildOfType(tokens.ARGUMENT_LIST)
120+
call_args = [arg for arg in arg_list.childrenOfType(tokens.EXPR)]
121+
args = [arg.firstChildOfType(tokens.IDENT) for arg in call_args[1:]]
122+
123+
# Translate format syntax (if format == string_literal)
124+
format = call_args[0].firstChildOfType(tokens.STRING_LITERAL)
125+
if format:
126+
format.token.text = \
127+
re.sub(r'%(?P<idx>\d+\$)?(?P<convers>[scdoxefg])',
128+
formatSyntaxTransf,
129+
format.token.text,
130+
flags=re.IGNORECASE)
131+
else:
132+
# Translation should happen at runtime
133+
format = call_args[0].firstChild()
134+
if format.type == tokens.IDENT:
135+
# String variable
136+
warn('Formatting string %s is not automatically translated.'
137+
% str(format.token.text))
138+
else:
139+
# Function that returns String
140+
warn('Formatting string returned by %s() is not automatically translated.'
141+
% str(format.firstChildOfType(tokens.IDENT).token.text))
142+
143+
left_ident = dot.children[0]
144+
right_ident = dot.children[1]
145+
146+
# Change AST
147+
arg_list.children.remove(format.parent)
148+
dot.children.remove(left_ident)
149+
dot.children.remove(right_ident)
150+
dot.addChild(format)
151+
dot.addChild(right_ident)
152+
153+
92154
def typeSub(node, config):
93155
""" Maps specific, well-known Java types to their Python counterparts.
94156

test/Format0.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
public class Format {
1+
public class Format0 {
22
public static void main(String[] args) {
33
int i = 22;
44
String s = "text";
5-
String r = String.format("> (%d) %s", i, s);
5+
String r = String.format("> (%1$d) %2$s", i, s);
66

77
System.out.println(r);
88
}

0 commit comments

Comments
 (0)