prettier 0.21.0 → 0.22.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 +18 -1
- data/CONTRIBUTING.md +3 -3
- data/README.md +4 -0
- data/package.json +3 -3
- data/src/embed.js +20 -5
- 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 +56 -28
- data/src/nodes/arrays.js +142 -104
- data/src/nodes/assign.js +30 -30
- data/src/nodes/blocks.js +8 -3
- data/src/nodes/calls.js +108 -53
- data/src/nodes/class.js +74 -0
- data/src/nodes/commands.js +36 -31
- data/src/nodes/conditionals.js +42 -28
- data/src/nodes/constants.js +39 -21
- data/src/nodes/flow.js +11 -1
- data/src/nodes/hashes.js +60 -87
- data/src/nodes/heredocs.js +34 -0
- data/src/nodes/hooks.js +16 -19
- data/src/nodes/ints.js +33 -20
- data/src/nodes/lambdas.js +15 -12
- data/src/nodes/loops.js +6 -2
- data/src/nodes/massign.js +87 -65
- data/src/nodes/methods.js +46 -73
- data/src/nodes/operators.js +66 -46
- data/src/nodes/params.js +12 -14
- data/src/nodes/patterns.js +108 -33
- data/src/nodes/regexp.js +22 -13
- data/src/nodes/rescue.js +72 -59
- data/src/nodes/statements.js +23 -1
- data/src/nodes/strings.js +89 -80
- data/src/nodes/super.js +35 -0
- data/src/nodes/undef.js +42 -0
- data/src/parser.js +71 -0
- data/src/parser.rb +2269 -625
- data/src/printer.js +88 -0
- data/src/ruby.js +4 -20
- data/src/toProc.js +2 -2
- data/src/utils.js +10 -86
- data/src/utils/literalLineNoBreak.js +7 -0
- metadata +9 -5
- 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,88 @@
|
|
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 "rescue":
|
44
|
+
return node.body[0].concat(node.body.slice(1));
|
45
|
+
case "aryptn":
|
46
|
+
return [node.body[0]]
|
47
|
+
.concat(node.body[1])
|
48
|
+
.concat(node.body[2])
|
49
|
+
.concat(node.body[3]);
|
50
|
+
case "hshptn": {
|
51
|
+
const pairs = node.body[1];
|
52
|
+
const values = pairs.reduce((left, right) => left.concat(right), []);
|
53
|
+
|
54
|
+
return [node.body[0]].concat(values).concat(node.body[2]);
|
55
|
+
}
|
56
|
+
default:
|
57
|
+
return node.body;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
// This is the generic print function for any comment in the AST. It handles
|
62
|
+
// both regular comments that begin with a # and embdoc comments, which are
|
63
|
+
// surrounded by =begin..=end.
|
64
|
+
function printComment(path, _opts) {
|
65
|
+
const comment = path.getValue();
|
66
|
+
|
67
|
+
if (comment.type === "@comment") {
|
68
|
+
return `#${comment.value}`;
|
69
|
+
}
|
70
|
+
|
71
|
+
return concat([trim, comment.value]);
|
72
|
+
}
|
73
|
+
|
74
|
+
// To be honest I'm not 100% sure this function is actually necessary, but it
|
75
|
+
// *feels* like a block comment equivalent in JavaScript so I'm going to leave
|
76
|
+
// it in place for now.
|
77
|
+
function isBlockComment(comment) {
|
78
|
+
return comment.type === "@embdoc";
|
79
|
+
}
|
80
|
+
|
81
|
+
module.exports = {
|
82
|
+
embed,
|
83
|
+
print: printNode,
|
84
|
+
canAttachComment,
|
85
|
+
getCommentChildNodes,
|
86
|
+
printComment,
|
87
|
+
isBlockComment
|
88
|
+
};
|
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,19 +70,10 @@ 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
79
|
addTrailingCommas: {
|
data/src/toProc.js
CHANGED
@@ -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,15 @@
|
|
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");
|
3
|
+
const literalLineNoBreak = require("./utils/literalLineNoBreak");
|
9
4
|
|
10
5
|
const concatBody = (path, opts, print) => concat(path.map(print, "body"));
|
11
6
|
|
12
7
|
// If the node is a type of assignment or if the node is a paren and nested
|
13
8
|
// inside that paren is a node that is a type of assignment.
|
14
9
|
const containsAssignment = (node) =>
|
15
|
-
|
16
|
-
(
|
10
|
+
node &&
|
11
|
+
(["assign", "massign", "opassign"].includes(node.type) ||
|
12
|
+
(Array.isArray(node.body) && node.body.some(containsAssignment)));
|
17
13
|
|
18
14
|
const docLength = (doc) => {
|
19
15
|
if (doc.length) {
|
@@ -53,34 +49,6 @@ const hasAncestor = (path, types) => {
|
|
53
49
|
|
54
50
|
const literal = (value) => () => value;
|
55
51
|
|
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
52
|
const makeCall = (path, opts, print) => {
|
85
53
|
const operation = path.getValue().body[1];
|
86
54
|
|
@@ -91,53 +59,13 @@ const makeCall = (path, opts, print) => {
|
|
91
59
|
return operation === "::" ? "." : path.call(print, "body", 1);
|
92
60
|
};
|
93
61
|
|
94
|
-
const makeList = (path, opts, print) => path.map(print, "body");
|
95
|
-
|
96
|
-
const nodeDive = (node, steps) => {
|
97
|
-
let current = node;
|
98
|
-
|
99
|
-
steps.forEach((step) => {
|
100
|
-
current = current[step];
|
101
|
-
});
|
102
|
-
|
103
|
-
return current;
|
104
|
-
};
|
105
|
-
|
106
62
|
const prefix = (value) => (path, opts, print) =>
|
107
63
|
concat([value, path.call(print, "body", 0)]);
|
108
64
|
|
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
|
-
|
65
|
+
const skippable = ["array", "hash", "heredoc", "lambda", "regexp_literal"];
|
132
66
|
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]);
|
67
|
+
skippable.includes(node.type) ||
|
68
|
+
(node.type === "call" && skipAssignIndent(node.body[0]));
|
141
69
|
|
142
70
|
module.exports = {
|
143
71
|
concatBody,
|
@@ -148,12 +76,8 @@ module.exports = {
|
|
148
76
|
hasAncestor,
|
149
77
|
isEmptyStmts,
|
150
78
|
literal,
|
151
|
-
|
79
|
+
literalLineNoBreak,
|
152
80
|
makeCall,
|
153
|
-
makeList,
|
154
|
-
nodeDive,
|
155
81
|
prefix,
|
156
|
-
|
157
|
-
skipAssignIndent,
|
158
|
-
surround
|
82
|
+
skipAssignIndent
|
159
83
|
};
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prettier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.22.0
|
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-
|
11
|
+
date: 2020-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -82,11 +82,13 @@ files:
|
|
82
82
|
- src/nodes/blocks.js
|
83
83
|
- src/nodes/calls.js
|
84
84
|
- src/nodes/case.js
|
85
|
+
- src/nodes/class.js
|
85
86
|
- src/nodes/commands.js
|
86
87
|
- src/nodes/conditionals.js
|
87
88
|
- src/nodes/constants.js
|
88
89
|
- src/nodes/flow.js
|
89
90
|
- src/nodes/hashes.js
|
91
|
+
- src/nodes/heredocs.js
|
90
92
|
- src/nodes/hooks.js
|
91
93
|
- src/nodes/ints.js
|
92
94
|
- src/nodes/lambdas.js
|
@@ -99,18 +101,20 @@ files:
|
|
99
101
|
- src/nodes/regexp.js
|
100
102
|
- src/nodes/rescue.js
|
101
103
|
- src/nodes/return.js
|
102
|
-
- src/nodes/scopes.js
|
103
104
|
- src/nodes/statements.js
|
104
105
|
- src/nodes/strings.js
|
105
|
-
- src/
|
106
|
+
- src/nodes/super.js
|
107
|
+
- src/nodes/undef.js
|
108
|
+
- src/parser.js
|
106
109
|
- src/parser.rb
|
107
110
|
- src/prettier.js
|
108
|
-
- src/
|
111
|
+
- src/printer.js
|
109
112
|
- src/ruby.js
|
110
113
|
- src/toProc.js
|
111
114
|
- src/utils.js
|
112
115
|
- src/utils/inlineEnsureParens.js
|
113
116
|
- src/utils/isEmptyStmts.js
|
117
|
+
- src/utils/literalLineNoBreak.js
|
114
118
|
homepage: https://github.com/prettier/plugin-ruby#readme
|
115
119
|
licenses:
|
116
120
|
- MIT
|
data/src/nodes/scopes.js
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
const {
|
2
|
-
concat,
|
3
|
-
group,
|
4
|
-
hardline,
|
5
|
-
ifBreak,
|
6
|
-
indent,
|
7
|
-
line
|
8
|
-
} = require("../prettier");
|
9
|
-
|
10
|
-
module.exports = {
|
11
|
-
class: (path, opts, print) => {
|
12
|
-
const [_constant, superclass, statements] = path.getValue().body;
|
13
|
-
|
14
|
-
const parts = ["class ", path.call(print, "body", 0)];
|
15
|
-
if (superclass) {
|
16
|
-
parts.push(" < ", path.call(print, "body", 1));
|
17
|
-
}
|
18
|
-
|
19
|
-
// If the body is empty, we can replace with a ;
|
20
|
-
const stmts = statements.body[0].body;
|
21
|
-
if (stmts.length === 1 && stmts[0].type === "void_stmt") {
|
22
|
-
return group(concat([concat(parts), ifBreak(line, "; "), "end"]));
|
23
|
-
}
|
24
|
-
|
25
|
-
return group(
|
26
|
-
concat([
|
27
|
-
concat(parts),
|
28
|
-
indent(concat([hardline, path.call(print, "body", 2)])),
|
29
|
-
concat([hardline, "end"])
|
30
|
-
])
|
31
|
-
);
|
32
|
-
},
|
33
|
-
class_name_error: (_path, _opts, _print) => {
|
34
|
-
throw new Error("class/module name must be CONSTANT");
|
35
|
-
},
|
36
|
-
module: (path, opts, print) => {
|
37
|
-
const declaration = group(concat(["module ", path.call(print, "body", 0)]));
|
38
|
-
|
39
|
-
// If the body is empty, we can replace with a ;
|
40
|
-
const stmts = path.getValue().body[1].body[0].body;
|
41
|
-
if (stmts.length === 1 && stmts[0].type === "void_stmt") {
|
42
|
-
return group(concat([declaration, ifBreak(line, "; "), "end"]));
|
43
|
-
}
|
44
|
-
|
45
|
-
return group(
|
46
|
-
concat([
|
47
|
-
declaration,
|
48
|
-
indent(concat([hardline, path.call(print, "body", 1)])),
|
49
|
-
concat([hardline, "end"])
|
50
|
-
])
|
51
|
-
);
|
52
|
-
},
|
53
|
-
sclass: (path, opts, print) =>
|
54
|
-
group(
|
55
|
-
concat([
|
56
|
-
concat(["class << ", path.call(print, "body", 0)]),
|
57
|
-
indent(concat([hardline, path.call(print, "body", 1)])),
|
58
|
-
concat([hardline, "end"])
|
59
|
-
])
|
60
|
-
)
|
61
|
-
};
|
data/src/parse.js
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
const { spawnSync } = require("child_process");
|
2
|
-
const path = require("path");
|
3
|
-
|
4
|
-
// In order to properly parse ruby code, we need to tell the ruby process to
|
5
|
-
// parse using UTF-8. Unfortunately, the way that you accomplish this looks
|
6
|
-
// differently depending on your platform. This object below represents all of
|
7
|
-
// the possible values of process.platform per:
|
8
|
-
// https://nodejs.org/api/process.html#process_process_platform
|
9
|
-
const LANG = {
|
10
|
-
aix: "C.UTF-8",
|
11
|
-
darwin: "en_US.UTF-8",
|
12
|
-
freebsd: "C.UTF-8",
|
13
|
-
linux: "C.UTF-8",
|
14
|
-
openbsd: "C.UTF-8",
|
15
|
-
sunos: "C.UTF-8",
|
16
|
-
win32: ".UTF-8"
|
17
|
-
}[process.platform];
|
18
|
-
|
19
|
-
module.exports = (text, _parsers, _opts) => {
|
20
|
-
const child = spawnSync(
|
21
|
-
"ruby",
|
22
|
-
["--disable-gems", path.join(__dirname, "./parser.rb")],
|
23
|
-
{
|
24
|
-
env: Object.assign({}, process.env, { LANG }),
|
25
|
-
input: text,
|
26
|
-
maxBuffer: 10 * 1024 * 1024 // 10MB
|
27
|
-
}
|
28
|
-
);
|
29
|
-
|
30
|
-
const error = child.stderr.toString();
|
31
|
-
if (error) {
|
32
|
-
throw new Error(error);
|
33
|
-
}
|
34
|
-
|
35
|
-
const response = child.stdout.toString();
|
36
|
-
return JSON.parse(response);
|
37
|
-
};
|
data/src/print.js
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
const { printComments } = require("./utils");
|
2
|
-
const nodes = require("./nodes");
|
3
|
-
|
4
|
-
module.exports = (path, opts, print) => {
|
5
|
-
const { type, body, comments, start } = path.getValue();
|
6
|
-
|
7
|
-
if (type in nodes) {
|
8
|
-
const printed = nodes[type](path, opts, print);
|
9
|
-
|
10
|
-
if (comments) {
|
11
|
-
return printComments(printed, start, comments);
|
12
|
-
}
|
13
|
-
return printed;
|
14
|
-
}
|
15
|
-
|
16
|
-
if (type[0] === "@") {
|
17
|
-
return body;
|
18
|
-
}
|
19
|
-
|
20
|
-
throw new Error(
|
21
|
-
`Unsupported node encountered: ${type}\n${JSON.stringify(body, null, 2)}`
|
22
|
-
);
|
23
|
-
};
|