Skip to content

Commit 7ab57cf

Browse files
author
hartsantler
committed
new command line option --analyzer for translator.py, trigger code analysis and debugging using dartanalyzer from the Dart SDK.
1 parent 83900ef commit 7ab57cf

2 files changed

Lines changed: 103 additions & 66 deletions

File tree

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,20 @@ will be converted into JavaScript.
5959

6060
Usage::
6161

62-
translator.py [--dart|--coffee|--lua|--no-wrapper] file.py
62+
translator.py [--help|--dart|--coffee|--lua|--no-wrapper|--analyzer] file.py
6363

6464
Examples::
6565

6666
cd pythonjs
6767
./translator.py myscript.py > myscript.js
6868
./translator.py myapp.html > app.html
6969

70+
The option `--no-wrapper` will output the raw JavaScript, by default the output is wrapped as a requirejs module.
71+
72+
The option `--analyzer` requires the Dart SDK is installed to your home directory: `~/dart-sdk`,
73+
if this option is used then your script is also translated using the dart backend and fed to
74+
`dartanalyzer` which will perform static analysis of your code. Dartanalyzer is able to catch many types of errors, like: missing functions, invalid names, calling a function with the wrong argument types. The quality of the analysis will depend on how much type information can be
75+
inferred from your code, combined with the variables you have manually typed. If dartanalyzer detects an error in your code, translation will abort, and debugging information is printed.
7076

7177
Extra Python Syntax
7278
-------------------

pythonjs/translator.py

Lines changed: 96 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -9,81 +9,112 @@
99
from pythonjs_to_luajs import main as pythonjs_to_luajs
1010

1111
cmdhelp = """\
12-
usage: translator.py [--dart|--coffee|--lua] file.py
13-
translator.py --visjs file.py\
12+
usage: translator.py [--dart|--coffee|--lua|--visjs|--no-wrapper|--analyze] file.py
13+
14+
example:
15+
translator.py --no-wrapper myscript.py > myscript.js
1416
"""
1517

18+
1619
def main(script, module_path=None):
17-
if '--visjs' in sys.argv:
18-
import python_to_visjs
19-
return python_to_visjs.main( script )
20-
else:
21-
code = ''
22-
if '--dart' in sys.argv:
23-
a = python_to_pythonjs(script, dart=True, module_path=module_path)
24-
code = pythonjs_to_dart( a )
25-
elif '--coffee' in sys.argv:
26-
a = python_to_pythonjs(script, coffee=True, module_path=module_path)
27-
code = pythonjs_to_coffee( a )
28-
elif '--lua' in sys.argv:
29-
a = python_to_pythonjs(script, lua=True, module_path=module_path)
30-
try: code = pythonjs_to_lua( a )
31-
except SyntaxError:
32-
err = traceback.format_exc()
33-
lineno = 0
34-
for line in err.splitlines():
35-
if "<unknown>" in line:
36-
lineno = int(line.split()[-1])
20+
if '--visjs' in sys.argv:
21+
import python_to_visjs
22+
return python_to_visjs.main( script )
23+
else:
24+
code = ''
25+
res = None
26+
if '--dart' in sys.argv:
27+
a = python_to_pythonjs(script, dart=True, module_path=module_path)
28+
code = pythonjs_to_dart( a )
29+
elif '--coffee' in sys.argv:
30+
a = python_to_pythonjs(script, coffee=True, module_path=module_path)
31+
code = pythonjs_to_coffee( a )
32+
elif '--lua' in sys.argv:
33+
a = python_to_pythonjs(script, lua=True, module_path=module_path)
34+
try: code = pythonjs_to_lua( a )
35+
except SyntaxError:
36+
err = traceback.format_exc()
37+
lineno = 0
38+
for line in err.splitlines():
39+
if "<unknown>" in line:
40+
lineno = int(line.split()[-1])
41+
42+
b = a.splitlines()[ lineno ]
43+
sys.stderr.write( '\n'.join([err,b]) )
44+
45+
elif '--luajs' in sys.argv: ## converts back to javascript
46+
a = python_to_pythonjs(script, lua=True, module_path=module_path)
47+
code = pythonjs_to_luajs( a )
48+
else:
49+
a = python_to_pythonjs(script, module_path=module_path)
50+
if isinstance(a, dict):
51+
res = {}
52+
for jsfile in a:
53+
res[ jsfile ] = pythonjs_to_javascript( a[jsfile], webworker=jsfile != 'main' )
54+
return res
55+
else:
56+
## requirejs module is on by default, this wraps the code in a `define` function
57+
## and returns `__module__`
58+
## if --no-wrapper is used, then the raw javascript is returned.
59+
code = pythonjs_to_javascript( a, requirejs='--no-wrapper' not in sys.argv )
60+
61+
if '--analyze' in sys.argv:
62+
dartanalyzer = os.path.expanduser('~/dart-sdk/bin/dartanalyzer')
63+
#dart2js = os.path.expanduser('~/dart-sdk/bin/dart2js')
64+
assert os.path.isfile( dartanalyzer )
3765

