Skip to content
This repository was archived by the owner on Oct 1, 2019. It is now read-only.

Commit 220ecb3

Browse files
committed
Add support for comments
This wires up the comment logic from prettier. This needs some modification inside of prettier itself, so it won't work as is. - locStart/End is ast-specific, we need a way to set it up for each parser. In this case I reused on that already existed: https://github.com/prettier/prettier/blob/master/src/util.js#L260-L262 - getSortedChildNodes as well, need a way to traverse the ast: https://github.com/prettier/prettier/blob/master/src/comments.js#L38 ```js (node.kind && node.kind !== "Comment") || node.ast_type && node.ast_type !== "comment") // <-- added ) { ``` - printComments as well: https://github.com/prettier/prettier/blob/master/src/comments.js#L928-L929 ```js switch (comment.type || comment.kind || comment.ast_type) { case "comment": return comment.value; case "Comment": ``` If we tweak those two small things in prettier itself, then it's able to print comments using the heuristic. @azz, do you think you'd be able to extract those out to be parser-specific?
1 parent b67650f commit 220ecb3

File tree

6 files changed

+211
-6
lines changed

6 files changed

+211
-6
lines changed

src/parser.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,8 @@ function parse(text, parsers, opts) {
2525
const pythonExectuable = `python${opts.pythonVersion == "2" ? "" : "3"}`;
2626
const executionResult = parseText(text, pythonExectuable);
2727

28-
const ast = JSON.parse(executionResult.stdout.toString());
29-
30-
// TODO: add comments
31-
32-
ast.comments = [];
28+
const res = executionResult.stdout.toString();
29+
const ast = JSON.parse(res);
3330
return ast;
3431
}
3532

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`comments.py 1`] = `
4+
if a: # a
5+
# b
6+
c
7+
8+
# c
9+
10+
d
11+
12+
# e
13+
14+
call(
15+
# a
16+
)
17+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18+
if a: # a
19+
# b
20+
c
21+
22+
# c
23+
24+
d
25+
26+
# e
27+
28+
call()
29+
# a
30+
31+
`;

tests/python_comments/comments.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
if a: # a
2+
# b
3+
c
4+
5+
# c
6+
7+
d
8+
9+
# e
10+
11+
call(
12+
# a
13+
)

tests/python_comments/jsfmt.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
run_spec(__dirname, ["python"]);

