prettier 1.5.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|