38-
b = a.splitlines()[ lineno ]
39-
sys.stderr.write( '\n'.join([err,b]) )
40-
41-
elif '--luajs' in sys.argv: ## converts back to javascript
42-
a = python_to_pythonjs(script, lua=True, module_path=module_path)
43-
code = pythonjs_to_luajs( a )
44-
else:
45-
a = python_to_pythonjs(script, module_path=module_path)
46-
if isinstance(a, dict):
47-
res = {}
48-
for jsfile in a:
49-
res[ jsfile ] = pythonjs_to_javascript( a[jsfile], webworker=jsfile != 'main' )
50-
return res
51-
else:
52-
## requirejs module is on by default, this wraps the code in a `define` function
53-
## and returns `__module__`
54-
## if --no-wrapper is used, then the raw javascript is returned.
55-
code = pythonjs_to_javascript( a, requirejs='--no-wrapper' not in sys.argv )
66+
x = python_to_pythonjs(script, dart=True, module_path=module_path)
67+
dartcode = pythonjs_to_dart( x )
68+
path = '/tmp/debug.dart'
69+
open(path, 'wb').write( dartcode )
70+
import subprocess
71+
try:
72+
subprocess.check_output( [dartanalyzer, path] )
73+
except subprocess.CalledProcessError as err:
74+
dartcodelines = dartcode.splitlines()
75+
for line in err.output.splitlines():
76+
if line.startswith('[error]'):
77+
a,b = line.split( path )
78+
a = a[:-1]
79+
print( '\x1B[0;31m' + a + '\x1B[0m' )
80+
lineno = int( b.split('line ')[-1].split(',')[0] )
81+
print('line: %s' %lineno)
82+
print( dartcodelines[lineno-1] )
83+
sys.exit(1)
5684

57-
return code
85+
if res: ## dict return
86+
return res
87+
else:
88+
return code
5889

5990
def command():
60-
if '-h' in sys.argv or '--help' in sys.argv:
61-
print(cmdhelp)
62-
return
91+
if '-h' in sys.argv or '--help' in sys.argv:
92+
print(cmdhelp)
93+
return
6394

64-
mpath = None
65-
scripts = []
66-
if len(sys.argv) > 1:
67-
for arg in sys.argv[1:]:
68-
if arg.endswith('.py') or arg.endswith('.html'):
69-
scripts.append( arg )
70-
if mpath is None:
71-
mpath = os.path.split(arg)[0]
95+
mpath = None
96+
scripts = []
97+
if len(sys.argv) > 1:
98+
for arg in sys.argv[1:]:
99+
if arg.endswith('.py') or arg.endswith('.html'):
100+
scripts.append( arg )
101+
if mpath is None:
102+
mpath = os.path.split(arg)[0]
72103

73-
if len(scripts):
74-
a = []
75-
for script in scripts:
76-
a.append( open(script, 'rb').read() )
77-
data = '\n'.join( a )
78-
else:
79-
data = sys.stdin.read()
104+
if len(scripts):
105+
a = []
106+
for script in scripts:
107+
a.append( open(script, 'rb').read() )
108+
data = '\n'.join( a )
109+
else:
110+
data = sys.stdin.read()
80111

81-
js = main(data, module_path=mpath)
82-
if isinstance(js, dict):
83-
print( json.dumps(js) )
84-
else:
85-
print(js)
112+
js = main(data, module_path=mpath)
113+
if isinstance(js, dict):
114+
print( json.dumps(js) )
115+
else:
116+
print(js)
86117

87118

88119
if __name__ == '__main__':
89-
command()
120+
command()

0 commit comments

Comments
 (0)