tests/python_expressions/__snapshots__/jsfmt.spec.js.snap

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,14 +1039,18 @@ a=1;a&=2
10391039
a=1;a^=2
10401040
a=1;a|=2
10411041
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1042+
# https://bitbucket.org/pypy/pypy/src/f9e4e9cb7b1949c548cb16ab1520e7ebced75dda/pypy/interpreter/pyparser/test/expressions.py
1043+
10421044
0
10431045
10441046
7
10451047
10461048
-3
10471049
1050+
# 053
10481051
24
10491052
1053+
# 14L
10501054
1
10511055
10521056
3.9
@@ -1059,6 +1063,8 @@ a=1;a|=2
10591063
10601064
90000000000000
10611065
1066+
# 3j
1067+
10621068
x = a + 1
10631069
10641070
x = 1 - a
@@ -1083,8 +1089,13 @@ x = a + 1 * b
10831089
10841090
x = a * b / c
10851091
1092+
# x = a * (1 + c)
10861093
x, y, z = 1, 2, 3
10871094
1095+
# x = 'a' 'b' 'c'
1096+
# del foo
1097+
# del foo[bar]
1098+
# del foo.bar
10881099
l[0]
10891100
10901101
k[v]
@@ -1105,6 +1116,8 @@ f("foo")("bar")("spam").read()[0]
11051116
11061117
a.b[0][0]
11071118
1119+
# a.b[0][:]
1120+
# a.b[0][::]
11081121
a.b[0][0].pop()[0].push("bar")("baz").spam
11091122
11101123
a.b[0].read()[1][2].foo().spam()[0].bar
@@ -1119,8 +1132,12 @@ a.b[0].read()[1][2].foo().spam()[0].bar ** 2
11191132
11201133
l[start:end] = l2
11211134
1135+
# l[::] = l2
1136+
# a = \`s\`
1137+
# a = \`1 + 2 + f(3, 4)\`
11221138
[a, b] = c
11231139
1140+
# (a, b) = c
11241141
[a, (b, c), d] = e
11251142
11261143
a, (b, c), d = e
@@ -1133,6 +1150,9 @@ l = func()
11331150
11341151
l = func(10)
11351152
1153+
# l = func(10, 12, a, b=c, *args)
1154+
# l = func(10, 12, a, b=c, **kwargs)
1155+
# l = func(10, 12, a, b=c, *args, **kwargs)
11361156
l = func(10, 12, a, b=c)
11371157
11381158
e = l.pop(3)
@@ -1157,8 +1177,21 @@ l = [i for j in range(10) for i in range(j) if j % 2 == 0]
11571177
11581178
l = [i for j in range(10) for i in range(j) if j % 2 == 0 and i % 2 == 0]
11591179
1180+
# l = [(a, b) for (a,b,c) in l2]
1181+
# l = [{a:b} for (a,b,c) in l2]
11601182
l = [i for j in k if j % 2 == 0 j * 2 < 20 for i in j if i % 2 == 0]
11611183
1184+
# l = (i for i in j)
1185+
# l = (i for i in j if i%2 == 0)
1186+
# l = (i for j in k for i in j)
1187+
# l = (i for j in k for i in j if j%2==0)
1188+
# l = (i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0)
1189+
# l = (i for i in [ j*2 for j in range(10) ] )
1190+
# l = [i for i in ( j*2 for j in range(10) ) ]
1191+
# l = (i for i in [ j*2 for j in ( k*3 for k in range(10) ) ] )
1192+
# l = [i for j in ( j*2 for j in [ k*3 for k in range(10) ] ) ]
1193+
# l = f(i for i in j)
1194+
11621195
l = {a: b,"c": 0}
11631196
11641197
l = {}
@@ -1195,32 +1228,64 @@ a is b
11951228
11961229
3 < x < 5
11971230
1231+
# (3 < x) < 5
11981232
a < b < c < d
11991233
1234+
# (a < b) < (c < d)
1235+
# a < (b < c) < d
1236+
12001237
a = b
12011238
12021239
c = d
12031240
1241+
# a = b = c = d
1242+
12041243
a.b = 2
12051244
12061245
x = a.b
12071246
1247+
# l[:]
1248+
# l[::]
12081249
l[1:2]
12091250
1251+
# l[1:]
12101252
l[:2]
12111253
1254+
# l[1::]
1255+
# l[:1:]
12121256
l[::1]
12131257
1258+
# l[1:2:]
12141259
l[:1:2]
12151260
12161261
l[1::2]
12171262
12181263
l[0:1:2]
12191264
1265+
# a.b.l[:]
12201266
a.b.l[1:2]
12211267
1268+
# a.b.l[1:]
1269+
# a.b.l[:2]
12221270
a.b.l[0:1:2]
12231271
1272+
# a[1:2:3, 100]
1273+
# a[:2:3, 100]
1274+
# a[1::3, 100,]
1275+
# a[1:2:, 100]
1276+
# a[1:2, 100]
1277+
# a[1:, 100,]
1278+
# a[:2, 100]
1279+
# a[:, 100]
1280+
# a[100, 1:2:3,]
1281+
# a[100, :2:3]
1282+
# a[100, 1::3]
1283+
# a[100, 1:2:,]
1284+
# a[100, 1:2]
1285+
# a[100, 1:]
1286+
# a[100, :2,]
1287+
# a[100, :]
1288+
#
12241289
import os
12251290
12261291
import sys, os
@@ -1247,6 +1312,7 @@ from os import path, system
12471312
12481313
from os import path as P, system as S
12491314
1315+
# from os import (path as P, system as S,)
12501316
from os import *
12511317
12521318
if a == 1:
@@ -1259,6 +1325,10 @@ elif a == 2:
12591325
else:
12601326
a += 4
12611327
1328+
# if a and not b == c: pass
1329+
# if a and not not not b == c: pass
1330+
# if 0: print 'foo'
1331+
12621332
assert False
12631333
12641334
assert a == 1
@@ -1267,12 +1337,33 @@ assert a == 1 and b == 2
12671337
12681338
assert a == 1 and b == 2, "assertion failed"
12691339
1340+
# exec a
1341+
# exec "a=b+3"
1342+
# exec a in f()
1343+
# exec a in f(), g()
1344+
1345+
# print
1346+
# print a
1347+
# print a,
1348+
# print a, b
1349+
# print a, "b", c
1350+
# print >> err
1351+
# print >> err, "error"
1352+
# print >> err, "error",
1353+
# print >> err, "error", a
1354+
1355+
# global a
1356+
# global a,b,c
1357+
12701358
raise
12711359
12721360
raise ValueError
12731361
12741362
raise ValueError("error")
12751363
1364+
# raise ValueError, "error"
1365+
# raise ValueError, "error", foo
1366+
12761367
try:
12771368
a
12781369
@@ -1287,6 +1378,55 @@ try:
12871378
except NameError:
12881379
pass
12891380
1381+
# try:
1382+
# a
1383+
# b
1384+
# except NameError, err:
1385+
# pass
1386+
# try:
1387+
# a
1388+
# b
1389+
# except (NameError, ValueError):
1390+
# pass
1391+
# try:
1392+
# a
1393+
# b
1394+
# except (NameError, ValueError), err:
1395+
# pass
1396+
# try:
1397+
# a
1398+
# except NameError, err:
1399+
# pass
1400+
# except ValueError, err:
1401+
# pass
1402+
# def f():
1403+
# try:
1404+
# a
1405+
# except NameError, err:
1406+
# a = 1
1407+
# b = 2
1408+
# except ValueError, err:
1409+
# a = 2
1410+
# return a
1411+
# try:
1412+
# a
1413+
# except NameError, err:
1414+
# a = 1
1415+
# except ValueError, err:
1416+
# a = 2
1417+
# else:
1418+
# a += 3
1419+
# try:
1420+
# a
1421+
# finally:
1422+
# b
1423+
# def f():
1424+
# try:
1425+
# return a
1426+
# finally:
1427+
# a = 3
1428+
# return 1
1429+
12901430
def f():
12911431
return 1
12921432
@@ -1314,6 +1454,12 @@ def f(*args):
13141454
def f(**kwargs):
13151455
return 1
13161456
1457+
# def f(t=()): pass
1458+
# def f(a, b, (c, d), e): pass
1459+
# def f(a, b, (c, (d, e), f, (g, h))): pass
1460+
# def f(a, b, (c, (d, e), f, (g, h)), i): pass
1461+
# def f((a)): pass
1462+
13171463
class Pdb(bdb.Bdb,cmd.Cmd):
13181464
pass
13191465
@@ -1343,6 +1489,12 @@ def foo():
13431489
13441490
return a
13451491
1492+
# def foo():
1493+
# """doc"""; print 1
1494+
# a=1
1495+
1496+
# """Docstring""";print 1
1497+
13461498
def f():
13471499
return
13481500

vendor/python/astexport.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,15 @@
66

77

88
def export_json(atok, pretty_print=False):
9+
dict = export_dict(atok)
10+
dict['comments'] = [{
11+
'ast_type': 'comment',
12+
'value': token.string,
13+
'start': token.startpos,
14+
'end': token.endpos,
15+
} for token in atok.tokens if token.type == 57]
916
return json.dumps(
10-
export_dict(atok),
17+
dict,
1118
indent=4 if pretty_print else None,
1219
sort_keys=True,
1320
separators=(",", ": ") if pretty_print else (",", ":")
@@ -53,6 +60,10 @@ def default_visit(self, node):
5360
# Use None as default when lineno/col_offset are not set
5461
args[attr] = meth(getattr(node, attr, None))
5562

63+
if hasattr(node, 'first_token'):
64+
args['start'] = node.first_token.startpos
65+
args['end'] = node.last_token.endpos
66+
5667
args['source'] = self.atok.get_text(node)
5768

5869
return args

0 commit comments

Comments
 (0)