prettier 1.5.5 → 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 +17 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +31 -12
- data/node_modules/prettier/bin-prettier.js +13702 -11629
- data/node_modules/prettier/index.js +19198 -16572
- data/node_modules/prettier/parser-angular.js +61 -40
- data/node_modules/prettier/parser-babel.js +22 -1
- data/node_modules/prettier/parser-espree.js +22 -1
- data/node_modules/prettier/parser-flow.js +22 -1
- data/node_modules/prettier/parser-glimmer.js +1 -1
- data/node_modules/prettier/parser-graphql.js +1 -1
- data/node_modules/prettier/parser-html.js +82 -63
- data/node_modules/prettier/parser-markdown.js +24 -9
- data/node_modules/prettier/parser-meriyah.js +22 -1
- data/node_modules/prettier/parser-postcss.js +22 -1
- data/node_modules/prettier/parser-typescript.js +22 -1
- data/node_modules/prettier/parser-yaml.js +2 -2
- data/node_modules/prettier/third-party.js +1042 -833
- data/package.json +3 -3
- data/rubocop.yml +9 -0
- data/src/haml/parser.js +5 -4
- data/src/haml/printer.js +428 -18
- data/src/parser/parseSync.js +8 -6
- data/src/plugin.js +1 -1
- data/src/rbs/parser.js +1 -3
- data/src/rbs/printer.js +35 -7
- data/src/ruby/nodes/args.js +66 -22
- 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/params.js +2 -9
- data/src/ruby/nodes/strings.js +95 -2
- data/src/ruby/parser.js +1 -3
- data/src/ruby/parser.rb +52 -29
- data/src/ruby/printer.js +10 -1
- data/src/utils/inlineEnsureParens.js +1 -0
- data/src/utils/skipAssignIndent.js +8 -1
- metadata +3 -12
- 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 -232
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@prettier/plugin-ruby",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.6.0",
|
4
4
|
"description": "prettier plugin for the Ruby programming language",
|
5
5
|
"main": "src/plugin.js",
|
6
6
|
"scripts": {
|
@@ -24,8 +24,8 @@
|
|
24
24
|
"devDependencies": {
|
25
25
|
"eslint": "^7.22.0",
|
26
26
|
"eslint-config-prettier": "^8.0.0",
|
27
|
-
"husky": "^
|
28
|
-
"jest": "^
|
27
|
+
"husky": "^6.0.0",
|
28
|
+
"jest": "^27.0.1",
|
29
29
|
"pretty-quick": "^3.1.0"
|
30
30
|
},
|
31
31
|
"eslintConfig": {
|
data/rubocop.yml
CHANGED
@@ -4,6 +4,15 @@
|
|
4
4
|
Layout:
|
5
5
|
Enabled: false
|
6
6
|
|
7
|
+
# Re-enable Layout/LineLength because certain cops that most projects use
|
8
|
+
# (e.g. Style/IfUnlessModifier) require Layout/LineLength to be enabled.
|
9
|
+
# By leaving it disabled, those rules will mis-fire.
|
10
|
+
#
|
11
|
+
# Users can always override these defaults in their own rubocop.yml files.
|
12
|
+
# https://github.com/prettier/plugin-ruby/issues/825
|
13
|
+
Layout/LineLength:
|
14
|
+
Enabled: true
|
15
|
+
|
7
16
|
# Disabling all of the following options because they could conflict with a
|
8
17
|
# prettier configuration setting.
|
9
18
|
|
data/src/haml/parser.js
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
const parseSync = require("../parser/parseSync");
|
2
2
|
|
3
|
-
|
3
|
+
function parse(text, _parsers, opts) {
|
4
4
|
return parseSync("haml", text, opts);
|
5
|
-
}
|
5
|
+
}
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
function hasPragma(text) {
|
8
|
+
return /^\s*-#\s*@(prettier|format)/.test(text);
|
9
|
+
}
|
9
10
|
|
10
11
|
// These functions are just placeholders until we can actually perform this
|
11
12
|
// properly. The functions are necessary otherwise the format with cursor
|
data/src/haml/printer.js
CHANGED
@@ -1,28 +1,438 @@
|
|
1
|
+
const {
|
2
|
+
align,
|
3
|
+
concat,
|
4
|
+
fill,
|
5
|
+
group,
|
6
|
+
hardline,
|
7
|
+
ifBreak,
|
8
|
+
indent,
|
9
|
+
join,
|
10
|
+
line,
|
11
|
+
softline
|
12
|
+
} = require("../prettier");
|
1
13
|
const embed = require("./embed");
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
silent_script: require("./nodes/silentScript"),
|
11
|
-
tag: require("./nodes/tag")
|
14
|
+
|
15
|
+
const docTypes = {
|
16
|
+
basic: "Basic",
|
17
|
+
frameset: "Frameset",
|
18
|
+
mobile: "Mobile",
|
19
|
+
rdfa: "RDFa",
|
20
|
+
strict: "Strict",
|
21
|
+
xml: "XML"
|
12
22
|
};
|
13
23
|
|
14
|
-
const
|
15
|
-
|
24
|
+
const docVersions = ["1.1", "5"];
|
25
|
+
|
26
|
+
// Prints out a hash key according to the configured prettier options.
|
27
|
+
function printHashKey(key, opts) {
|
28
|
+
let quoted = key;
|
29
|
+
const joiner = opts.rubyHashLabel ? ":" : " =>";
|
16
30
|
|
17
|
-
|
18
|
-
|
19
|
-
|
31
|
+
if (key.includes(":") || key.includes("-")) {
|
32
|
+
const quote = opts.rubySingleQuote ? "'" : '"';
|
33
|
+
quoted = `${quote}${key}${quote}`;
|
20
34
|
}
|
21
35
|
|
22
|
-
return
|
23
|
-
}
|
36
|
+
return `${opts.rubyHashLabel ? "" : ":"}${quoted}${joiner}`;
|
37
|
+
}
|
38
|
+
|
39
|
+
// Prints out the value inside of a hash key-value pair according to the
|
40
|
+
// configured prettier options.
|
41
|
+
function printHashValue(value, opts) {
|
42
|
+
if (typeof value !== "string") {
|
43
|
+
return value.toString();
|
44
|
+
}
|
45
|
+
|
46
|
+
// This is a very special syntax created by the parser to let us know that
|
47
|
+
// this should be printed literally instead of as a string.
|
48
|
+
if (value.startsWith("&")) {
|
49
|
+
return value.slice(1);
|
50
|
+
}
|
51
|
+
|
52
|
+
const quote = opts.rubySingleQuote && !value.includes("#{") ? "'" : '"';
|
53
|
+
return `${quote}${value}${quote}`;
|
54
|
+
}
|
55
|
+
|
56
|
+
// This will print an attributes object to a Doc node. It handles nesting on
|
57
|
+
// multiple levels and will print out according to whether or not the version of
|
58
|
+
// HAML being used supports multi-line attributes.
|
59
|
+
function printAttributes(object, opts, level = 0) {
|
60
|
+
if (typeof object !== "object") {
|
61
|
+
return printHashValue(object, opts);
|
62
|
+
}
|
63
|
+
|
64
|
+
const boundary = level === 0 ? softline : line;
|
65
|
+
const parts = Object.keys(object).map((key) =>
|
66
|
+
concat([
|
67
|
+
printHashKey(key, opts),
|
68
|
+
" ",
|
69
|
+
printAttributes(object[key], opts, level + 1)
|
70
|
+
])
|
71
|
+
);
|
72
|
+
|
73
|
+
// If we have support for multi-line attributes laid out like a regular hash,
|
74
|
+
// then we print them that way here.
|
75
|
+
if (opts.supportsMultiline) {
|
76
|
+
return group(
|
77
|
+
concat([
|
78
|
+
"{",
|
79
|
+
indent(group(concat([boundary, join(concat([",", line]), parts)]))),
|
80
|
+
boundary,
|
81
|
+
"}"
|
82
|
+
])
|
83
|
+
);
|
84
|
+
}
|
85
|
+
|
86
|
+
// Otherwise, if we only have one attribute, then just print it inline
|
87
|
+
// regardless of how long it is.
|
88
|
+
if (parts.length === 0) {
|
89
|
+
return group(concat(["{", parts[0], "}"]));
|
90
|
+
}
|
91
|
+
|
92
|
+
// Otherwise, depending on how long the line is it will split the content into
|
93
|
+
// multi-line attributes that old Haml understands.
|
94
|
+
return group(
|
95
|
+
concat([
|
96
|
+
"{",
|
97
|
+
parts[0],
|
98
|
+
",",
|
99
|
+
align(
|
100
|
+
opts.headerLength + 1,
|
101
|
+
concat([line, join(concat([",", line]), parts.slice(1))])
|
102
|
+
),
|
103
|
+
"}"
|
104
|
+
])
|
105
|
+
);
|
106
|
+
}
|
107
|
+
|
108
|
+
// A utility function used in a silent script that is meant to determine if a
|
109
|
+
// child node is a continuation of a parent node (as in a when clause within a
|
110
|
+
// case statement or an else clause within an if).
|
111
|
+
function isContinuation(parentNode, childNode) {
|
112
|
+
if (childNode.type !== "silent_script") {
|
113
|
+
return false;
|
114
|
+
}
|
115
|
+
|
116
|
+
const parent = parentNode.value.keyword;
|
117
|
+
const child = childNode.value.keyword;
|
118
|
+
|
119
|
+
return (
|
120
|
+
(parent === "case" && ["when", "else"].includes(child)) ||
|
121
|
+
(["if", "unless"].includes(parent) && ["elsif", "else"].includes(child))
|
122
|
+
);
|
123
|
+
}
|
124
|
+
|
125
|
+
// This is our printer's main print function that will switch on the type of
|
126
|
+
// node and print it out by returning a Doc tree.
|
127
|
+
function printNode(path, opts, print) {
|
128
|
+
const node = path.getValue();
|
129
|
+
const { value } = node;
|
130
|
+
|
131
|
+
switch (node.type) {
|
132
|
+
case "comment":
|
133
|
+
return printComment();
|
134
|
+
case "doctype":
|
135
|
+
return printDoctype();
|
136
|
+
case "filter":
|
137
|
+
return printFilter();
|
138
|
+
case "haml_comment":
|
139
|
+
return printHamlComment();
|
140
|
+
case "plain":
|
141
|
+
return printPlain();
|
142
|
+
case "root":
|
143
|
+
return printRoot();
|
144
|
+
case "script":
|
145
|
+
return printScript();
|
146
|
+
case "silent_script":
|
147
|
+
return printSilentScript();
|
148
|
+
case "tag":
|
149
|
+
return printTag();
|
150
|
+
default:
|
151
|
+
throw new Error(`Unsupported node encountered: ${node.type}`);
|
152
|
+
}
|
153
|
+
|
154
|
+
// It's common to a couple of nodes to attach nested child nodes on the
|
155
|
+
// children property. This utility prints them out grouped together with their
|
156
|
+
// parent node docs.
|
157
|
+
function printWithChildren(docs) {
|
158
|
+
if (node.children.length === 0) {
|
159
|
+
return docs;
|
160
|
+
}
|
161
|
+
|
162
|
+
return group(
|
163
|
+
concat([
|
164
|
+
docs,
|
165
|
+
indent(concat([hardline, join(hardline, path.map(print, "children"))]))
|
166
|
+
])
|
167
|
+
);
|
168
|
+
}
|
169
|
+
|
170
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#html-comments-
|
171
|
+
function printComment() {
|
172
|
+
const parts = ["/"];
|
173
|
+
|
174
|
+
if (value.revealed) {
|
175
|
+
parts.push("!");
|
176
|
+
}
|
177
|
+
|
178
|
+
if (value.conditional) {
|
179
|
+
parts.push(value.conditional);
|
180
|
+
} else if (value.text) {
|
181
|
+
parts.push(" ", value.text);
|
182
|
+
}
|
183
|
+
|
184
|
+
return printWithChildren(group(concat(parts)));
|
185
|
+
}
|
186
|
+
|
187
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#doctype-
|
188
|
+
function printDoctype() {
|
189
|
+
const parts = ["!!!"];
|
190
|
+
|
191
|
+
if (value.type in docTypes) {
|
192
|
+
parts.push(docTypes[value.type]);
|
193
|
+
} else if (docVersions.includes(value.version)) {
|
194
|
+
parts.push(value.version);
|
195
|
+
} else {
|
196
|
+
parts.push(value.type);
|
197
|
+
}
|
198
|
+
|
199
|
+
if (value.encoding) {
|
200
|
+
parts.push(value.encoding);
|
201
|
+
}
|
202
|
+
|
203
|
+
return group(join(" ", parts));
|
204
|
+
}
|
205
|
+
|
206
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#filters
|
207
|
+
function printFilter() {
|
208
|
+
return group(
|
209
|
+
concat([
|
210
|
+
":",
|
211
|
+
value.name,
|
212
|
+
indent(
|
213
|
+
concat([hardline, join(hardline, value.text.trim().split("\n"))])
|
214
|
+
)
|
215
|
+
])
|
216
|
+
);
|
217
|
+
}
|
218
|
+
|
219
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#haml-comments--
|
220
|
+
function printHamlComment() {
|
221
|
+
const parts = ["-#"];
|
222
|
+
|
223
|
+
if (value.text) {
|
224
|
+
if (opts.originalText.split("\n")[node.line - 1].trim() === "-#") {
|
225
|
+
const lines = value.text.trim().split("\n");
|
226
|
+
|
227
|
+
parts.push(indent(concat([hardline, join(hardline, lines)])));
|
228
|
+
} else {
|
229
|
+
parts.push(" ", value.text.trim());
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
return concat(parts);
|
234
|
+
}
|
235
|
+
|
236
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#plain-text
|
237
|
+
function printPlain() {
|
238
|
+
return value.text;
|
239
|
+
}
|
240
|
+
|
241
|
+
// The root node in the AST that we build in the parser.
|
242
|
+
function printRoot() {
|
243
|
+
return concat([join(hardline, path.map(print, "children")), hardline]);
|
244
|
+
}
|
245
|
+
|
246
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#inserting_ruby
|
247
|
+
function printScript() {
|
248
|
+
const parts = [];
|
249
|
+
|
250
|
+
if (value.escape_html) {
|
251
|
+
parts.unshift("&");
|
252
|
+
}
|
253
|
+
|
254
|
+
if (value.preserve) {
|
255
|
+
parts.push("~");
|
256
|
+
} else if (!value.interpolate) {
|
257
|
+
parts.push("=");
|
258
|
+
}
|
259
|
+
|
260
|
+
if (value.escape_html && !value.preserve && value.interpolate) {
|
261
|
+
parts.push(" ", value.text.trim().slice(1, -1));
|
262
|
+
} else {
|
263
|
+
parts.push(" ", value.text.trim());
|
264
|
+
}
|
265
|
+
|
266
|
+
return printWithChildren(group(concat(parts)));
|
267
|
+
}
|
268
|
+
|
269
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#running-ruby--
|
270
|
+
function printSilentScript() {
|
271
|
+
const parts = [`- ${value.text.trim()}`];
|
272
|
+
|
273
|
+
if (node.children.length > 0) {
|
274
|
+
parts.push(
|
275
|
+
concat(
|
276
|
+
path.map((childPath) => {
|
277
|
+
const child = childPath.getValue();
|
278
|
+
const concated = concat([hardline, print(childPath)]);
|
279
|
+
|
280
|
+
return isContinuation(node, child) ? concated : indent(concated);
|
281
|
+
}, "children")
|
282
|
+
)
|
283
|
+
);
|
284
|
+
}
|
285
|
+
|
286
|
+
return group(concat(parts));
|
287
|
+
}
|
288
|
+
|
289
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#element-name-
|
290
|
+
function printTag() {
|
291
|
+
const { attributes, dynamic_attributes } = value;
|
292
|
+
const parts = [];
|
293
|
+
|
294
|
+
// If we have a tag that isn't a div, then we need to print out that name of
|
295
|
+
// that tag first. If it is a div, first we'll check if there are any other
|
296
|
+
// things that would force us to print out the div explicitly, and otherwise
|
297
|
+
// we'll leave it off.
|
298
|
+
if (value.name !== "div") {
|
299
|
+
parts.push(`%${value.name}`);
|
300
|
+
}
|
301
|
+
|
302
|
+
// If we have a class attribute, then we're going to print that here using
|
303
|
+
// the special class syntax.
|
304
|
+
if (attributes.class) {
|
305
|
+
parts.push(`.${attributes.class.replace(/ /g, ".")}`);
|
306
|
+
}
|
307
|
+
|
308
|
+
// If we have an id attribute, then we're going to print that here using the
|
309
|
+
// special id syntax.
|
310
|
+
if (attributes.id) {
|
311
|
+
parts.push(`#${attributes.id}`);
|
312
|
+
}
|
313
|
+
|
314
|
+
// If we're using dynamic attributes on this tag, then they come in as a
|
315
|
+
// string that looks like the output of Hash#inspect from Ruby. So here
|
316
|
+
// we're going to split it all up and print it out nicely.
|
317
|
+
if (dynamic_attributes.new) {
|
318
|
+
const pairs = dynamic_attributes.new
|
319
|
+
.slice(1, -2)
|
320
|
+
.split(",")
|
321
|
+
.map((pair) => join("=", pair.slice(1).split('" => ')));
|
322
|
+
|
323
|
+
parts.push(
|
324
|
+
group(
|
325
|
+
concat([
|
326
|
+
"(",
|
327
|
+
align(parts.join("").length + 1, fill(join(line, pairs).parts)),
|
328
|
+
")"
|
329
|
+
])
|
330
|
+
)
|
331
|
+
);
|
332
|
+
}
|
333
|
+
|
334
|
+
// If there are any static attributes that are not class or id (because we
|
335
|
+
// already took care of those), then we're going to print them out here.
|
336
|
+
const staticAttributes = Object.keys(attributes).filter(
|
337
|
+
(name) => !["class", "id"].includes(name)
|
338
|
+
);
|
339
|
+
|
340
|
+
if (staticAttributes.length > 0) {
|
341
|
+
const docs = staticAttributes.reduce((accum, key) => {
|
342
|
+
const doc = `${printHashKey(key, opts)} ${printHashValue(
|
343
|
+
attributes[key],
|
344
|
+
opts
|
345
|
+
)}`;
|
346
|
+
|
347
|
+
return accum.length === 0 ? [doc] : accum.concat(",", line, doc);
|
348
|
+
}, []);
|
349
|
+
|
350
|
+
parts.push(
|
351
|
+
group(concat(["{", align(parts.join("").length + 1, fill(docs)), "}"]))
|
352
|
+
);
|
353
|
+
}
|
354
|
+
|
355
|
+
// If there are dynamic attributes that don't use the newer syntax, then
|
356
|
+
// we're going to print them out here.
|
357
|
+
if (dynamic_attributes.old) {
|
358
|
+
if (parts.length === 0) {
|
359
|
+
parts.push("%div");
|
360
|
+
}
|
361
|
+
|
362
|
+
if (typeof dynamic_attributes.old === "string") {
|
363
|
+
parts.push(dynamic_attributes.old);
|
364
|
+
} else {
|
365
|
+
const attrOptions = {
|
366
|
+
// This is kind of a total hack in that I don't think you're really
|
367
|
+
// supposed to directly use `path.stack`, but it's the easiest way to
|
368
|
+
// get the root node without having to know how many levels deep we
|
369
|
+
// are.
|
370
|
+
supportsMultiline: path.stack[0].supports_multiline,
|
371
|
+
headerLength: parts.join("").length
|
372
|
+
};
|
373
|
+
|
374
|
+
parts.push(
|
375
|
+
printAttributes(
|
376
|
+
dynamic_attributes.old,
|
377
|
+
Object.assign({}, opts, attrOptions)
|
378
|
+
)
|
379
|
+
);
|
380
|
+
}
|
381
|
+
}
|
382
|
+
|
383
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#object-reference-
|
384
|
+
if (value.object_ref) {
|
385
|
+
if (parts.length === 0) {
|
386
|
+
parts.push("%div");
|
387
|
+
}
|
388
|
+
parts.push(value.object_ref);
|
389
|
+
}
|
390
|
+
|
391
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#whitespace-removal--and-
|
392
|
+
if (value.nuke_outer_whitespace) {
|
393
|
+
parts.push(">");
|
394
|
+
}
|
395
|
+
|
396
|
+
if (value.nuke_inner_whitespace) {
|
397
|
+
parts.push("<");
|
398
|
+
}
|
399
|
+
|
400
|
+
// https://haml.info/docs/yardoc/file.REFERENCE.html#empty-void-tags-
|
401
|
+
if (value.self_closing) {
|
402
|
+
parts.push("/");
|
403
|
+
}
|
404
|
+
|
405
|
+
if (value.value) {
|
406
|
+
const prefix = value.parse ? "= " : ifBreak("", " ");
|
407
|
+
|
408
|
+
return printWithChildren(
|
409
|
+
group(
|
410
|
+
concat([
|
411
|
+
group(concat(parts)),
|
412
|
+
indent(concat([softline, prefix, value.value]))
|
413
|
+
])
|
414
|
+
)
|
415
|
+
);
|
416
|
+
}
|
417
|
+
|
418
|
+
// In case none of the other if statements have matched and we're printing
|
419
|
+
// a div, we need to explicitly add it back into the array.
|
420
|
+
if (parts.length === 0 && value.name === "div") {
|
421
|
+
parts.push("%div");
|
422
|
+
}
|
423
|
+
|
424
|
+
return printWithChildren(group(concat(parts)));
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
// This function handles adding the format pragma to a source string. This is an
|
429
|
+
// optional workflow for incremental adoption.
|
430
|
+
function insertPragma(text) {
|
431
|
+
return `-# @format${text.startsWith("-#") ? "\n" : "\n\n"}${text}`;
|
432
|
+
}
|
24
433
|
|
25
434
|
module.exports = {
|
26
435
|
embed,
|
27
|
-
print:
|
436
|
+
print: printNode,
|
437
|
+
insertPragma
|
28
438
|
};
|