prettier 0.18.0 → 0.20.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 +103 -2
- data/LICENSE +1 -1
- data/README.md +12 -0
- data/node_modules/prettier/bin-prettier.js +33712 -25689
- data/node_modules/prettier/index.js +32389 -24963
- data/node_modules/prettier/third-party.js +10733 -3849
- data/package.json +35 -7
- data/src/embed.js +71 -0
- data/src/haml.js +3 -3
- data/src/haml/embed.js +2 -2
- data/src/haml/nodes/tag.js +13 -7
- data/src/haml/parse.rb +5 -8
- data/src/nodes/alias.js +2 -2
- data/src/nodes/args.js +2 -2
- data/src/nodes/arrays.js +11 -7
- data/src/nodes/blocks.js +5 -5
- data/src/nodes/calls.js +45 -10
- data/src/nodes/case.js +1 -1
- data/src/nodes/commands.js +2 -2
- data/src/nodes/conditionals.js +9 -7
- data/src/nodes/hashes.js +2 -2
- data/src/nodes/hooks.js +1 -1
- data/src/nodes/lambdas.js +1 -1
- data/src/nodes/methods.js +2 -2
- data/src/nodes/operators.js +11 -3
- data/src/nodes/params.js +1 -1
- data/src/nodes/regexp.js +1 -1
- data/src/nodes/rescue.js +5 -1
- data/src/nodes/return.js +11 -1
- data/src/nodes/strings.js +5 -5
- data/src/parse.js +16 -0
- data/src/prettier.js +0 -1
- data/src/ripper.rb +3 -2
- data/src/ruby.js +15 -4
- data/src/toProc.js +30 -3
- data/src/utils.js +6 -6
- metadata +9 -8
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@prettier/plugin-ruby",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.20.0",
|
4
4
|
"description": "prettier plugin for the Ruby programming language",
|
5
5
|
"main": "src/ruby.js",
|
6
6
|
"scripts": {
|
@@ -22,17 +22,45 @@
|
|
22
22
|
"prettier": ">=1.10"
|
23
23
|
},
|
24
24
|
"devDependencies": {
|
25
|
-
"all-contributors-cli": "^6.
|
26
|
-
"eslint": "^
|
27
|
-
"eslint-config-
|
28
|
-
"
|
29
|
-
"
|
30
|
-
"
|
25
|
+
"all-contributors-cli": "^6.14.1",
|
26
|
+
"eslint": "^7.1.0",
|
27
|
+
"eslint-config-prettier": "^6.10.1",
|
28
|
+
"husky": "^4.2.5",
|
29
|
+
"jest": "^26.0.0",
|
30
|
+
"pretty-quick": "^3.0.0"
|
31
|
+
},
|
32
|
+
"eslintConfig": {
|
33
|
+
"extends": [
|
34
|
+
"eslint:recommended",
|
35
|
+
"prettier"
|
36
|
+
],
|
37
|
+
"env": {
|
38
|
+
"es6": true,
|
39
|
+
"jest": true,
|
40
|
+
"node": true
|
41
|
+
},
|
42
|
+
"rules": {
|
43
|
+
"no-unused-vars": [
|
44
|
+
"error",
|
45
|
+
{
|
46
|
+
"argsIgnorePattern": "^_",
|
47
|
+
"varsIgnorePattern": "^_"
|
48
|
+
}
|
49
|
+
]
|
50
|
+
}
|
31
51
|
},
|
32
52
|
"jest": {
|
33
53
|
"setupFilesAfterEnv": [
|
34
54
|
"./test/js/setupTests.js"
|
35
55
|
],
|
36
56
|
"testRegex": ".test.js$"
|
57
|
+
},
|
58
|
+
"husky": {
|
59
|
+
"hooks": {
|
60
|
+
"pre-commit": "pretty-quick --staged"
|
61
|
+
}
|
62
|
+
},
|
63
|
+
"prettier": {
|
64
|
+
"trailingComma": "none"
|
37
65
|
}
|
38
66
|
}
|
data/src/embed.js
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
const {
|
2
|
+
concat,
|
3
|
+
indent,
|
4
|
+
literalline,
|
5
|
+
mapDoc,
|
6
|
+
markAsRoot,
|
7
|
+
stripTrailingHardline
|
8
|
+
} = require("./prettier");
|
9
|
+
|
10
|
+
const parsers = {
|
11
|
+
css: "css",
|
12
|
+
javascript: "babel",
|
13
|
+
js: "babel",
|
14
|
+
less: "less",
|
15
|
+
markdown: "markdown",
|
16
|
+
ruby: "ruby",
|
17
|
+
scss: "scss"
|
18
|
+
};
|
19
|
+
|
20
|
+
const replaceNewlines = (doc) =>
|
21
|
+
mapDoc(doc, (currentDoc) =>
|
22
|
+
typeof currentDoc === "string" && currentDoc.includes("\n")
|
23
|
+
? concat(
|
24
|
+
currentDoc
|
25
|
+
.split(/(\n)/g)
|
26
|
+
.map((v, i) => (i % 2 === 0 ? v : literalline))
|
27
|
+
)
|
28
|
+
: currentDoc
|
29
|
+
);
|
30
|
+
|
31
|
+
const embed = (path, _print, textToDoc, _opts) => {
|
32
|
+
const node = path.getValue();
|
33
|
+
|
34
|
+
// Currently we only support embedded formatting on heredoc nodes
|
35
|
+
if (node.type !== "heredoc") {
|
36
|
+
return null;
|
37
|
+
}
|
38
|
+
|
39
|
+
// First, ensure that we don't have any interpolation
|
40
|
+
const { beging, body, ending } = node;
|
41
|
+
if (body.some((part) => part.type !== "@tstring_content")) {
|
42
|
+
return null;
|
43
|
+
}
|
44
|
+
|
45
|
+
// Next, find the parser associated with this heredoc (if there is one). For
|
46
|
+
// example, if you use <<~CSS, we'd hook it up to the css parser.
|
47
|
+
const parser = parsers[beging.slice(3).toLowerCase()];
|
48
|
+
if (!parser) {
|
49
|
+
return null;
|
50
|
+
}
|
51
|
+
|
52
|
+
// Get the content as if it were a source string, and then pass that content
|
53
|
+
// into the embedded parser. Get back the doc node.
|
54
|
+
const content = body.map((part) => part.body).join("");
|
55
|
+
const formatted = concat([
|
56
|
+
literalline,
|
57
|
+
replaceNewlines(stripTrailingHardline(textToDoc(content, { parser })))
|
58
|
+
]);
|
59
|
+
|
60
|
+
// If we're using a squiggly heredoc, then we can properly handle indentation
|
61
|
+
// ourselves.
|
62
|
+
if (beging[2] === "~") {
|
63
|
+
return concat([beging, indent(markAsRoot(formatted)), literalline, ending]);
|
64
|
+
}
|
65
|
+
|
66
|
+
// Otherwise, we need to just assume it's formatted correctly and return the
|
67
|
+
// content as it is.
|
68
|
+
return markAsRoot(concat([beging, formatted, literalline, ending]));
|
69
|
+
};
|
70
|
+
|
71
|
+
module.exports = embed;
|
data/src/haml.js
CHANGED
@@ -3,13 +3,13 @@ const parse = require("./haml/parse");
|
|
3
3
|
const print = require("./haml/print");
|
4
4
|
|
5
5
|
const pragmaPattern = /^\s*-#\s*@(prettier|format)/;
|
6
|
-
const hasPragma = text => pragmaPattern.test(text);
|
6
|
+
const hasPragma = (text) => pragmaPattern.test(text);
|
7
7
|
|
8
8
|
// These functions are just placeholders until we can actually perform this
|
9
9
|
// properly. The functions are necessary otherwise the format with cursor
|
10
10
|
// functions break.
|
11
|
-
const locStart = _node => 0;
|
12
|
-
const locEnd = _node => 0;
|
11
|
+
const locStart = (_node) => 0;
|
12
|
+
const locEnd = (_node) => 0;
|
13
13
|
|
14
14
|
module.exports = {
|
15
15
|
embed,
|
data/src/haml/embed.js
CHANGED
@@ -17,8 +17,8 @@ const parsers = {
|
|
17
17
|
scss: "scss"
|
18
18
|
};
|
19
19
|
|
20
|
-
const replaceNewlines = doc =>
|
21
|
-
mapDoc(doc, currentDoc =>
|
20
|
+
const replaceNewlines = (doc) =>
|
21
|
+
mapDoc(doc, (currentDoc) =>
|
22
22
|
typeof currentDoc === "string" && currentDoc.includes("\n")
|
23
23
|
? concat(
|
24
24
|
currentDoc
|
data/src/haml/nodes/tag.js
CHANGED
@@ -4,6 +4,7 @@ const {
|
|
4
4
|
fill,
|
5
5
|
group,
|
6
6
|
hardline,
|
7
|
+
ifBreak,
|
7
8
|
indent,
|
8
9
|
join,
|
9
10
|
line,
|
@@ -14,10 +15,10 @@ const getDynamicAttributes = (header, attributes) => {
|
|
14
15
|
const pairs = attributes
|
15
16
|
.slice(1, -2)
|
16
17
|
.split(",")
|
17
|
-
.map(pair => pair.slice(1).split('" => '));
|
18
|
+
.map((pair) => pair.slice(1).split('" => '));
|
18
19
|
const parts = [concat([pairs[0][0], "=", pairs[0][1]])];
|
19
20
|
|
20
|
-
pairs.slice(1).forEach(pair => {
|
21
|
+
pairs.slice(1).forEach((pair) => {
|
21
22
|
parts.push(line, concat([pair[0], "=", pair[1]]));
|
22
23
|
});
|
23
24
|
|
@@ -49,13 +50,13 @@ const getHashLabel = (key, value, opts) => {
|
|
49
50
|
|
50
51
|
const getStaticAttributes = (header, attributes, opts) => {
|
51
52
|
const keys = Object.keys(attributes).filter(
|
52
|
-
name => !["class", "id"].includes(name)
|
53
|
+
(name) => !["class", "id"].includes(name)
|
53
54
|
);
|
54
55
|
|
55
56
|
const getKeyValuePair = opts.preferHashLabels ? getHashLabel : getHashRocket;
|
56
57
|
const parts = [getKeyValuePair(keys[0], attributes[keys[0]], opts)];
|
57
58
|
|
58
|
-
keys.slice(1).forEach(key => {
|
59
|
+
keys.slice(1).forEach((key) => {
|
59
60
|
parts.push(",", line, getKeyValuePair(key, attributes[key], opts));
|
60
61
|
});
|
61
62
|
|
@@ -84,11 +85,16 @@ const getHeader = (value, opts) => {
|
|
84
85
|
);
|
85
86
|
}
|
86
87
|
|
87
|
-
if (
|
88
|
+
if (
|
89
|
+
Object.keys(attributes).some((name) => name !== "class" && name !== "id")
|
90
|
+
) {
|
88
91
|
parts.push(getStaticAttributes(parts.join("").length, attributes, opts));
|
89
92
|
}
|
90
93
|
|
91
94
|
if (value.dynamic_attributes.old) {
|
95
|
+
if (parts.length === 0) {
|
96
|
+
parts.push("%div");
|
97
|
+
}
|
92
98
|
parts.push(value.dynamic_attributes.old);
|
93
99
|
}
|
94
100
|
|
@@ -112,12 +118,12 @@ const getHeader = (value, opts) => {
|
|
112
118
|
}
|
113
119
|
|
114
120
|
if (value.value) {
|
115
|
-
const prefix = value.parse ? "=" : "";
|
121
|
+
const prefix = value.parse ? "= " : ifBreak("", " ");
|
116
122
|
|
117
123
|
return group(
|
118
124
|
concat([
|
119
125
|
group(concat(parts)),
|
120
|
-
indent(concat([softline,
|
126
|
+
indent(concat([softline, prefix, value.value]))
|
121
127
|
])
|
122
128
|
);
|
123
129
|
}
|
data/src/haml/parse.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'json'
|
4
|
-
|
5
3
|
require 'bundler/setup' if ENV['CI']
|
6
4
|
require 'haml'
|
7
5
|
|
@@ -48,18 +46,17 @@ class Haml::Parser::ParseNode
|
|
48
46
|
raise ArgumentError, "Unsupported type: #{type}"
|
49
47
|
end
|
50
48
|
end
|
51
|
-
|
52
|
-
def self.to_json(template)
|
53
|
-
parser = Haml::Parser.new({})
|
54
|
-
JSON.fast_generate(parser.call(template).as_json)
|
55
|
-
end
|
56
49
|
end
|
57
50
|
|
58
51
|
# If this is the main file we're executing, then most likely this is being
|
59
52
|
# executed from the haml.js spawn. In that case, read the ruby source from
|
60
53
|
# stdin and report back the AST over stdout.
|
61
|
-
|
62
54
|
if $0 == __FILE__
|
55
|
+
# Don't explicitly require JSON if there is already as JSON loaded, as this
|
56
|
+
# can lead to all kinds of trouble where one version of it was already
|
57
|
+
# "activated" by rubygems.
|
58
|
+
require 'json' unless defined?(JSON)
|
59
|
+
|
63
60
|
parser = Haml::Parser.new({})
|
64
61
|
template = $stdin.read
|
65
62
|
|
data/src/nodes/alias.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
const { concat, join } = require("../prettier");
|
2
2
|
|
3
|
-
const usingSymbols = path => {
|
4
|
-
const [left, right] = path.getValue().body.map(node => node.body[0].type);
|
3
|
+
const usingSymbols = (path) => {
|
4
|
+
const [left, right] = path.getValue().body.map((node) => node.body[0].type);
|
5
5
|
return left === "symbol" && right === "symbol";
|
6
6
|
};
|
7
7
|
|
data/src/nodes/args.js
CHANGED
@@ -62,7 +62,7 @@ module.exports = {
|
|
62
62
|
// method_add_block node, and if they are that that node has a block
|
63
63
|
// associated with it. If it does, we're going to attempt to transform it
|
64
64
|
// into the to_proc shorthand and add it to the list of arguments.
|
65
|
-
[1, 2, 3].find(parent => {
|
65
|
+
[1, 2, 3].find((parent) => {
|
66
66
|
const parentNode = path.getParentNode(parent);
|
67
67
|
blockNode =
|
68
68
|
parentNode &&
|
@@ -72,7 +72,7 @@ module.exports = {
|
|
72
72
|
return blockNode;
|
73
73
|
});
|
74
74
|
|
75
|
-
const proc = blockNode && toProc(blockNode);
|
75
|
+
const proc = blockNode && toProc(path, opts, blockNode);
|
76
76
|
|
77
77
|
// If we have a successful to_proc transformation, but we're part of an aref
|
78
78
|
// node, that means it's something to the effect of
|
data/src/nodes/arrays.js
CHANGED
@@ -9,19 +9,23 @@ const {
|
|
9
9
|
softline
|
10
10
|
} = require("../prettier");
|
11
11
|
|
12
|
-
const
|
12
|
+
const preserveArraySubstrings = [" ", "\\"];
|
13
|
+
|
14
|
+
const isStringArray = (args) =>
|
13
15
|
args.body.every(
|
14
|
-
arg =>
|
16
|
+
(arg) =>
|
15
17
|
arg.type === "string_literal" &&
|
16
18
|
arg.body[0].body.length === 1 &&
|
17
19
|
arg.body[0].body[0].type === "@tstring_content" &&
|
18
|
-
!
|
20
|
+
!preserveArraySubstrings.some((str) =>
|
21
|
+
arg.body[0].body[0].body.includes(str)
|
22
|
+
)
|
19
23
|
);
|
20
24
|
|
21
|
-
const isSymbolArray = args =>
|
22
|
-
args.body.every(arg => arg.type === "symbol_literal");
|
25
|
+
const isSymbolArray = (args) =>
|
26
|
+
args.body.every((arg) => arg.type === "symbol_literal");
|
23
27
|
|
24
|
-
const makeArray = start => (path, opts, print) =>
|
28
|
+
const makeArray = (start) => (path, opts, print) =>
|
25
29
|
[start].concat(path.map(print, "body"));
|
26
30
|
|
27
31
|
const getSpecialArrayParts = (path, print, args) =>
|
@@ -44,7 +48,7 @@ const printAref = (path, opts, print) =>
|
|
44
48
|
])
|
45
49
|
);
|
46
50
|
|
47
|
-
const printSpecialArray = parts =>
|
51
|
+
const printSpecialArray = (parts) =>
|
48
52
|
group(
|
49
53
|
concat([
|
50
54
|
parts[0],
|
data/src/nodes/blocks.js
CHANGED
@@ -10,7 +10,7 @@ const {
|
|
10
10
|
} = require("../prettier");
|
11
11
|
const { empty, hasAncestor } = require("../utils");
|
12
12
|
|
13
|
-
const printBlock = (path, opts, print) => {
|
13
|
+
const printBlock = (braces) => (path, opts, print) => {
|
14
14
|
const [variables, statements] = path.getValue().body;
|
15
15
|
const stmts =
|
16
16
|
statements.type === "stmts" ? statements.body : statements.body[0].body;
|
@@ -25,7 +25,7 @@ const printBlock = (path, opts, print) => {
|
|
25
25
|
// as opposed to the current node (because of the difference in operator
|
26
26
|
// precedence). Instead, we still use a multi-line format but switch to using
|
27
27
|
// braces instead.
|
28
|
-
const useBraces = hasAncestor(path, ["command", "command_call"]);
|
28
|
+
const useBraces = braces && hasAncestor(path, ["command", "command_call"]);
|
29
29
|
|
30
30
|
const doBlock = concat([
|
31
31
|
useBraces ? " {" : " do",
|
@@ -38,7 +38,7 @@ const printBlock = (path, opts, print) => {
|
|
38
38
|
// comment.
|
39
39
|
if (
|
40
40
|
stmts.length > 1 &&
|
41
|
-
stmts.filter(stmt => stmt.type !== "@comment").length === 1
|
41
|
+
stmts.filter((stmt) => stmt.type !== "@comment").length === 1
|
42
42
|
) {
|
43
43
|
return concat([breakParent, doBlock]);
|
44
44
|
}
|
@@ -74,7 +74,7 @@ module.exports = {
|
|
74
74
|
parts.push("| ");
|
75
75
|
return concat(parts);
|
76
76
|
},
|
77
|
-
brace_block: printBlock,
|
78
|
-
do_block: printBlock,
|
77
|
+
brace_block: printBlock(true),
|
78
|
+
do_block: printBlock(false),
|
79
79
|
excessed_comma: empty
|
80
80
|
};
|
data/src/nodes/calls.js
CHANGED
@@ -1,29 +1,64 @@
|
|
1
|
-
const { concat, group, indent, softline } = require("../prettier");
|
1
|
+
const { concat, group, indent, literalline, softline } = require("../prettier");
|
2
2
|
const toProc = require("../toProc");
|
3
3
|
const { concatBody, first, makeCall } = require("../utils");
|
4
4
|
|
5
5
|
const noIndent = ["array", "hash", "if", "method_add_block", "xstring_literal"];
|
6
6
|
|
7
|
+
const getHeredoc = (path, print, node) => {
|
8
|
+
if (node.type === "heredoc") {
|
9
|
+
const { beging, ending } = node;
|
10
|
+
return { beging, ending, content: ["body", 0, "body"] };
|
11
|
+
}
|
12
|
+
|
13
|
+
if (node.type === "string_literal" && node.body[0].type === "heredoc") {
|
14
|
+
const { beging, ending } = node.body[0];
|
15
|
+
return { beging, ending, content: ["body", 0, "body", 0, "body"] };
|
16
|
+
}
|
17
|
+
|
18
|
+
return null;
|
19
|
+
};
|
20
|
+
|
7
21
|
module.exports = {
|
8
22
|
call: (path, opts, print) => {
|
9
|
-
const
|
10
|
-
|
11
|
-
|
23
|
+
const [receiverNode, _operatorNode, messageNode] = path.getValue().body;
|
24
|
+
|
25
|
+
const printedReceiver = path.call(print, "body", 0);
|
26
|
+
const printedOperator = makeCall(path, opts, print);
|
12
27
|
|
13
28
|
// You can call lambdas with a special syntax that looks like func.(*args).
|
14
29
|
// In this case, "call" is returned for the 3rd child node.
|
15
|
-
|
16
|
-
|
30
|
+
const printedMessage =
|
31
|
+
messageNode === "call" ? messageNode : path.call(print, "body", 2);
|
32
|
+
|
33
|
+
// If we have a heredoc as a receiver, then we need to move the operator and
|
34
|
+
// the message up to start of the heredoc declaration, as in:
|
35
|
+
//
|
36
|
+
// <<~TEXT.strip
|
37
|
+
// content
|
38
|
+
// TEXT
|
39
|
+
const heredoc = getHeredoc(path, print, receiverNode);
|
40
|
+
if (heredoc) {
|
41
|
+
return concat([
|
42
|
+
heredoc.beging,
|
43
|
+
printedOperator,
|
44
|
+
printedMessage,
|
45
|
+
literalline,
|
46
|
+
concat(path.map.apply(path, [print].concat(heredoc.content))),
|
47
|
+
heredoc.ending
|
48
|
+
]);
|
17
49
|
}
|
18
50
|
|
19
51
|
// For certain left sides of the call nodes, we want to attach directly to
|
20
52
|
// the } or end.
|
21
|
-
if (noIndent.includes(
|
22
|
-
return concat([
|
53
|
+
if (noIndent.includes(receiverNode.type)) {
|
54
|
+
return concat([printedReceiver, printedOperator, printedMessage]);
|
23
55
|
}
|
24
56
|
|
25
57
|
return group(
|
26
|
-
concat([
|
58
|
+
concat([
|
59
|
+
printedReceiver,
|
60
|
+
group(indent(concat([softline, printedOperator, printedMessage])))
|
61
|
+
])
|
27
62
|
);
|
28
63
|
},
|
29
64
|
fcall: concatBody,
|
@@ -41,7 +76,7 @@ module.exports = {
|
|
41
76
|
},
|
42
77
|
method_add_block: (path, opts, print) => {
|
43
78
|
const [method, block] = path.getValue().body;
|
44
|
-
const proc = toProc(block);
|
79
|
+
const proc = toProc(path, opts, block);
|
45
80
|
|
46
81
|
if (proc && method.type === "call") {
|
47
82
|
return group(
|