prettier 0.21.0 → 1.0.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 +112 -7
- data/CONTRIBUTING.md +4 -4
- data/README.md +18 -14
- data/package.json +9 -6
- data/src/embed.js +27 -8
- data/src/nodes.js +5 -2
- data/src/nodes/alias.js +29 -31
- data/src/nodes/aref.js +26 -26
- data/src/nodes/args.js +55 -47
- data/src/nodes/arrays.js +132 -106
- data/src/nodes/assign.js +32 -32
- data/src/nodes/blocks.js +8 -3
- data/src/nodes/calls.js +163 -60
- data/src/nodes/case.js +11 -7
- data/src/nodes/class.js +74 -0
- data/src/nodes/commands.js +36 -31
- data/src/nodes/conditionals.js +44 -30
- data/src/nodes/constants.js +39 -21
- data/src/nodes/flow.js +11 -1
- data/src/nodes/hashes.js +90 -109
- data/src/nodes/heredocs.js +34 -0
- data/src/nodes/hooks.js +21 -22
- data/src/nodes/ints.js +27 -20
- data/src/nodes/lambdas.js +14 -27
- data/src/nodes/loops.js +10 -5
- data/src/nodes/massign.js +87 -65
- data/src/nodes/methods.js +48 -73
- data/src/nodes/operators.js +70 -39
- data/src/nodes/params.js +26 -16
- data/src/nodes/patterns.js +108 -33
- data/src/nodes/regexp.js +45 -14
- data/src/nodes/rescue.js +72 -59
- data/src/nodes/statements.js +86 -44
- data/src/nodes/strings.js +95 -85
- data/src/nodes/super.js +35 -0
- data/src/nodes/undef.js +42 -0
- data/src/parser.js +86 -0
- data/src/parser.rb +2400 -621
- data/src/printer.js +90 -0
- data/src/ruby.js +19 -41
- data/src/toProc.js +4 -4
- data/src/utils.js +24 -88
- data/src/utils/literalLineNoBreak.js +7 -0
- data/src/utils/printEmptyCollection.js +42 -0
- metadata +12 -49
- data/src/nodes/scopes.js +0 -61
- data/src/parse.js +0 -37
- data/src/print.js +0 -23
data/src/printer.js
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
const { concat, trim } = require("./prettier");
|
2
|
+
|
3
|
+
const embed = require("./embed");
|
4
|
+
const nodes = require("./nodes");
|
5
|
+
|
6
|
+
// This is the generic node print function, used to convert any node in the AST
|
7
|
+
// into its equivalent Doc representation.
|
8
|
+
function printNode(path, opts, print) {
|
9
|
+
const { type, body } = path.getValue();
|
10
|
+
|
11
|
+
if (type in nodes) {
|
12
|
+
return nodes[type](path, opts, print);
|
13
|
+
}
|
14
|
+
|
15
|
+
if (type[0] === "@") {
|
16
|
+
return body;
|
17
|
+
}
|
18
|
+
|
19
|
+
const ast = JSON.stringify(body, null, 2);
|
20
|
+
throw new Error(`Unsupported node encountered: ${type}\n${ast}`);
|
21
|
+
}
|
22
|
+
|
23
|
+
const noComments = [
|
24
|
+
"args",
|
25
|
+
"args_add_block",
|
26
|
+
"args_add_star",
|
27
|
+
"mlhs",
|
28
|
+
"mlhs_add_post",
|
29
|
+
"mlhs_add_star"
|
30
|
+
];
|
31
|
+
|
32
|
+
// Certain nodes are used more for organizational purposed than for actually
|
33
|
+
// displaying content, so we tell prettier that we don't want comments attached
|
34
|
+
// to them.
|
35
|
+
function canAttachComment(node) {
|
36
|
+
return !noComments.includes(node.type);
|
37
|
+
}
|
38
|
+
|
39
|
+
// This function tells prettier how to recurse down our AST so that it can find
|
40
|
+
// where it needs to attach the comments.
|
41
|
+
function getCommentChildNodes(node) {
|
42
|
+
switch (node.type) {
|
43
|
+
case "heredoc":
|
44
|
+
return [node.beging];
|
45
|
+
case "rescue":
|
46
|
+
return [].concat(node.body[0]).concat(node.body.slice(1));
|
47
|
+
case "aryptn":
|
48
|
+
return [node.body[0]]
|
49
|
+
.concat(node.body[1])
|
50
|
+
.concat(node.body[2])
|
51
|
+
.concat(node.body[3]);
|
52
|
+
case "hshptn": {
|
53
|
+
const pairs = node.body[1];
|
54
|
+
const values = pairs.reduce((left, right) => left.concat(right), []);
|
55
|
+
|
56
|
+
return [node.body[0]].concat(values).concat(node.body[2]);
|
57
|
+
}
|
58
|
+
default:
|
59
|
+
return node.body;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
// This is the generic print function for any comment in the AST. It handles
|
64
|
+
// both regular comments that begin with a # and embdoc comments, which are
|
65
|
+
// surrounded by =begin..=end.
|
66
|
+
function printComment(path, _opts) {
|
67
|
+
const comment = path.getValue();
|
68
|
+
|
69
|
+
if (comment.type === "@comment") {
|
70
|
+
return `#${comment.value}`;
|
71
|
+
}
|
72
|
+
|
73
|
+
return concat([trim, comment.value]);
|
74
|
+
}
|
75
|
+
|
76
|
+
// To be honest I'm not 100% sure this function is actually necessary, but it
|
77
|
+
// *feels* like a block comment equivalent in JavaScript so I'm going to leave
|
78
|
+
// it in place for now.
|
79
|
+
function isBlockComment(comment) {
|
80
|
+
return comment.type === "@embdoc";
|
81
|
+
}
|
82
|
+
|
83
|
+
module.exports = {
|
84
|
+
embed,
|
85
|
+
print: printNode,
|
86
|
+
canAttachComment,
|
87
|
+
getCommentChildNodes,
|
88
|
+
printComment,
|
89
|
+
isBlockComment
|
90
|
+
};
|
data/src/ruby.js
CHANGED
@@ -1,12 +1,5 @@
|
|
1
|
-
const
|
2
|
-
const
|
3
|
-
const print = require("./print");
|
4
|
-
|
5
|
-
const pragmaPattern = /#\s*@(prettier|format)/;
|
6
|
-
const hasPragma = (text) => pragmaPattern.test(text);
|
7
|
-
|
8
|
-
const locStart = (node) => node.char_start;
|
9
|
-
const locEnd = (node) => node.char_end;
|
1
|
+
const printer = require("./printer");
|
2
|
+
const parser = require("./parser");
|
10
3
|
|
11
4
|
/*
|
12
5
|
* metadata mostly pulled from linguist and rubocop:
|
@@ -77,59 +70,43 @@ module.exports = {
|
|
77
70
|
}
|
78
71
|
],
|
79
72
|
parsers: {
|
80
|
-
ruby:
|
81
|
-
parse,
|
82
|
-
astFormat: "ruby",
|
83
|
-
hasPragma,
|
84
|
-
locStart,
|
85
|
-
locEnd
|
86
|
-
}
|
73
|
+
ruby: parser
|
87
74
|
},
|
88
75
|
printers: {
|
89
|
-
ruby:
|
90
|
-
embed,
|
91
|
-
print
|
92
|
-
}
|
76
|
+
ruby: printer
|
93
77
|
},
|
94
78
|
options: {
|
95
|
-
|
96
|
-
type: "boolean",
|
97
|
-
category: "Global",
|
98
|
-
default: false,
|
99
|
-
description:
|
100
|
-
"Adds a trailing comma to array literals, hash literals, and method calls."
|
101
|
-
},
|
102
|
-
inlineConditionals: {
|
79
|
+
rubyArrayLiteral: {
|
103
80
|
type: "boolean",
|
104
|
-
category: "
|
81
|
+
category: "Ruby",
|
105
82
|
default: true,
|
106
83
|
description:
|
107
|
-
"When
|
84
|
+
"When possible, favor the use of string and symbol array literals."
|
108
85
|
},
|
109
|
-
|
86
|
+
rubyHashLabel: {
|
110
87
|
type: "boolean",
|
111
|
-
category: "
|
88
|
+
category: "Ruby",
|
112
89
|
default: true,
|
113
90
|
description:
|
114
|
-
"When
|
91
|
+
"When possible, uses the shortened hash key syntax, as opposed to hash rockets."
|
115
92
|
},
|
116
|
-
|
93
|
+
rubyModifier: {
|
117
94
|
type: "boolean",
|
118
|
-
category: "
|
95
|
+
category: "Ruby",
|
119
96
|
default: true,
|
120
97
|
description:
|
121
|
-
"When
|
98
|
+
"When it fits on one line, allows if, unless, while, and until statements to use the modifier form."
|
122
99
|
},
|
123
|
-
|
100
|
+
rubySingleQuote: {
|
124
101
|
type: "boolean",
|
125
|
-
category: "
|
102
|
+
category: "Ruby",
|
126
103
|
default: true,
|
127
104
|
description:
|
128
105
|
"When double quotes are not necessary for interpolation, prefers the use of single quotes for string literals."
|
129
106
|
},
|
130
|
-
|
107
|
+
rubyToProc: {
|
131
108
|
type: "boolean",
|
132
|
-
category: "
|
109
|
+
category: "Ruby",
|
133
110
|
default: false,
|
134
111
|
description:
|
135
112
|
"When possible, convert blocks to the more concise Symbol#to_proc syntax."
|
@@ -137,6 +114,7 @@ module.exports = {
|
|
137
114
|
},
|
138
115
|
defaultOptions: {
|
139
116
|
printWidth: 80,
|
140
|
-
tabWidth: 2
|
117
|
+
tabWidth: 2,
|
118
|
+
trailingComma: "none"
|
141
119
|
}
|
142
120
|
};
|
data/src/toProc.js
CHANGED
@@ -11,8 +11,8 @@ const isCall = (node) => ["::", "."].includes(node) || node.type === "@period";
|
|
11
11
|
// [1, 2, 3].map(&:to_s)
|
12
12
|
//
|
13
13
|
// This works with `do` blocks as well.
|
14
|
-
const toProc = (path,
|
15
|
-
if (!node
|
14
|
+
const toProc = (path, node) => {
|
15
|
+
if (!node) {
|
16
16
|
return null;
|
17
17
|
}
|
18
18
|
|
@@ -57,9 +57,9 @@ const toProc = (path, opts, node) => {
|
|
57
57
|
return null;
|
58
58
|
}
|
59
59
|
|
60
|
-
// Ensure that statement is a call
|
60
|
+
// Ensure that statement is a call and that it has no comments attached
|
61
61
|
const [statement] = statements.body;
|
62
|
-
if (statement.type !== "call") {
|
62
|
+
if (statement.type !== "call" || statement.comments) {
|
63
63
|
return null;
|
64
64
|
}
|
65
65
|
|
data/src/utils.js
CHANGED
@@ -1,19 +1,14 @@
|
|
1
|
-
const {
|
2
|
-
breakParent,
|
3
|
-
concat,
|
4
|
-
hardline,
|
5
|
-
lineSuffix,
|
6
|
-
literalline
|
7
|
-
} = require("./prettier");
|
1
|
+
const { concat } = require("./prettier");
|
8
2
|
const isEmptyStmts = require("./utils/isEmptyStmts");
|
9
|
-
|
10
|
-
const
|
3
|
+
const literalLineNoBreak = require("./utils/literalLineNoBreak");
|
4
|
+
const printEmptyCollection = require("./utils/printEmptyCollection");
|
11
5
|
|
12
6
|
// If the node is a type of assignment or if the node is a paren and nested
|
13
7
|
// inside that paren is a node that is a type of assignment.
|
14
8
|
const containsAssignment = (node) =>
|
15
|
-
|
16
|
-
(
|
9
|
+
node &&
|
10
|
+
(["assign", "massign", "opassign"].includes(node.type) ||
|
11
|
+
(Array.isArray(node.body) && node.body.some(containsAssignment)));
|
17
12
|
|
18
13
|
const docLength = (doc) => {
|
19
14
|
if (doc.length) {
|
@@ -35,6 +30,8 @@ const empty = () => "";
|
|
35
30
|
|
36
31
|
const first = (path, opts, print) => path.call(print, "body", 0);
|
37
32
|
|
33
|
+
const getTrailingComma = (opts) => ["all", "es5"].includes(opts.trailingComma);
|
34
|
+
|
38
35
|
const hasAncestor = (path, types) => {
|
39
36
|
let parent = 0;
|
40
37
|
let parentNode = path.getParentNode();
|
@@ -53,34 +50,6 @@ const hasAncestor = (path, types) => {
|
|
53
50
|
|
54
51
|
const literal = (value) => () => value;
|
55
52
|
|
56
|
-
const makeArgs = (path, opts, print, argsIndex) => {
|
57
|
-
let argNodes = path.getValue().body[argsIndex];
|
58
|
-
const argPattern = [print, "body", argsIndex, "body"];
|
59
|
-
|
60
|
-
if (argNodes.type === "args_add_block") {
|
61
|
-
[argNodes] = argNodes.body;
|
62
|
-
argPattern.push(0, "body");
|
63
|
-
}
|
64
|
-
|
65
|
-
const args = path.call(print, "body", argsIndex);
|
66
|
-
const heredocs = [];
|
67
|
-
|
68
|
-
argNodes.body.forEach((argNode, index) => {
|
69
|
-
if (argNode.type === "heredoc") {
|
70
|
-
const content = path.map.apply(
|
71
|
-
path,
|
72
|
-
argPattern.slice().concat([index, "body"])
|
73
|
-
);
|
74
|
-
heredocs.push(
|
75
|
-
concat([literalline].concat(content).concat([argNode.ending]))
|
76
|
-
);
|
77
|
-
args[index] = argNode.beging;
|
78
|
-
}
|
79
|
-
});
|
80
|
-
|
81
|
-
return { args, heredocs };
|
82
|
-
};
|
83
|
-
|
84
53
|
const makeCall = (path, opts, print) => {
|
85
54
|
const operation = path.getValue().body[1];
|
86
55
|
|
@@ -91,69 +60,36 @@ const makeCall = (path, opts, print) => {
|
|
91
60
|
return operation === "::" ? "." : path.call(print, "body", 1);
|
92
61
|
};
|
93
62
|
|
94
|
-
const
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
return current;
|
104
|
-
};
|
63
|
+
const noIndent = [
|
64
|
+
"array",
|
65
|
+
"hash",
|
66
|
+
"heredoc",
|
67
|
+
"if",
|
68
|
+
"method_add_block",
|
69
|
+
"xstring_literal"
|
70
|
+
];
|
105
71
|
|
106
72
|
const prefix = (value) => (path, opts, print) =>
|
107
73
|
concat([value, path.call(print, "body", 0)]);
|
108
74
|
|
109
|
-
const
|
110
|
-
let node = printed;
|
111
|
-
|
112
|
-
comments.forEach((comment) => {
|
113
|
-
if (comment.start < start) {
|
114
|
-
node = concat([
|
115
|
-
comment.break ? breakParent : "",
|
116
|
-
comment.body,
|
117
|
-
hardline,
|
118
|
-
node
|
119
|
-
]);
|
120
|
-
} else {
|
121
|
-
node = concat([
|
122
|
-
node,
|
123
|
-
comment.break ? breakParent : "",
|
124
|
-
lineSuffix(` ${comment.body}`)
|
125
|
-
]);
|
126
|
-
}
|
127
|
-
});
|
128
|
-
|
129
|
-
return node;
|
130
|
-
};
|
131
|
-
|
75
|
+
const skippable = ["array", "hash", "heredoc", "lambda", "regexp_literal"];
|
132
76
|
const skipAssignIndent = (node) =>
|
133
|
-
|
134
|
-
|
135
|
-
) ||
|
136
|
-
(node.type === "call" && skipAssignIndent(node.body[0])) ||
|
137
|
-
(node.type === "string_literal" && node.body[0].type === "heredoc");
|
138
|
-
|
139
|
-
const surround = (left, right) => (path, opts, print) =>
|
140
|
-
concat([left, path.call(print, "body", 0), right]);
|
77
|
+
skippable.includes(node.type) ||
|
78
|
+
(node.type === "call" && skipAssignIndent(node.body[0]));
|
141
79
|
|
142
80
|
module.exports = {
|
143
|
-
concatBody,
|
144
81
|
containsAssignment,
|
145
82
|
docLength,
|
146
83
|
empty,
|
147
84
|
first,
|
85
|
+
getTrailingComma,
|
148
86
|
hasAncestor,
|
149
87
|
isEmptyStmts,
|
150
88
|
literal,
|
151
|
-
|
89
|
+
literalLineNoBreak,
|
152
90
|
makeCall,
|
153
|
-
|
154
|
-
nodeDive,
|
91
|
+
noIndent,
|
155
92
|
prefix,
|
156
|
-
|
157
|
-
skipAssignIndent
|
158
|
-
surround
|
93
|
+
printEmptyCollection,
|
94
|
+
skipAssignIndent
|
159
95
|
};
|
@@ -0,0 +1,42 @@
|
|
1
|
+
const { concat, group, hardline, indent, join, line } = require("../prettier");
|
2
|
+
|
3
|
+
// Empty collections are array or hash literals that do not contain any
|
4
|
+
// contents. They can, however, have comments inside the body. You can solve
|
5
|
+
// this by having a child node inside the array that gets the comments attached
|
6
|
+
// to it, but that requires modifying the parser. Instead, we can just manually
|
7
|
+
// print out the non-leading comments here.
|
8
|
+
function printEmptyCollection(path, opts, startToken, endToken) {
|
9
|
+
const node = path.getValue();
|
10
|
+
|
11
|
+
// If there are no comments or only leading comments, then we can just print
|
12
|
+
// out the start and end token and be done, as there are no comments inside
|
13
|
+
// the body of this node.
|
14
|
+
if (!node.comments || !node.comments.some((comment) => !comment.leading)) {
|
15
|
+
return `${startToken}${endToken}`;
|
16
|
+
}
|
17
|
+
|
18
|
+
const comments = [];
|
19
|
+
|
20
|
+
// For each comment, go through its path and print it out manually.
|
21
|
+
const printComment = (commentPath) => {
|
22
|
+
const comment = commentPath.getValue();
|
23
|
+
|
24
|
+
if (!comment.leading) {
|
25
|
+
comment.printed = true;
|
26
|
+
comments.push(opts.printer.printComment(commentPath));
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
path.each(printComment, "comments");
|
31
|
+
|
32
|
+
return group(
|
33
|
+
concat([
|
34
|
+
startToken,
|
35
|
+
indent(concat([hardline, join(hardline, comments)])),
|
36
|
+
line,
|
37
|
+
endToken
|
38
|
+
])
|
39
|
+
);
|
40
|
+
}
|
41
|
+
|
42
|
+
module.exports = printEmptyCollection;
|
metadata
CHANGED
@@ -1,57 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prettier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Deisz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: minitest
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '5.13'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '5.13'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rake
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '13.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '13.0'
|
11
|
+
date: 2020-12-12 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
55
13
|
description:
|
56
14
|
email:
|
57
15
|
executables:
|
@@ -82,11 +40,13 @@ files:
|
|
82
40
|
- src/nodes/blocks.js
|
83
41
|
- src/nodes/calls.js
|
84
42
|
- src/nodes/case.js
|
43
|
+
- src/nodes/class.js
|
85
44
|
- src/nodes/commands.js
|
86
45
|
- src/nodes/conditionals.js
|
87
46
|
- src/nodes/constants.js
|
88
47
|
- src/nodes/flow.js
|
89
48
|
- src/nodes/hashes.js
|
49
|
+
- src/nodes/heredocs.js
|
90
50
|
- src/nodes/hooks.js
|
91
51
|
- src/nodes/ints.js
|
92
52
|
- src/nodes/lambdas.js
|
@@ -99,18 +59,21 @@ files:
|
|
99
59
|
- src/nodes/regexp.js
|
100
60
|
- src/nodes/rescue.js
|
101
61
|
- src/nodes/return.js
|
102
|
-
- src/nodes/scopes.js
|
103
62
|
- src/nodes/statements.js
|
104
63
|
- src/nodes/strings.js
|
105
|
-
- src/
|
64
|
+
- src/nodes/super.js
|
65
|
+
- src/nodes/undef.js
|
66
|
+
- src/parser.js
|
106
67
|
- src/parser.rb
|
107
68
|
- src/prettier.js
|
108
|
-
- src/
|
69
|
+
- src/printer.js
|
109
70
|
- src/ruby.js
|
110
71
|
- src/toProc.js
|
111
72
|
- src/utils.js
|
112
73
|
- src/utils/inlineEnsureParens.js
|
113
74
|
- src/utils/isEmptyStmts.js
|
75
|
+
- src/utils/literalLineNoBreak.js
|
76
|
+
- src/utils/printEmptyCollection.js
|
114
77
|
homepage: https://github.com/prettier/plugin-ruby#readme
|
115
78
|
licenses:
|
116
79
|
- MIT
|
@@ -130,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
93
|
- !ruby/object:Gem::Version
|
131
94
|
version: '0'
|
132
95
|
requirements: []
|
133
|
-
rubygems_version: 3.
|
96
|
+
rubygems_version: 3.1.4
|
134
97
|
signing_key:
|
135
98
|
specification_version: 4
|
136
99
|
summary: prettier plugin for the Ruby programming language
|