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

Skip to content

String formatting as AST transform (1st iteration) #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 7, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion java2python/config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),

Expand Down Expand Up @@ -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)'),
Expand Down
62 changes: 62 additions & 0 deletions java2python/mod/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
# See the java2python.config.default and java2python.lang.selector modules to
# understand how and when selectors are associated with these callables.

import re
from logging import warn

import keyword
import types

Expand Down Expand Up @@ -89,6 +92,65 @@ 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)]
args = [arg.firstChildOfType(tokens.IDENT) for arg in call_args[1:]]

# Translate format syntax (if format == string_literal)
format = call_args[0].firstChildOfType(tokens.STRING_LITERAL)
if format:
format.token.text = \
re.sub(r'%(?P<idx>\d+\$)?(?P<convers>[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
warn('Formatting string %s is not automatically translated.'
% str(format.token.text))
else:
# Function that returns String
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]

# 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.

Expand Down
4 changes: 2 additions & 2 deletions test/Format0.java
Original file line number Diff line number Diff line change
@@ -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);
}
Expand Down