prettier 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +55 -2
- data/CONTRIBUTING.md +2 -2
- data/README.md +41 -12
- data/node_modules/prettier/bin-prettier.js +13702 -11629
- data/node_modules/prettier/index.js +19191 -16565
- data/node_modules/prettier/parser-angular.js +67 -0
- data/node_modules/prettier/parser-babel.js +22 -0
- data/node_modules/prettier/parser-espree.js +22 -0
- data/node_modules/prettier/parser-flow.js +22 -0
- data/node_modules/prettier/parser-glimmer.js +1 -0
- data/node_modules/prettier/parser-graphql.js +1 -0
- data/node_modules/prettier/parser-html.js +132 -0
- data/node_modules/prettier/parser-markdown.js +34 -0
- data/node_modules/prettier/parser-meriyah.js +22 -0
- data/node_modules/prettier/parser-postcss.js +22 -0
- data/node_modules/prettier/parser-typescript.js +22 -0
- data/node_modules/prettier/parser-yaml.js +15 -0
- data/node_modules/prettier/third-party.js +1042 -833
- data/package.json +5 -5
- data/rubocop.yml +12 -0
- data/src/haml/parser.js +6 -5
- data/src/haml/parser.rb +8 -3
- data/src/haml/printer.js +428 -18
- data/src/parser/netcat.js +0 -2
- data/src/parser/parseSync.js +153 -14
- data/src/parser/server.rb +7 -2
- data/src/plugin.js +7 -1
- data/src/rbs/parser.js +3 -5
- data/src/rbs/parser.rb +7 -3
- data/src/rbs/printer.js +46 -8
- data/src/ruby/embed.js +7 -5
- data/src/ruby/nodes/args.js +111 -19
- data/src/ruby/nodes/calls.js +8 -1
- data/src/ruby/nodes/conditionals.js +47 -45
- data/src/ruby/nodes/hashes.js +5 -14
- data/src/ruby/nodes/heredocs.js +5 -3
- data/src/ruby/nodes/params.js +2 -9
- data/src/ruby/nodes/strings.js +95 -2
- data/src/ruby/parser.js +3 -5
- data/src/ruby/parser.rb +82 -31
- data/src/ruby/printer.js +10 -1
- data/src/utils.js +1 -1
- data/src/utils/inlineEnsureParens.js +1 -0
- data/src/utils/literallineWithoutBreakParent.js +7 -0
- data/src/utils/skipAssignIndent.js +8 -1
- metadata +15 -15
- data/src/haml/nodes/comment.js +0 -27
- data/src/haml/nodes/doctype.js +0 -34
- data/src/haml/nodes/filter.js +0 -16
- data/src/haml/nodes/hamlComment.js +0 -21
- data/src/haml/nodes/plain.js +0 -6
- data/src/haml/nodes/root.js +0 -8
- data/src/haml/nodes/script.js +0 -33
- data/src/haml/nodes/silentScript.js +0 -59
- data/src/haml/nodes/tag.js +0 -193
- data/src/parser/getLang.js +0 -32
- data/src/parser/getNetcat.js +0 -50
- data/src/parser/requestParse.js +0 -74
- data/src/utils/literalLineNoBreak.js +0 -7
data/src/ruby/nodes/calls.js
CHANGED
@@ -4,6 +4,7 @@ const {
|
|
4
4
|
hardline,
|
5
5
|
ifBreak,
|
6
6
|
indent,
|
7
|
+
join,
|
7
8
|
softline
|
8
9
|
} = require("../../prettier");
|
9
10
|
const { makeCall, noIndent } = require("../../utils");
|
@@ -133,7 +134,13 @@ function printMethodAddArg(path, opts, print) {
|
|
133
134
|
);
|
134
135
|
}
|
135
136
|
|
136
|
-
|
137
|
+
// If there are already parentheses, then we can just use the doc that's
|
138
|
+
// already printed.
|
139
|
+
if (argNode.type == "arg_paren") {
|
140
|
+
return concat([methodDoc, argsDoc]);
|
141
|
+
}
|
142
|
+
|
143
|
+
return concat([methodDoc, " ", join(", ", argsDoc), " "]);
|
137
144
|
}
|
138
145
|
|
139
146
|
function printMethodAddBlock(path, opts, print) {
|
@@ -190,57 +190,59 @@ const canTernary = (path) => {
|
|
190
190
|
};
|
191
191
|
|
192
192
|
// A normalized print function for both `if` and `unless` nodes.
|
193
|
-
const printConditional =
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
193
|
+
const printConditional =
|
194
|
+
(keyword) =>
|
195
|
+
(path, { rubyModifier }, print) => {
|
196
|
+
if (canTernary(path)) {
|
197
|
+
let ternaryParts = [path.call(print, "body", 0), " ? "].concat(
|
198
|
+
printTernaryClauses(
|
199
|
+
keyword,
|
200
|
+
path.call(print, "body", 1),
|
201
|
+
path.call(print, "body", 2, "body", 0)
|
202
|
+
)
|
203
|
+
);
|
204
|
+
|
205
|
+
if (["binary", "call"].includes(path.getParentNode().type)) {
|
206
|
+
ternaryParts = ["("].concat(ternaryParts).concat(")");
|
207
|
+
}
|
208
|
+
|
209
|
+
return group(
|
210
|
+
ifBreak(printWithAddition(keyword, path, print), concat(ternaryParts))
|
211
|
+
);
|
205
212
|
}
|
206
213
|
|
207
|
-
|
208
|
-
ifBreak(printWithAddition(keyword, path, print), concat(ternaryParts))
|
209
|
-
);
|
210
|
-
}
|
211
|
-
|
212
|
-
const [predicate, statements, addition] = path.getValue().body;
|
214
|
+
const [predicate, statements, addition] = path.getValue().body;
|
213
215
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
216
|
+
// If there's an additional clause that wasn't matched earlier, we know we
|
217
|
+
// can't go for the inline option.
|
218
|
+
if (addition) {
|
219
|
+
return group(printWithAddition(keyword, path, print, { breaking: true }));
|
220
|
+
}
|
219
221
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
222
|
+
// If the body of the conditional is empty, then we explicitly have to use the
|
223
|
+
// block form.
|
224
|
+
if (isEmptyStmts(statements)) {
|
225
|
+
return concat([
|
226
|
+
`${keyword} `,
|
227
|
+
align(keyword.length + 1, path.call(print, "body", 0)),
|
228
|
+
concat([hardline, "end"])
|
229
|
+
]);
|
230
|
+
}
|
229
231
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
232
|
+
// If the predicate of the conditional contains an assignment, then we can't
|
233
|
+
// know for sure that it doesn't impact the body of the conditional, so we
|
234
|
+
// have to default to the block form.
|
235
|
+
if (containsAssignment(predicate)) {
|
236
|
+
return concat([
|
237
|
+
`${keyword} `,
|
238
|
+
align(keyword.length + 1, path.call(print, "body", 0)),
|
239
|
+
indent(concat([hardline, path.call(print, "body", 1)])),
|
240
|
+
concat([hardline, "end"])
|
241
|
+
]);
|
242
|
+
}
|
241
243
|
|
242
|
-
|
243
|
-
};
|
244
|
+
return printSingle(keyword)(path, { rubyModifier }, print);
|
245
|
+
};
|
244
246
|
|
245
247
|
module.exports = {
|
246
248
|
else: (path, opts, print) => {
|
data/src/ruby/nodes/hashes.js
CHANGED
@@ -56,28 +56,19 @@ function printHashKeyLabel(path, print) {
|
|
56
56
|
case "symbol_literal":
|
57
57
|
return concat([path.call(print, "body", 0), ":"]);
|
58
58
|
case "dyna_symbol": {
|
59
|
-
|
60
|
-
|
61
|
-
// We're going to slice off the starting colon character so that we can
|
62
|
-
// move it to the end. If there are comments, then we're going to go
|
63
|
-
// further into the printed doc nodes.
|
64
|
-
if (parts[0] === ":") {
|
65
|
-
parts.splice(0, 1);
|
66
|
-
} else {
|
67
|
-
parts[1].parts.splice(0, 1);
|
68
|
-
}
|
69
|
-
|
70
|
-
return concat(parts.concat(":"));
|
59
|
+
return concat([print(path), ":"]);
|
71
60
|
}
|
72
61
|
}
|
73
62
|
}
|
74
63
|
|
75
64
|
function printHashKeyRocket(path, print) {
|
76
65
|
const node = path.getValue();
|
77
|
-
|
66
|
+
let doc = print(path);
|
78
67
|
|
79
68
|
if (node.type === "@label") {
|
80
|
-
|
69
|
+
doc = concat([":", doc.slice(0, doc.length - 1)]);
|
70
|
+
} else if (node.type === "dyna_symbol") {
|
71
|
+
doc = concat([":", doc]);
|
81
72
|
}
|
82
73
|
|
83
74
|
return concat([doc, " =>"]);
|
data/src/ruby/nodes/heredocs.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
const { concat, group, lineSuffix, join } = require("../../prettier");
|
2
|
-
const {
|
2
|
+
const { literallineWithoutBreakParent } = require("../../utils");
|
3
3
|
|
4
4
|
function printHeredoc(path, opts, print) {
|
5
5
|
const { body, ending } = path.getValue();
|
@@ -11,7 +11,7 @@ function printHeredoc(path, opts, print) {
|
|
11
11
|
}
|
12
12
|
|
13
13
|
// In this case, the part of the string is just regular string content
|
14
|
-
return join(
|
14
|
+
return join(literallineWithoutBreakParent, part.body.split("\n"));
|
15
15
|
});
|
16
16
|
|
17
17
|
// We use a literalline break because matching indentation is required
|
@@ -23,7 +23,9 @@ function printHeredoc(path, opts, print) {
|
|
23
23
|
concat([
|
24
24
|
path.call(print, "beging"),
|
25
25
|
lineSuffix(
|
26
|
-
group(
|
26
|
+
group(
|
27
|
+
concat([literallineWithoutBreakParent].concat(parts).concat(ending))
|
28
|
+
)
|
27
29
|
)
|
28
30
|
])
|
29
31
|
);
|
data/src/ruby/nodes/params.js
CHANGED
@@ -17,15 +17,8 @@ function printRestParam(symbol) {
|
|
17
17
|
}
|
18
18
|
|
19
19
|
function printParams(path, opts, print) {
|
20
|
-
const [
|
21
|
-
|
22
|
-
optls,
|
23
|
-
rest,
|
24
|
-
post,
|
25
|
-
kwargs,
|
26
|
-
kwargRest,
|
27
|
-
block
|
28
|
-
] = path.getValue().body;
|
20
|
+
const [reqs, optls, rest, post, kwargs, kwargRest, block] =
|
21
|
+
path.getValue().body;
|
29
22
|
let parts = [];
|
30
23
|
|
31
24
|
if (reqs) {
|
data/src/ruby/nodes/strings.js
CHANGED
@@ -82,13 +82,106 @@ function printChar(path, { rubySingleQuote }, _print) {
|
|
82
82
|
return concat([quote, body.slice(1), quote]);
|
83
83
|
}
|
84
84
|
|
85
|
+
function printPercentSDynaSymbol(path, opts, print) {
|
86
|
+
const node = path.getValue();
|
87
|
+
const parts = [];
|
88
|
+
|
89
|
+
// Push on the quote, which includes the opening character.
|
90
|
+
parts.push(node.quote);
|
91
|
+
|
92
|
+
path.each((childPath) => {
|
93
|
+
const childNode = childPath.getValue();
|
94
|
+
|
95
|
+
if (childNode.type !== "@tstring_content") {
|
96
|
+
// Here we are printing an embedded variable or expression.
|
97
|
+
parts.push(print(childPath));
|
98
|
+
} else {
|
99
|
+
// Here we are printing plain string content.
|
100
|
+
parts.push(join(literalline, childNode.body.split("\n")));
|
101
|
+
}
|
102
|
+
}, "body");
|
103
|
+
|
104
|
+
// Push on the closing character, which is the opposite of the third
|
105
|
+
// character from the opening.
|
106
|
+
parts.push(quotePairs[node.quote[2]]);
|
107
|
+
|
108
|
+
return concat(parts);
|
109
|
+
}
|
110
|
+
|
111
|
+
// We don't actually want to print %s symbols, as they're much more rarely seen
|
112
|
+
// in the wild. But we're going to be forced into it if it's a multi-line symbol
|
113
|
+
// or if the quoting would get super complicated.
|
114
|
+
function shouldPrintPercentSDynaSymbol(node) {
|
115
|
+
// We shouldn't print a %s dyna symbol if it was not already that way in the
|
116
|
+
// original source.
|
117
|
+
if (node.quote[0] !== "%") {
|
118
|
+
return false;
|
119
|
+
}
|
120
|
+
|
121
|
+
// Here we're going to check if there is a closing character, a new line, or a
|
122
|
+
// quote in the content of the dyna symbol. If there is, then quoting could
|
123
|
+
// get weird, so just bail out and stick to the original bounds in the source.
|
124
|
+
const closing = quotePairs[node.quote[2]];
|
125
|
+
|
126
|
+
return node.body.some(
|
127
|
+
(child) =>
|
128
|
+
child.type === "@tstring_content" &&
|
129
|
+
(child.body.includes("\n") ||
|
130
|
+
child.body.includes(closing) ||
|
131
|
+
child.body.includes("'") ||
|
132
|
+
child.body.includes('"'))
|
133
|
+
);
|
134
|
+
}
|
135
|
+
|
85
136
|
// Prints a dynamic symbol. Assumes there's a quote property attached to the
|
86
137
|
// node that will tell us which quote to use when printing. We're just going to
|
87
138
|
// use whatever quote was provided.
|
139
|
+
//
|
140
|
+
// In the case of a plain dyna symbol, node.quote will be either :" or :'
|
141
|
+
// For %s dyna symbols, node.quote will be %s[, %s(, %s{, or %s<
|
88
142
|
function printDynaSymbol(path, opts, print) {
|
89
|
-
const
|
143
|
+
const node = path.getValue();
|
144
|
+
|
145
|
+
if (shouldPrintPercentSDynaSymbol(node)) {
|
146
|
+
return printPercentSDynaSymbol(path, opts, print);
|
147
|
+
}
|
148
|
+
|
149
|
+
const parts = [];
|
150
|
+
let quote;
|
151
|
+
|
152
|
+
if (isQuoteLocked(node)) {
|
153
|
+
if (node.quote.startsWith("%")) {
|
154
|
+
quote = opts.rubySingleQuote ? "'" : '"';
|
155
|
+
} else {
|
156
|
+
quote = node.quote.slice(1);
|
157
|
+
}
|
158
|
+
} else {
|
159
|
+
quote = opts.rubySingleQuote && isSingleQuotable(node) ? "'" : '"';
|
160
|
+
}
|
161
|
+
|
162
|
+
parts.push(quote);
|
163
|
+
path.each((childPath) => {
|
164
|
+
const child = childPath.getValue();
|
165
|
+
|
166
|
+
if (child.type !== "@tstring_content") {
|
167
|
+
parts.push(print(childPath));
|
168
|
+
} else {
|
169
|
+
parts.push(
|
170
|
+
join(literalline, normalizeQuotes(child.body, quote).split("\n"))
|
171
|
+
);
|
172
|
+
}
|
173
|
+
}, "body");
|
174
|
+
|
175
|
+
parts.push(quote);
|
176
|
+
|
177
|
+
// If we're inside of an assoc_new node as the key, then it will handle
|
178
|
+
// printing the : on its own since it could change sides.
|
179
|
+
const parentNode = path.getParentNode();
|
180
|
+
if (parentNode.type !== "assoc_new" || parentNode.body[0] !== node) {
|
181
|
+
parts.unshift(":");
|
182
|
+
}
|
90
183
|
|
91
|
-
return concat(
|
184
|
+
return concat(parts);
|
92
185
|
}
|
93
186
|
|
94
187
|
function printStringConcat(path, opts, print) {
|
data/src/ruby/parser.js
CHANGED
@@ -4,16 +4,14 @@ const parseSync = require("../parser/parseSync");
|
|
4
4
|
// to prettier a JavaScript object that is the equivalent AST that represents
|
5
5
|
// the code stored in that string. We accomplish this by spawning a new Ruby
|
6
6
|
// process of parser.rb and reading JSON off STDOUT.
|
7
|
-
function parse(text, _parsers,
|
8
|
-
return parseSync("ruby", text);
|
7
|
+
function parse(text, _parsers, opts) {
|
8
|
+
return parseSync("ruby", text, opts);
|
9
9
|
}
|
10
10
|
|
11
|
-
const pragmaPattern = /#\s*@(prettier|format)/;
|
12
|
-
|
13
11
|
// This function handles checking whether or not the source string has the
|
14
12
|
// pragma for prettier. This is an optional workflow for incremental adoption.
|
15
13
|
function hasPragma(text) {
|
16
|
-
return
|
14
|
+
return /^\s*#[^\S\n]*@(format|prettier)\s*(\n|$)/.test(text);
|
17
15
|
}
|
18
16
|
|
19
17
|
// This function is critical for comments and cursor support, and is responsible
|
data/src/ruby/parser.rb
CHANGED
@@ -13,8 +13,7 @@ if (RUBY_MAJOR < 2) || ((RUBY_MAJOR == 2) && (RUBY_MINOR < 5))
|
|
13
13
|
exit 1
|
14
14
|
end
|
15
15
|
|
16
|
-
require '
|
17
|
-
require 'json'
|
16
|
+
require 'json' unless defined?(JSON)
|
18
17
|
require 'ripper'
|
19
18
|
|
20
19
|
module Prettier
|
@@ -54,6 +53,35 @@ class Prettier::Parser < Ripper
|
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
56
|
+
# This is a small wrapper around the value of a node for those specific events
|
57
|
+
# that need extra handling. (For example: statement, body statement, and
|
58
|
+
# rescue nodes which all need extra information to determine their character
|
59
|
+
# boundaries.)
|
60
|
+
class Node
|
61
|
+
attr_reader :parser, :value
|
62
|
+
|
63
|
+
def initialize(parser, value)
|
64
|
+
@parser = parser
|
65
|
+
@value = value
|
66
|
+
end
|
67
|
+
|
68
|
+
def [](key)
|
69
|
+
value[key]
|
70
|
+
end
|
71
|
+
|
72
|
+
def dig(*keys)
|
73
|
+
value.dig(*keys)
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_json(*opts)
|
77
|
+
value.to_json(*opts)
|
78
|
+
end
|
79
|
+
|
80
|
+
def pretty_print(q)
|
81
|
+
q.pp_hash(self)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
57
85
|
attr_reader :source, :lines, :scanner_events
|
58
86
|
|
59
87
|
# This is an attr_accessor so Stmts objects can grab comments out of this
|
@@ -565,6 +593,12 @@ class Prettier::Parser < Ripper
|
|
565
593
|
# binary is a parser event that represents a binary operation between two
|
566
594
|
# values.
|
567
595
|
def on_binary(left, oper, right)
|
596
|
+
# On most Ruby implementations, oper is a Symbol that represents that
|
597
|
+
# operation being performed. For instance in the example `1 < 2`, the `oper`
|
598
|
+
# object would be `:<`. However, on JRuby, it's an `@op` node, so here we're
|
599
|
+
# going to explicitly convert it into the same normalized form.
|
600
|
+
oper = scanner_events.delete(oper)[:body] unless oper.is_a?(Symbol)
|
601
|
+
|
568
602
|
{
|
569
603
|
type: :binary,
|
570
604
|
body: [left, oper, right],
|
@@ -611,19 +645,19 @@ class Prettier::Parser < Ripper
|
|
611
645
|
# bodystmt can't actually determine its bounds appropriately because it
|
612
646
|
# doesn't necessarily know where it started. So the parent node needs to
|
613
647
|
# report back down into this one where it goes.
|
614
|
-
class BodyStmt <
|
648
|
+
class BodyStmt < Node
|
615
649
|
def bind(sc, ec)
|
616
|
-
merge!(sc: sc, ec: ec)
|
617
|
-
parts =
|
650
|
+
value.merge!(sc: sc, ec: ec)
|
651
|
+
parts = value[:body]
|
618
652
|
|
619
653
|
# Here we're going to determine the bounds for the stmts
|
620
654
|
consequent = parts[1..-1].compact.first
|
621
|
-
|
655
|
+
value[:body][0].bind(sc, consequent ? consequent[:sc] : ec)
|
622
656
|
|
623
657
|
# Next we're going to determine the rescue clause if there is one
|
624
658
|
if parts[1]
|
625
659
|
consequent = parts[2..-1].compact.first
|
626
|
-
|
660
|
+
value[:body][1].bind_end(consequent ? consequent[:sc] : ec)
|
627
661
|
end
|
628
662
|
end
|
629
663
|
end
|
@@ -632,6 +666,7 @@ class Prettier::Parser < Ripper
|
|
632
666
|
# of clauses within the body of a method or block.
|
633
667
|
def on_bodystmt(stmts, rescued, ensured, elsed)
|
634
668
|
BodyStmt.new(
|
669
|
+
self,
|
635
670
|
type: :bodystmt,
|
636
671
|
body: [stmts, rescued, ensured, elsed],
|
637
672
|
sl: lineno,
|
@@ -656,7 +691,7 @@ class Prettier::Parser < Ripper
|
|
656
691
|
body: [block_var, stmts],
|
657
692
|
sl: beging[:sl],
|
658
693
|
sc: beging[:sc],
|
659
|
-
el: ending[:el],
|
694
|
+
el: [ending[:el], stmts[:el]].max,
|
660
695
|
ec: ending[:ec]
|
661
696
|
}
|
662
697
|
end
|
@@ -709,7 +744,7 @@ class Prettier::Parser < Ripper
|
|
709
744
|
body: [receiver, oper, sending],
|
710
745
|
sl: receiver[:sl],
|
711
746
|
sc: receiver[:sc],
|
712
|
-
el: ending[:el],
|
747
|
+
el: [ending[:el], receiver[:el]].max,
|
713
748
|
ec: ending[:ec]
|
714
749
|
}
|
715
750
|
end
|
@@ -1057,7 +1092,7 @@ class Prettier::Parser < Ripper
|
|
1057
1092
|
|
1058
1093
|
beging.merge(
|
1059
1094
|
type: :dyna_symbol,
|
1060
|
-
quote: beging[:body]
|
1095
|
+
quote: beging[:body],
|
1061
1096
|
body: string[:body],
|
1062
1097
|
el: ending[:el],
|
1063
1098
|
ec: ending[:ec]
|
@@ -1723,6 +1758,28 @@ class Prettier::Parser < Ripper
|
|
1723
1758
|
)
|
1724
1759
|
end
|
1725
1760
|
|
1761
|
+
# A special parser error so that we can get nice syntax displays on the error
|
1762
|
+
# message when prettier prints out the results.
|
1763
|
+
class ParserError < StandardError
|
1764
|
+
attr_reader :lineno, :column
|
1765
|
+
|
1766
|
+
def initialize(error, lineno, column)
|
1767
|
+
super(error)
|
1768
|
+
@lineno = lineno
|
1769
|
+
@column = column
|
1770
|
+
end
|
1771
|
+
end
|
1772
|
+
|
1773
|
+
# If we encounter a parse error, just immediately bail out so that our runner
|
1774
|
+
# can catch it.
|
1775
|
+
def on_parse_error(error, *)
|
1776
|
+
raise ParserError.new(error, lineno, column)
|
1777
|
+
end
|
1778
|
+
alias on_alias_error on_parse_error
|
1779
|
+
alias on_assign_error on_parse_error
|
1780
|
+
alias on_class_name_error on_parse_error
|
1781
|
+
alias on_param_error on_parse_error
|
1782
|
+
|
1726
1783
|
# The program node is the very top of the AST. Here we'll attach all of
|
1727
1784
|
# the comments that we've gathered up over the course of parsing the
|
1728
1785
|
# source string. We'll also attach on the __END__ content if there was
|
@@ -1817,12 +1874,12 @@ class Prettier::Parser < Ripper
|
|
1817
1874
|
# doesn't really have all of the information that it needs in order to
|
1818
1875
|
# determine its ending. Therefore it relies on its parent bodystmt node to
|
1819
1876
|
# report its ending to it.
|
1820
|
-
class Rescue <
|
1877
|
+
class Rescue < Node
|
1821
1878
|
def bind_end(ec)
|
1822
|
-
merge!(ec: ec)
|
1879
|
+
value.merge!(ec: ec)
|
1823
1880
|
|
1824
|
-
stmts =
|
1825
|
-
consequent =
|
1881
|
+
stmts = value[:body][1]
|
1882
|
+
consequent = value[:body][2]
|
1826
1883
|
|
1827
1884
|
if consequent
|
1828
1885
|
consequent.bind_end(ec)
|
@@ -1858,6 +1915,7 @@ class Prettier::Parser < Ripper
|
|
1858
1915
|
end
|
1859
1916
|
|
1860
1917
|
Rescue.new(
|
1918
|
+
self,
|
1861
1919
|
beging.merge!(
|
1862
1920
|
type: :rescue,
|
1863
1921
|
body: [rescue_ex, stmts, consequent],
|
@@ -1958,36 +2016,29 @@ class Prettier::Parser < Ripper
|
|
1958
2016
|
# stmts nodes will report back down the location information. We then
|
1959
2017
|
# propagate that onto void_stmt nodes inside the stmts in order to make sure
|
1960
2018
|
# all comments get printed appropriately.
|
1961
|
-
class Stmts <
|
1962
|
-
attr_reader :parser
|
1963
|
-
|
1964
|
-
def initialize(parser, values)
|
1965
|
-
@parser = parser
|
1966
|
-
__setobj__(values)
|
1967
|
-
end
|
1968
|
-
|
2019
|
+
class Stmts < Node
|
1969
2020
|
def bind(sc, ec)
|
1970
|
-
merge!(sc: sc, ec: ec)
|
2021
|
+
value.merge!(sc: sc, ec: ec)
|
1971
2022
|
|
1972
|
-
if
|
1973
|
-
|
2023
|
+
if value[:body][0][:type] == :void_stmt
|
2024
|
+
value[:body][0].merge!(sc: sc, ec: sc)
|
1974
2025
|
end
|
1975
2026
|
|
1976
2027
|
attach_comments(sc, ec)
|
1977
2028
|
end
|
1978
2029
|
|
1979
2030
|
def bind_end(ec)
|
1980
|
-
merge!(ec: ec)
|
2031
|
+
value.merge!(ec: ec)
|
1981
2032
|
end
|
1982
2033
|
|
1983
2034
|
def <<(statement)
|
1984
|
-
if
|
1985
|
-
merge!(statement.slice(:el, :ec))
|
2035
|
+
if value[:body].any?
|
2036
|
+
value.merge!(statement.slice(:el, :ec))
|
1986
2037
|
else
|
1987
|
-
merge!(statement.slice(:sl, :el, :sc, :ec))
|
2038
|
+
value.merge!(statement.slice(:sl, :el, :sc, :ec))
|
1988
2039
|
end
|
1989
2040
|
|
1990
|
-
|
2041
|
+
value[:body] << statement
|
1991
2042
|
self
|
1992
2043
|
end
|
1993
2044
|
|
@@ -2004,7 +2055,7 @@ class Prettier::Parser < Ripper
|
|
2004
2055
|
return if attachable.empty?
|
2005
2056
|
|
2006
2057
|
parser.comments -= attachable
|
2007
|
-
|
2058
|
+
value[:body] = (value[:body] + attachable).sort_by! { |node| node[:sc] }
|
2008
2059
|
end
|
2009
2060
|
end
|
2010
2061
|
|