prettier 1.5.2 → 1.6.1
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 +58 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +41 -12
- data/node_modules/prettier/bin-prettier.js +13848 -11589
- data/node_modules/prettier/doc.js +4961 -0
- data/node_modules/prettier/index.js +19466 -16783
- data/node_modules/prettier/package.json +23 -0
- 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 +1671 -864
- 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 +5 -0
- 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/nodes/args.js +111 -19
- data/src/ruby/nodes/calls.js +50 -3
- data/src/ruby/nodes/conditionals.js +47 -45
- data/src/ruby/nodes/hashes.js +5 -14
- data/src/ruby/nodes/params.js +2 -9
- data/src/ruby/nodes/strings.js +97 -2
- data/src/ruby/parser.js +3 -5
- data/src/ruby/parser.rb +76 -31
- data/src/ruby/printer.js +10 -1
- data/src/utils/inlineEnsureParens.js +1 -0
- data/src/utils/noIndent.js +0 -1
- data/src/utils/skipAssignIndent.js +8 -1
- metadata +16 -14
- 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/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");
|
@@ -32,12 +33,23 @@ function printCall(path, opts, print) {
|
|
32
33
|
|
33
34
|
// The right side of the call node, as in everything including the operator
|
34
35
|
// and beyond.
|
35
|
-
|
36
|
+
let rightSideDoc = concat([
|
36
37
|
receiverNode.comments ? hardline : softline,
|
37
38
|
operatorDoc,
|
38
39
|
messageDoc
|
39
40
|
]);
|
40
41
|
|
42
|
+
// This is very specialized behavior wherein we group .where.not calls
|
43
|
+
// together because it looks better. For more information, see
|
44
|
+
// https://github.com/prettier/plugin-ruby/issues/862.
|
45
|
+
if (
|
46
|
+
receiverNode.type === "call" &&
|
47
|
+
receiverNode.body[2].body === "where" &&
|
48
|
+
messageDoc === "not"
|
49
|
+
) {
|
50
|
+
rightSideDoc = concat([operatorDoc, messageDoc]);
|
51
|
+
}
|
52
|
+
|
41
53
|
// Get a reference to the parent node so we can check if we're inside a chain
|
42
54
|
const parentNode = path.getParentNode();
|
43
55
|
|
@@ -109,9 +121,38 @@ function printMethodAddArg(path, opts, print) {
|
|
109
121
|
parentNode.firstReceiverType = node.firstReceiverType;
|
110
122
|
}
|
111
123
|
|
124
|
+
// This is the threshold at which we will start to try to make a nicely
|
125
|
+
// indented call chain. For the most part, it's always 3.
|
126
|
+
let threshold = 3;
|
127
|
+
|
128
|
+
// Here, we have very specialized behavior where if we're within a sig block,
|
129
|
+
// then we're going to assume we're creating a Sorbet type signature. In that
|
130
|
+
// case, we really want the threshold to be lowered to 2 so that we create
|
131
|
+
// method chains off of any two method calls within the block. For more
|
132
|
+
// details, see
|
133
|
+
// https://github.com/prettier/plugin-ruby/issues/863.
|
134
|
+
let sigBlock = path.getParentNode(2);
|
135
|
+
if (sigBlock) {
|
136
|
+
// If we're at a do_block, then we want to go one more level up. This is
|
137
|
+
// because do_blocks have bodystmt nodes instead of just stmt nodes.
|
138
|
+
if (sigBlock.type === "do_block") {
|
139
|
+
sigBlock = path.getParentNode(3);
|
140
|
+
}
|
141
|
+
|
142
|
+
if (
|
143
|
+
sigBlock.type === "method_add_block" &&
|
144
|
+
sigBlock.body[1] &&
|
145
|
+
sigBlock.body[0].type === "method_add_arg" &&
|
146
|
+
sigBlock.body[0].body[0].type === "fcall" &&
|
147
|
+
sigBlock.body[0].body[0].body[0].body === "sig"
|
148
|
+
) {
|
149
|
+
threshold = 2;
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
112
153
|
// If we're at the top of a chain, then we're going to print out a nice
|
113
154
|
// multi-line layout if this doesn't break into multiple lines.
|
114
|
-
if (!chained.includes(parentNode.type) && (node.chain || 0) >=
|
155
|
+
if (!chained.includes(parentNode.type) && (node.chain || 0) >= threshold) {
|
115
156
|
// This is pretty specialized behavior. Basically if we're at the top of a
|
116
157
|
// chain but we've only had method calls without arguments and now we have
|
117
158
|
// arguments, then we're effectively trying to call a method with arguments
|
@@ -133,7 +174,13 @@ function printMethodAddArg(path, opts, print) {
|
|
133
174
|
);
|
134
175
|
}
|
135
176
|
|
136
|
-
|
177
|
+
// If there are already parentheses, then we can just use the doc that's
|
178
|
+
// already printed.
|
179
|
+
if (argNode.type == "arg_paren") {
|
180
|
+
return concat([methodDoc, argsDoc]);
|
181
|
+
}
|
182
|
+
|
183
|
+
return concat([methodDoc, " ", join(", ", argsDoc), " "]);
|
137
184
|
}
|
138
185
|
|
139
186
|
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/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,108 @@ 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 if (node.quote.startsWith(":")) {
|
156
|
+
quote = node.quote.slice(1);
|
157
|
+
} else {
|
158
|
+
quote = node.quote;
|
159
|
+
}
|
160
|
+
} else {
|
161
|
+
quote = opts.rubySingleQuote && isSingleQuotable(node) ? "'" : '"';
|
162
|
+
}
|
163
|
+
|
164
|
+
parts.push(quote);
|
165
|
+
path.each((childPath) => {
|
166
|
+
const child = childPath.getValue();
|
167
|
+
|
168
|
+
if (child.type !== "@tstring_content") {
|
169
|
+
parts.push(print(childPath));
|
170
|
+
} else {
|
171
|
+
parts.push(
|
172
|
+
join(literalline, normalizeQuotes(child.body, quote).split("\n"))
|
173
|
+
);
|
174
|
+
}
|
175
|
+
}, "body");
|
176
|
+
|
177
|
+
parts.push(quote);
|
178
|
+
|
179
|
+
// If we're inside of an assoc_new node as the key, then it will handle
|
180
|
+
// printing the : on its own since it could change sides.
|
181
|
+
const parentNode = path.getParentNode();
|
182
|
+
if (parentNode.type !== "assoc_new" || parentNode.body[0] !== node) {
|
183
|
+
parts.unshift(":");
|
184
|
+
}
|
90
185
|
|
91
|
-
return concat(
|
186
|
+
return concat(parts);
|
92
187
|
}
|
93
188
|
|
94
189
|
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
|
@@ -617,19 +645,19 @@ class Prettier::Parser < Ripper
|
|
617
645
|
# bodystmt can't actually determine its bounds appropriately because it
|
618
646
|
# doesn't necessarily know where it started. So the parent node needs to
|
619
647
|
# report back down into this one where it goes.
|
620
|
-
class BodyStmt <
|
648
|
+
class BodyStmt < Node
|
621
649
|
def bind(sc, ec)
|
622
|
-
merge!(sc: sc, ec: ec)
|
623
|
-
parts =
|
650
|
+
value.merge!(sc: sc, ec: ec)
|
651
|
+
parts = value[:body]
|
624
652
|
|
625
653
|
# Here we're going to determine the bounds for the stmts
|
626
654
|
consequent = parts[1..-1].compact.first
|
627
|
-
|
655
|
+
value[:body][0].bind(sc, consequent ? consequent[:sc] : ec)
|
628
656
|
|
629
657
|
# Next we're going to determine the rescue clause if there is one
|
630
658
|
if parts[1]
|
631
659
|
consequent = parts[2..-1].compact.first
|
632
|
-
|
660
|
+
value[:body][1].bind_end(consequent ? consequent[:sc] : ec)
|
633
661
|
end
|
634
662
|
end
|
635
663
|
end
|
@@ -638,6 +666,7 @@ class Prettier::Parser < Ripper
|
|
638
666
|
# of clauses within the body of a method or block.
|
639
667
|
def on_bodystmt(stmts, rescued, ensured, elsed)
|
640
668
|
BodyStmt.new(
|
669
|
+
self,
|
641
670
|
type: :bodystmt,
|
642
671
|
body: [stmts, rescued, ensured, elsed],
|
643
672
|
sl: lineno,
|
@@ -662,7 +691,7 @@ class Prettier::Parser < Ripper
|
|
662
691
|
body: [block_var, stmts],
|
663
692
|
sl: beging[:sl],
|
664
693
|
sc: beging[:sc],
|
665
|
-
el: ending[:el],
|
694
|
+
el: [ending[:el], stmts[:el]].max,
|
666
695
|
ec: ending[:ec]
|
667
696
|
}
|
668
697
|
end
|
@@ -715,7 +744,7 @@ class Prettier::Parser < Ripper
|
|
715
744
|
body: [receiver, oper, sending],
|
716
745
|
sl: receiver[:sl],
|
717
746
|
sc: receiver[:sc],
|
718
|
-
el: ending[:el],
|
747
|
+
el: [ending[:el], receiver[:el]].max,
|
719
748
|
ec: ending[:ec]
|
720
749
|
}
|
721
750
|
end
|
@@ -1063,7 +1092,7 @@ class Prettier::Parser < Ripper
|
|
1063
1092
|
|
1064
1093
|
beging.merge(
|
1065
1094
|
type: :dyna_symbol,
|
1066
|
-
quote: beging[:body]
|
1095
|
+
quote: beging[:body],
|
1067
1096
|
body: string[:body],
|
1068
1097
|
el: ending[:el],
|
1069
1098
|
ec: ending[:ec]
|
@@ -1729,6 +1758,28 @@ class Prettier::Parser < Ripper
|
|
1729
1758
|
)
|
1730
1759
|
end
|
1731
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
|
+
|
1732
1783
|
# The program node is the very top of the AST. Here we'll attach all of
|
1733
1784
|
# the comments that we've gathered up over the course of parsing the
|
1734
1785
|
# source string. We'll also attach on the __END__ content if there was
|
@@ -1823,12 +1874,12 @@ class Prettier::Parser < Ripper
|
|
1823
1874
|
# doesn't really have all of the information that it needs in order to
|
1824
1875
|
# determine its ending. Therefore it relies on its parent bodystmt node to
|
1825
1876
|
# report its ending to it.
|
1826
|
-
class Rescue <
|
1877
|
+
class Rescue < Node
|
1827
1878
|
def bind_end(ec)
|
1828
|
-
merge!(ec: ec)
|
1879
|
+
value.merge!(ec: ec)
|
1829
1880
|
|
1830
|
-
stmts =
|
1831
|
-
consequent =
|
1881
|
+
stmts = value[:body][1]
|
1882
|
+
consequent = value[:body][2]
|
1832
1883
|
|
1833
1884
|
if consequent
|
1834
1885
|
consequent.bind_end(ec)
|
@@ -1864,6 +1915,7 @@ class Prettier::Parser < Ripper
|
|
1864
1915
|
end
|
1865
1916
|
|
1866
1917
|
Rescue.new(
|
1918
|
+
self,
|
1867
1919
|
beging.merge!(
|
1868
1920
|
type: :rescue,
|
1869
1921
|
body: [rescue_ex, stmts, consequent],
|
@@ -1964,36 +2016,29 @@ class Prettier::Parser < Ripper
|
|
1964
2016
|
# stmts nodes will report back down the location information. We then
|
1965
2017
|
# propagate that onto void_stmt nodes inside the stmts in order to make sure
|
1966
2018
|
# all comments get printed appropriately.
|
1967
|
-
class Stmts <
|
1968
|
-
attr_reader :parser
|
1969
|
-
|
1970
|
-
def initialize(parser, values)
|
1971
|
-
@parser = parser
|
1972
|
-
__setobj__(values)
|
1973
|
-
end
|
1974
|
-
|
2019
|
+
class Stmts < Node
|
1975
2020
|
def bind(sc, ec)
|
1976
|
-
merge!(sc: sc, ec: ec)
|
2021
|
+
value.merge!(sc: sc, ec: ec)
|
1977
2022
|
|
1978
|
-
if
|
1979
|
-
|
2023
|
+
if value[:body][0][:type] == :void_stmt
|
2024
|
+
value[:body][0].merge!(sc: sc, ec: sc)
|
1980
2025
|
end
|
1981
2026
|
|
1982
2027
|
attach_comments(sc, ec)
|
1983
2028
|
end
|
1984
2029
|
|
1985
2030
|
def bind_end(ec)
|
1986
|
-
merge!(ec: ec)
|
2031
|
+
value.merge!(ec: ec)
|
1987
2032
|
end
|
1988
2033
|
|
1989
2034
|
def <<(statement)
|
1990
|
-
if
|
1991
|
-
merge!(statement.slice(:el, :ec))
|
2035
|
+
if value[:body].any?
|
2036
|
+
value.merge!(statement.slice(:el, :ec))
|
1992
2037
|
else
|
1993
|
-
merge!(statement.slice(:sl, :el, :sc, :ec))
|
2038
|
+
value.merge!(statement.slice(:sl, :el, :sc, :ec))
|
1994
2039
|
end
|
1995
2040
|
|
1996
|
-
|
2041
|
+
value[:body] << statement
|
1997
2042
|
self
|
1998
2043
|
end
|
1999
2044
|
|
@@ -2010,7 +2055,7 @@ class Prettier::Parser < Ripper
|
|
2010
2055
|
return if attachable.empty?
|
2011
2056
|
|
2012
2057
|
parser.comments -= attachable
|
2013
|
-
|
2058
|
+
value[:body] = (value[:body] + attachable).sort_by! { |node| node[:sc] }
|
2014
2059
|
end
|
2015
2060
|
end
|
2016
2061
|
|