prettier 1.6.1 → 2.0.0.pre.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +316 -293
- data/CONTRIBUTING.md +6 -9
- data/LICENSE +1 -1
- data/README.md +11 -12
- data/dist/haml/embed.js +53 -0
- data/dist/haml/parser.js +31 -0
- data/{src → dist}/haml/parser.rb +0 -0
- data/dist/haml/printer.js +336 -0
- data/dist/parser/getInfo.js +17 -0
- data/{src → dist}/parser/netcat.js +1 -0
- data/dist/parser/parseSync.js +128 -0
- data/dist/parser/server.rb +140 -0
- data/dist/plugin.js +143 -0
- data/dist/prettier.js +15 -0
- data/dist/rbs/parser.js +34 -0
- data/{src → dist}/rbs/parser.rb +0 -0
- data/dist/rbs/printer.js +517 -0
- data/dist/ruby/embed.js +110 -0
- data/dist/ruby/nodes/alias.js +59 -0
- data/{src → dist}/ruby/nodes/aref.js +26 -35
- data/dist/ruby/nodes/args.js +165 -0
- data/dist/ruby/nodes/arrays.js +126 -0
- data/dist/ruby/nodes/assign.js +41 -0
- data/dist/ruby/nodes/blocks.js +68 -0
- data/dist/ruby/nodes/calls.js +220 -0
- data/dist/ruby/nodes/case.js +50 -0
- data/dist/ruby/nodes/class.js +54 -0
- data/dist/ruby/nodes/commands.js +124 -0
- data/dist/ruby/nodes/conditionals.js +242 -0
- data/dist/ruby/nodes/constants.js +38 -0
- data/dist/ruby/nodes/flow.js +66 -0
- data/dist/ruby/nodes/hashes.js +130 -0
- data/dist/ruby/nodes/heredocs.js +30 -0
- data/dist/ruby/nodes/hooks.js +35 -0
- data/dist/ruby/nodes/ints.js +27 -0
- data/dist/ruby/nodes/lambdas.js +69 -0
- data/dist/ruby/nodes/loops.js +73 -0
- data/dist/ruby/nodes/massign.js +73 -0
- data/dist/ruby/nodes/methods.js +70 -0
- data/dist/ruby/nodes/operators.js +70 -0
- data/dist/ruby/nodes/params.js +89 -0
- data/dist/ruby/nodes/patterns.js +109 -0
- data/dist/ruby/nodes/regexp.js +45 -0
- data/dist/ruby/nodes/rescue.js +82 -0
- data/dist/ruby/nodes/return.js +75 -0
- data/dist/ruby/nodes/statements.js +111 -0
- data/dist/ruby/nodes/strings.js +218 -0
- data/dist/ruby/nodes/super.js +30 -0
- data/dist/ruby/nodes/undef.js +26 -0
- data/dist/ruby/nodes.js +151 -0
- data/dist/ruby/parser.js +34 -0
- data/{src → dist}/ruby/parser.rb +1215 -252
- data/dist/ruby/printer.js +125 -0
- data/dist/ruby/toProc.js +93 -0
- data/dist/types/haml.js +4 -0
- data/dist/types/plugin.js +3 -0
- data/dist/types/rbs.js +4 -0
- data/dist/types/ruby.js +4 -0
- data/dist/types/utils.js +2 -0
- data/dist/types.js +30 -0
- data/dist/utils/containsAssignment.js +15 -0
- data/dist/utils/getTrailingComma.js +6 -0
- data/dist/utils/hasAncestor.js +15 -0
- data/{src → dist}/utils/inlineEnsureParens.js +16 -17
- data/dist/utils/isEmptyBodyStmt.js +10 -0
- data/dist/utils/isEmptyStmts.js +10 -0
- data/dist/utils/literal.js +8 -0
- data/dist/utils/literallineWithoutBreakParent.js +8 -0
- data/dist/utils/makeCall.js +13 -0
- data/dist/utils/noIndent.js +11 -0
- data/dist/utils/printEmptyCollection.js +44 -0
- data/dist/utils/skipAssignIndent.js +15 -0
- data/dist/utils.js +30 -0
- data/node_modules/prettier/bin-prettier.js +313 -190
- data/node_modules/prettier/doc.js +191 -323
- data/node_modules/prettier/index.js +2753 -3677
- data/node_modules/prettier/package.json +1 -1
- data/node_modules/prettier/parser-angular.js +13 -14
- data/node_modules/prettier/parser-babel.js +7 -7
- data/node_modules/prettier/parser-espree.js +7 -7
- data/node_modules/prettier/parser-flow.js +7 -7
- 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 +17 -17
- data/node_modules/prettier/parser-markdown.js +9 -9
- data/node_modules/prettier/parser-meriyah.js +7 -7
- data/node_modules/prettier/parser-postcss.js +2 -2
- data/node_modules/prettier/parser-typescript.js +7 -7
- data/node_modules/prettier/parser-yaml.js +2 -2
- data/node_modules/prettier/third-party.js +143 -78
- data/package.json +26 -18
- metadata +74 -67
- data/src/haml/embed.js +0 -87
- data/src/haml/parser.js +0 -23
- data/src/haml/printer.js +0 -438
- data/src/parser/parseSync.js +0 -172
- data/src/parser/server.rb +0 -66
- data/src/plugin.js +0 -148
- data/src/prettier.js +0 -16
- data/src/rbs/parser.js +0 -37
- data/src/rbs/printer.js +0 -643
- data/src/ruby/embed.js +0 -142
- data/src/ruby/nodes/alias.js +0 -73
- data/src/ruby/nodes/args.js +0 -222
- data/src/ruby/nodes/arrays.js +0 -162
- data/src/ruby/nodes/assign.js +0 -47
- data/src/ruby/nodes/blocks.js +0 -90
- data/src/ruby/nodes/calls.js +0 -246
- data/src/ruby/nodes/case.js +0 -65
- data/src/ruby/nodes/class.js +0 -64
- data/src/ruby/nodes/commands.js +0 -131
- data/src/ruby/nodes/conditionals.js +0 -282
- data/src/ruby/nodes/constants.js +0 -43
- data/src/ruby/nodes/flow.js +0 -74
- data/src/ruby/nodes/hashes.js +0 -155
- data/src/ruby/nodes/heredocs.js +0 -36
- data/src/ruby/nodes/hooks.js +0 -34
- data/src/ruby/nodes/ints.js +0 -31
- data/src/ruby/nodes/lambdas.js +0 -76
- data/src/ruby/nodes/loops.js +0 -98
- data/src/ruby/nodes/massign.js +0 -98
- data/src/ruby/nodes/methods.js +0 -74
- data/src/ruby/nodes/operators.js +0 -83
- data/src/ruby/nodes/params.js +0 -106
- data/src/ruby/nodes/patterns.js +0 -157
- data/src/ruby/nodes/regexp.js +0 -56
- data/src/ruby/nodes/rescue.js +0 -101
- data/src/ruby/nodes/return.js +0 -94
- data/src/ruby/nodes/statements.js +0 -142
- data/src/ruby/nodes/strings.js +0 -272
- data/src/ruby/nodes/super.js +0 -35
- data/src/ruby/nodes/undef.js +0 -42
- data/src/ruby/nodes.js +0 -34
- data/src/ruby/parser.js +0 -37
- data/src/ruby/printer.js +0 -147
- data/src/ruby/toProc.js +0 -105
- data/src/utils/containsAssignment.js +0 -11
- data/src/utils/getTrailingComma.js +0 -5
- data/src/utils/hasAncestor.js +0 -17
- data/src/utils/isEmptyBodyStmt.js +0 -7
- data/src/utils/isEmptyStmts.js +0 -11
- data/src/utils/literal.js +0 -7
- data/src/utils/literallineWithoutBreakParent.js +0 -7
- data/src/utils/makeCall.js +0 -14
- data/src/utils/noIndent.js +0 -10
- data/src/utils/printEmptyCollection.js +0 -49
- data/src/utils/skipAssignIndent.js +0 -17
- data/src/utils.js +0 -13
data/src/ruby/embed.js
DELETED
@@ -1,142 +0,0 @@
|
|
1
|
-
const {
|
2
|
-
concat,
|
3
|
-
group,
|
4
|
-
indent,
|
5
|
-
lineSuffix,
|
6
|
-
mapDoc,
|
7
|
-
markAsRoot,
|
8
|
-
stripTrailingHardline
|
9
|
-
} = require("../prettier");
|
10
|
-
|
11
|
-
const { literallineWithoutBreakParent } = require("../utils");
|
12
|
-
|
13
|
-
const parsers = {
|
14
|
-
css: "css",
|
15
|
-
javascript: "babel",
|
16
|
-
js: "babel",
|
17
|
-
less: "less",
|
18
|
-
markdown: "markdown",
|
19
|
-
ruby: "ruby",
|
20
|
-
scss: "scss"
|
21
|
-
};
|
22
|
-
|
23
|
-
// This function is in here because it handles embedded parser values. I don't
|
24
|
-
// have a test that exercises it because I'm not sure for which parser it is
|
25
|
-
// necessary, but since it's in prettier core I'm keeping it here.
|
26
|
-
/* istanbul ignore next */
|
27
|
-
function replaceNewlines(doc) {
|
28
|
-
return mapDoc(doc, (currentDoc) =>
|
29
|
-
typeof currentDoc === "string" && currentDoc.includes("\n")
|
30
|
-
? concat(
|
31
|
-
currentDoc
|
32
|
-
.split(/(\n)/g)
|
33
|
-
.map((v, i) => (i % 2 === 0 ? v : literallineWithoutBreakParent))
|
34
|
-
)
|
35
|
-
: currentDoc
|
36
|
-
);
|
37
|
-
}
|
38
|
-
|
39
|
-
// Returns a number that represents the minimum amount of leading whitespace
|
40
|
-
// that is present on every line in the given string. So for example if you have
|
41
|
-
// the following heredoc:
|
42
|
-
//
|
43
|
-
// <<~HERE
|
44
|
-
// my
|
45
|
-
// content
|
46
|
-
// here
|
47
|
-
// HERE
|
48
|
-
//
|
49
|
-
// then the return value of this function would be 2. If you indented every line
|
50
|
-
// of the inner content 2 more spaces then this function would return 4.
|
51
|
-
function getCommonLeadingWhitespace(content) {
|
52
|
-
const pattern = /^\s+/;
|
53
|
-
|
54
|
-
return content
|
55
|
-
.split("\n")
|
56
|
-
.slice(0, -1)
|
57
|
-
.reduce((minimum, line) => {
|
58
|
-
const matched = pattern.exec(line);
|
59
|
-
const length = matched ? matched[0].length : 0;
|
60
|
-
|
61
|
-
return minimum === null ? length : Math.min(minimum, length);
|
62
|
-
}, null);
|
63
|
-
}
|
64
|
-
|
65
|
-
// Returns a new string with the common whitespace stripped out. Effectively it
|
66
|
-
// emulates what a squiggly heredoc does in Ruby.
|
67
|
-
function stripCommonLeadingWhitespace(content) {
|
68
|
-
const lines = content.split("\n");
|
69
|
-
const minimum = getCommonLeadingWhitespace(content);
|
70
|
-
|
71
|
-
return lines.map((line) => line.slice(minimum)).join("\n");
|
72
|
-
}
|
73
|
-
|
74
|
-
function embed(path, print, textToDoc, _opts) {
|
75
|
-
const node = path.getValue();
|
76
|
-
|
77
|
-
// Currently we only support embedded formatting on heredoc nodes
|
78
|
-
if (node.type !== "heredoc") {
|
79
|
-
return null;
|
80
|
-
}
|
81
|
-
|
82
|
-
// First, ensure that we don't have any interpolation
|
83
|
-
const { beging, body, ending } = node;
|
84
|
-
const isSquiggly = beging.body[2] === "~";
|
85
|
-
|
86
|
-
if (body.some((part) => part.type !== "@tstring_content")) {
|
87
|
-
return null;
|
88
|
-
}
|
89
|
-
|
90
|
-
// Next, find the parser associated with this heredoc (if there is one). For
|
91
|
-
// example, if you use <<~CSS, we'd hook it up to the css parser.
|
92
|
-
const parser = parsers[beging.body.slice(3).toLowerCase()];
|
93
|
-
if (!parser) {
|
94
|
-
return null;
|
95
|
-
}
|
96
|
-
|
97
|
-
// Get the content as if it were a source string.
|
98
|
-
let content = body.map((part) => part.body).join("");
|
99
|
-
|
100
|
-
// If we're using a squiggly heredoc, then we're going to manually strip off
|
101
|
-
// the leading whitespace of each line up to the minimum leading whitespace so
|
102
|
-
// that the embedded parser can handle that for us.
|
103
|
-
if (isSquiggly) {
|
104
|
-
content = stripCommonLeadingWhitespace(content);
|
105
|
-
}
|
106
|
-
|
107
|
-
// Pass that content into the embedded parser. Get back the doc node.
|
108
|
-
const formatted = concat([
|
109
|
-
literallineWithoutBreakParent,
|
110
|
-
replaceNewlines(stripTrailingHardline(textToDoc(content, { parser })))
|
111
|
-
]);
|
112
|
-
|
113
|
-
// If we're using a squiggly heredoc, then we can properly handle indentation
|
114
|
-
// ourselves.
|
115
|
-
if (isSquiggly) {
|
116
|
-
return concat([
|
117
|
-
path.call(print, "beging"),
|
118
|
-
lineSuffix(
|
119
|
-
group(
|
120
|
-
concat([
|
121
|
-
indent(markAsRoot(formatted)),
|
122
|
-
literallineWithoutBreakParent,
|
123
|
-
ending.trim()
|
124
|
-
])
|
125
|
-
)
|
126
|
-
)
|
127
|
-
]);
|
128
|
-
}
|
129
|
-
|
130
|
-
// Otherwise, we need to just assume it's formatted correctly and return the
|
131
|
-
// content as it is.
|
132
|
-
return markAsRoot(
|
133
|
-
concat([
|
134
|
-
path.call(print, "beging"),
|
135
|
-
lineSuffix(
|
136
|
-
group(concat([formatted, literallineWithoutBreakParent, ending.trim()]))
|
137
|
-
)
|
138
|
-
])
|
139
|
-
);
|
140
|
-
}
|
141
|
-
|
142
|
-
module.exports = embed;
|
data/src/ruby/nodes/alias.js
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
const {
|
2
|
-
addTrailingComment,
|
3
|
-
align,
|
4
|
-
concat,
|
5
|
-
group,
|
6
|
-
hardline,
|
7
|
-
line
|
8
|
-
} = require("../../prettier");
|
9
|
-
|
10
|
-
// In general, return the printed doc of the argument at the provided index.
|
11
|
-
// Special handling is given for symbol literals that are not bare words, as we
|
12
|
-
// convert those into bare words by just pulling out the ident node.
|
13
|
-
function printAliasArgument(path, print, argIndex) {
|
14
|
-
const node = path.getValue().body[argIndex];
|
15
|
-
|
16
|
-
if (node.type === "symbol_literal") {
|
17
|
-
// If we're going to descend into the symbol literal to grab out the ident
|
18
|
-
// node, then we need to make sure we copy over any comments as well,
|
19
|
-
// otherwise we could accidentally skip printing them.
|
20
|
-
if (node.comments) {
|
21
|
-
node.comments.forEach((comment) => {
|
22
|
-
addTrailingComment(node.body[0], comment);
|
23
|
-
});
|
24
|
-
}
|
25
|
-
|
26
|
-
return path.call(print, "body", argIndex, "body", 0);
|
27
|
-
}
|
28
|
-
|
29
|
-
return path.call(print, "body", argIndex);
|
30
|
-
}
|
31
|
-
|
32
|
-
// The `alias` keyword is used to make a method respond to another name as well
|
33
|
-
// as the current one. For example, to get the method `foo` to also respond to
|
34
|
-
// `bar`, you would:
|
35
|
-
//
|
36
|
-
// alias bar foo
|
37
|
-
//
|
38
|
-
// Now, in the current context you can call `bar` and it will execute the `foo`
|
39
|
-
// method.
|
40
|
-
//
|
41
|
-
// When you're aliasing two methods, you can either provide bare words (like the
|
42
|
-
// example above) or you can provide symbols (note that this includes dynamic
|
43
|
-
// symbols like :"foo-#{bar}-baz"). In general, to be consistent with the ruby
|
44
|
-
// style guide, we prefer bare words:
|
45
|
-
//
|
46
|
-
// https://github.com/rubocop-hq/ruby-style-guide#alias-method-lexically
|
47
|
-
//
|
48
|
-
// The `alias` node contains two children. The left and right align with the
|
49
|
-
// arguments passed to the keyword. So, for the above example the left would be
|
50
|
-
// the symbol literal `bar` and the right could be the symbol literal `foo`.
|
51
|
-
function printAlias(path, opts, print) {
|
52
|
-
const keyword = "alias ";
|
53
|
-
|
54
|
-
const rightSide = concat([
|
55
|
-
// If the left child has any comments, then we need to explicitly break this
|
56
|
-
// into two lines
|
57
|
-
path.getValue().body[0].comments ? hardline : line,
|
58
|
-
printAliasArgument(path, print, 1)
|
59
|
-
]);
|
60
|
-
|
61
|
-
return group(
|
62
|
-
concat([
|
63
|
-
keyword,
|
64
|
-
printAliasArgument(path, print, 0),
|
65
|
-
group(align(keyword.length, rightSide))
|
66
|
-
])
|
67
|
-
);
|
68
|
-
}
|
69
|
-
|
70
|
-
module.exports = {
|
71
|
-
alias: printAlias,
|
72
|
-
var_alias: printAlias
|
73
|
-
};
|
data/src/ruby/nodes/args.js
DELETED
@@ -1,222 +0,0 @@
|
|
1
|
-
const {
|
2
|
-
concat,
|
3
|
-
group,
|
4
|
-
ifBreak,
|
5
|
-
indent,
|
6
|
-
join,
|
7
|
-
line,
|
8
|
-
softline
|
9
|
-
} = require("../../prettier");
|
10
|
-
const { getTrailingComma } = require("../../utils");
|
11
|
-
const toProc = require("../toProc");
|
12
|
-
|
13
|
-
const noTrailingComma = ["command", "command_call"];
|
14
|
-
|
15
|
-
function getArgParenTrailingComma(node) {
|
16
|
-
// If we have a block, then we don't want to add a trailing comma.
|
17
|
-
if (node.type === "args_add_block" && node.body[1]) {
|
18
|
-
return "";
|
19
|
-
}
|
20
|
-
|
21
|
-
// If we only have one argument and that first argument necessitates that we
|
22
|
-
// skip putting a comma (because it would interfere with parsing the argument)
|
23
|
-
// then we don't want to add a trailing comma.
|
24
|
-
if (node.body.length === 1 && noTrailingComma.includes(node.body[0].type)) {
|
25
|
-
return "";
|
26
|
-
}
|
27
|
-
|
28
|
-
return ifBreak(",", "");
|
29
|
-
}
|
30
|
-
|
31
|
-
function printArgParen(path, opts, print) {
|
32
|
-
const argsNode = path.getValue().body[0];
|
33
|
-
|
34
|
-
if (argsNode === null) {
|
35
|
-
return "";
|
36
|
-
}
|
37
|
-
|
38
|
-
// Here we can skip the entire rest of the method by just checking if it's
|
39
|
-
// an args_forward node, as we're guaranteed that there are no other arg
|
40
|
-
// nodes.
|
41
|
-
if (argsNode.type === "args_forward") {
|
42
|
-
return group(
|
43
|
-
concat([
|
44
|
-
"(",
|
45
|
-
indent(concat([softline, path.call(print, "body", 0)])),
|
46
|
-
softline,
|
47
|
-
")"
|
48
|
-
])
|
49
|
-
);
|
50
|
-
}
|
51
|
-
|
52
|
-
// Now here we return a doc that represents the whole grouped expression,
|
53
|
-
// including the surrouding parentheses.
|
54
|
-
return group(
|
55
|
-
concat([
|
56
|
-
"(",
|
57
|
-
indent(
|
58
|
-
concat([
|
59
|
-
softline,
|
60
|
-
join(concat([",", line]), path.call(print, "body", 0)),
|
61
|
-
getTrailingComma(opts) ? getArgParenTrailingComma(argsNode) : ""
|
62
|
-
])
|
63
|
-
),
|
64
|
-
softline,
|
65
|
-
")"
|
66
|
-
])
|
67
|
-
);
|
68
|
-
}
|
69
|
-
|
70
|
-
function printArgs(path, { rubyToProc }, print) {
|
71
|
-
const args = path.map(print, "body");
|
72
|
-
|
73
|
-
// Don't bother trying to do any kind of fancy toProc transform if the
|
74
|
-
// option is disabled.
|
75
|
-
if (rubyToProc) {
|
76
|
-
let blockNode = null;
|
77
|
-
|
78
|
-
// Look up the chain to see if these arguments are contained within a
|
79
|
-
// method_add_block node, and if they are that that node has a block
|
80
|
-
// associated with it. If it does, we're going to attempt to transform it
|
81
|
-
// into the to_proc shorthand and add it to the list of arguments.
|
82
|
-
[1, 2, 3].find((parent) => {
|
83
|
-
const parentNode = path.getParentNode(parent);
|
84
|
-
blockNode =
|
85
|
-
parentNode &&
|
86
|
-
parentNode.type === "method_add_block" &&
|
87
|
-
parentNode.body[1];
|
88
|
-
|
89
|
-
return blockNode;
|
90
|
-
});
|
91
|
-
|
92
|
-
const proc = blockNode && toProc(path, blockNode);
|
93
|
-
|
94
|
-
// If we have a successful to_proc transformation, but we're part of an
|
95
|
-
// aref node, that means it's something to the effect of
|
96
|
-
//
|
97
|
-
// foo[:bar].each(&:to_s)
|
98
|
-
//
|
99
|
-
// In this case we need to just return regular arguments, otherwise we
|
100
|
-
// would end up putting &:to_s inside the brackets accidentally.
|
101
|
-
if (proc && path.getParentNode(1).type !== "aref") {
|
102
|
-
args.push(proc);
|
103
|
-
}
|
104
|
-
}
|
105
|
-
|
106
|
-
return args;
|
107
|
-
}
|
108
|
-
|
109
|
-
function printArgsAddBlock(path, opts, print) {
|
110
|
-
const node = path.getValue();
|
111
|
-
const blockNode = node.body[1];
|
112
|
-
|
113
|
-
const parts = path.call(print, "body", 0);
|
114
|
-
|
115
|
-
if (blockNode) {
|
116
|
-
let blockDoc = path.call(print, "body", 1);
|
117
|
-
|
118
|
-
if (!(blockNode.comments || []).some(({ leading }) => leading)) {
|
119
|
-
// If we don't have any leading comments, we can just prepend the
|
120
|
-
// operator.
|
121
|
-
blockDoc = concat(["&", blockDoc]);
|
122
|
-
} else if (Array.isArray(blockDoc[0])) {
|
123
|
-
// If we have a method call like:
|
124
|
-
//
|
125
|
-
// foo(
|
126
|
-
// # comment
|
127
|
-
// &block
|
128
|
-
// )
|
129
|
-
//
|
130
|
-
// then we need to make sure we don't accidentally prepend the operator
|
131
|
-
// before the comment.
|
132
|
-
//
|
133
|
-
// In prettier >= 2.3.0, the comments are printed as an array before the
|
134
|
-
// content. I don't love this kind of reflection, but it's the simplest
|
135
|
-
// way at the moment to get this right.
|
136
|
-
blockDoc = blockDoc[0].concat(
|
137
|
-
concat(["&", blockDoc[1]]),
|
138
|
-
blockDoc.slice(2)
|
139
|
-
);
|
140
|
-
} else {
|
141
|
-
// In prettier < 2.3.0, the comments are printed as part of a concat, so
|
142
|
-
// we can reflect on how many leading comments there are to determine
|
143
|
-
// which doc node we should modify.
|
144
|
-
const index = blockNode.comments.filter(({ leading }) => leading).length;
|
145
|
-
blockDoc.parts[index] = concat(["&", blockDoc.parts[index]]);
|
146
|
-
}
|
147
|
-
|
148
|
-
parts.push(blockDoc);
|
149
|
-
}
|
150
|
-
|
151
|
-
return parts;
|
152
|
-
}
|
153
|
-
|
154
|
-
function printArgsAddStar(path, opts, print) {
|
155
|
-
let docs = [];
|
156
|
-
|
157
|
-
path.each((argPath, argIndex) => {
|
158
|
-
const doc = print(argPath);
|
159
|
-
|
160
|
-
// If it's the first child, then it's an array of args, so we're going to
|
161
|
-
// concat that onto the existing docs if there are any.
|
162
|
-
if (argIndex === 0) {
|
163
|
-
if (doc.length > 0) {
|
164
|
-
docs = docs.concat(doc);
|
165
|
-
}
|
166
|
-
return;
|
167
|
-
}
|
168
|
-
|
169
|
-
// If it's after the splat, then it's an individual arg, so we're just going
|
170
|
-
// to push it onto the array.
|
171
|
-
if (argIndex !== 1) {
|
172
|
-
docs.push(doc);
|
173
|
-
return;
|
174
|
-
}
|
175
|
-
|
176
|
-
// If we don't have any leading comments, we can just prepend the operator.
|
177
|
-
const argsNode = argPath.getValue();
|
178
|
-
if (!(argsNode.comments || []).some(({ leading }) => leading)) {
|
179
|
-
docs.push(concat(["*", doc]));
|
180
|
-
return;
|
181
|
-
}
|
182
|
-
|
183
|
-
// If we have an array like:
|
184
|
-
//
|
185
|
-
// [
|
186
|
-
// # comment
|
187
|
-
// *values
|
188
|
-
// ]
|
189
|
-
//
|
190
|
-
// then we need to make sure we don't accidentally prepend the operator
|
191
|
-
// before the comment(s).
|
192
|
-
//
|
193
|
-
// In prettier >= 2.3.0, the comments are printed as an array before the
|
194
|
-
// content. I don't love this kind of reflection, but it's the simplest way
|
195
|
-
// at the moment to get this right.
|
196
|
-
if (Array.isArray(doc[0])) {
|
197
|
-
docs.push(doc[0].concat(concat(["*", doc[1]]), doc.slice(2)));
|
198
|
-
return;
|
199
|
-
}
|
200
|
-
|
201
|
-
// In prettier < 2.3.0, the comments are printed as part of a concat, so
|
202
|
-
// we can reflect on how many leading comments there are to determine which
|
203
|
-
// doc node we should modify.
|
204
|
-
const index = argsNode.comments.filter(({ leading }) => leading).length;
|
205
|
-
doc.parts[index] = concat(["*", doc.parts[index]]);
|
206
|
-
docs = docs.concat(doc);
|
207
|
-
}, "body");
|
208
|
-
|
209
|
-
return docs;
|
210
|
-
}
|
211
|
-
|
212
|
-
function printBlockArg(path, opts, print) {
|
213
|
-
return concat(["&", path.call(print, "body", 0)]);
|
214
|
-
}
|
215
|
-
|
216
|
-
module.exports = {
|
217
|
-
arg_paren: printArgParen,
|
218
|
-
args: printArgs,
|
219
|
-
args_add_block: printArgsAddBlock,
|
220
|
-
args_add_star: printArgsAddStar,
|
221
|
-
blockarg: printBlockArg
|
222
|
-
};
|
data/src/ruby/nodes/arrays.js
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
const {
|
2
|
-
concat,
|
3
|
-
group,
|
4
|
-
ifBreak,
|
5
|
-
indent,
|
6
|
-
join,
|
7
|
-
line,
|
8
|
-
softline
|
9
|
-
} = require("../../prettier");
|
10
|
-
const { getTrailingComma, printEmptyCollection } = require("../../utils");
|
11
|
-
|
12
|
-
// Checks that every argument within this args node is a string_literal node
|
13
|
-
// that has no spaces or interpolations. This means we're dealing with an array
|
14
|
-
// that looks something like:
|
15
|
-
//
|
16
|
-
// ['a', 'b', 'c']
|
17
|
-
//
|
18
|
-
function isStringArray(args) {
|
19
|
-
return (
|
20
|
-
args.body.length > 1 &&
|
21
|
-
args.body.every((arg) => {
|
22
|
-
// We want to verify that every node inside of this array is a string
|
23
|
-
// literal. We also want to make sure none of them have comments attached.
|
24
|
-
if (arg.type !== "string_literal" || arg.comments) {
|
25
|
-
return false;
|
26
|
-
}
|
27
|
-
|
28
|
-
// If the string has multiple parts (meaning plain string content but also
|
29
|
-
// interpolated content) then we know it's not a simple string.
|
30
|
-
if (arg.body.length !== 1) {
|
31
|
-
return false;
|
32
|
-
}
|
33
|
-
|
34
|
-
const part = arg.body[0];
|
35
|
-
|
36
|
-
// If the only part of this string is not @tstring_content then it's
|
37
|
-
// interpolated, so again we can return false.
|
38
|
-
if (part.type !== "@tstring_content") {
|
39
|
-
return false;
|
40
|
-
}
|
41
|
-
|
42
|
-
// Finally, verify that the string doesn't contain a space, an escape
|
43
|
-
// character, or brackets so that we know it can be put into a string
|
44
|
-
// literal array.
|
45
|
-
return !/[\s\\[\]]/.test(part.body);
|
46
|
-
})
|
47
|
-
);
|
48
|
-
}
|
49
|
-
|
50
|
-
// Checks that every argument within this args node is a symbol_literal node (as
|
51
|
-
// opposed to a dyna_symbol) so it has no interpolation. This means we're
|
52
|
-
// dealing with an array that looks something like:
|
53
|
-
//
|
54
|
-
// [:a, :b, :c]
|
55
|
-
//
|
56
|
-
function isSymbolArray(args) {
|
57
|
-
return (
|
58
|
-
args.body.length > 1 &&
|
59
|
-
args.body.every((arg) => arg.type === "symbol_literal" && !arg.comments)
|
60
|
-
);
|
61
|
-
}
|
62
|
-
|
63
|
-
// Prints out a word that is a part of a special array literal that accepts
|
64
|
-
// interpolation. The body is an array of either plain strings or interpolated
|
65
|
-
// expressions.
|
66
|
-
function printArrayLiteralWord(path, opts, print) {
|
67
|
-
return concat(path.map(print, "body"));
|
68
|
-
}
|
69
|
-
|
70
|
-
// Prints out a special array literal. Accepts the parts of the array literal as
|
71
|
-
// an argument, where the first element of the parts array is a string that
|
72
|
-
// contains the special start.
|
73
|
-
function printArrayLiteral(start, parts) {
|
74
|
-
return group(
|
75
|
-
concat([
|
76
|
-
start,
|
77
|
-
"[",
|
78
|
-
indent(concat([softline, join(line, parts)])),
|
79
|
-
concat([softline, "]"])
|
80
|
-
])
|
81
|
-
);
|
82
|
-
}
|
83
|
-
|
84
|
-
const arrayLiteralStarts = {
|
85
|
-
qsymbols: "%i",
|
86
|
-
qwords: "%w",
|
87
|
-
symbols: "%I",
|
88
|
-
words: "%W"
|
89
|
-
};
|
90
|
-
|
91
|
-
// An array node is any literal array in Ruby. This includes all of the special
|
92
|
-
// array literals as well as regular arrays. If it is a special array literal
|
93
|
-
// then it will have one child that represents the special array, otherwise it
|
94
|
-
// will have one child that contains all of the elements of the array.
|
95
|
-
function printArray(path, opts, print) {
|
96
|
-
const array = path.getValue();
|
97
|
-
const args = array.body[0];
|
98
|
-
|
99
|
-
// If there is no inner arguments node, then we're dealing with an empty
|
100
|
-
// array, so we can go ahead and return.
|
101
|
-
if (args === null) {
|
102
|
-
return printEmptyCollection(path, opts, "[", "]");
|
103
|
-
}
|
104
|
-
|
105
|
-
if (opts.rubyArrayLiteral) {
|
106
|
-
// If we have an array that contains only simple string literals with no
|
107
|
-
// spaces or interpolation, then we're going to print a %w array.
|
108
|
-
if (isStringArray(args)) {
|
109
|
-
const printString = (stringPath) => stringPath.call(print, "body", 0);
|
110
|
-
const parts = path.map(printString, "body", 0, "body");
|
111
|
-
|
112
|
-
return printArrayLiteral("%w", parts);
|
113
|
-
}
|
114
|
-
|
115
|
-
// If we have an array that contains only simple symbol literals with no
|
116
|
-
// interpolation, then we're going to print a %i array.
|
117
|
-
if (isSymbolArray(args)) {
|
118
|
-
const printSymbol = (symbolPath) => symbolPath.call(print, "body", 0);
|
119
|
-
const parts = path.map(printSymbol, "body", 0, "body");
|
120
|
-
|
121
|
-
return printArrayLiteral("%i", parts);
|
122
|
-
}
|
123
|
-
}
|
124
|
-
|
125
|
-
// If we don't have a regular args node at this point then we have a special
|
126
|
-
// array literal. In that case we're going to print out the body (which will
|
127
|
-
// return to us an array with the first one being the start of the array) and
|
128
|
-
// send that over to the printArrayLiteral function.
|
129
|
-
if (!["args", "args_add_star"].includes(args.type)) {
|
130
|
-
return path.call(
|
131
|
-
(arrayPath) =>
|
132
|
-
printArrayLiteral(
|
133
|
-
arrayLiteralStarts[arrayPath.getValue().type],
|
134
|
-
arrayPath.map(print, "body")
|
135
|
-
),
|
136
|
-
"body",
|
137
|
-
0
|
138
|
-
);
|
139
|
-
}
|
140
|
-
|
141
|
-
// Here we have a normal array of any type of object with no special literal
|
142
|
-
// types or anything.
|
143
|
-
return group(
|
144
|
-
concat([
|
145
|
-
"[",
|
146
|
-
indent(
|
147
|
-
concat([
|
148
|
-
softline,
|
149
|
-
join(concat([",", line]), path.call(print, "body", 0)),
|
150
|
-
getTrailingComma(opts) ? ifBreak(",", "") : ""
|
151
|
-
])
|
152
|
-
),
|
153
|
-
softline,
|
154
|
-
"]"
|
155
|
-
])
|
156
|
-
);
|
157
|
-
}
|
158
|
-
|
159
|
-
module.exports = {
|
160
|
-
array: printArray,
|
161
|
-
word: printArrayLiteralWord
|
162
|
-
};
|
data/src/ruby/nodes/assign.js
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
const { concat, group, indent, join, line } = require("../../prettier");
|
2
|
-
const { skipAssignIndent } = require("../../utils");
|
3
|
-
|
4
|
-
function printAssign(path, opts, print) {
|
5
|
-
const [_targetNode, valueNode] = path.getValue().body;
|
6
|
-
const [targetDoc, valueDoc] = path.map(print, "body");
|
7
|
-
|
8
|
-
let rightSideDoc = valueDoc;
|
9
|
-
|
10
|
-
// If the right side of this assignment is a multiple assignment, then we need
|
11
|
-
// to join it together with commas.
|
12
|
-
if (["mrhs_add_star", "mrhs_new_from_args"].includes(valueNode.type)) {
|
13
|
-
rightSideDoc = group(join(concat([",", line]), valueDoc));
|
14
|
-
}
|
15
|
-
|
16
|
-
if (skipAssignIndent(valueNode)) {
|
17
|
-
return group(concat([targetDoc, " = ", rightSideDoc]));
|
18
|
-
}
|
19
|
-
|
20
|
-
return group(concat([targetDoc, " =", indent(concat([line, rightSideDoc]))]));
|
21
|
-
}
|
22
|
-
|
23
|
-
function printOpAssign(path, opts, print) {
|
24
|
-
return group(
|
25
|
-
concat([
|
26
|
-
path.call(print, "body", 0),
|
27
|
-
" ",
|
28
|
-
path.call(print, "body", 1),
|
29
|
-
indent(concat([line, path.call(print, "body", 2)]))
|
30
|
-
])
|
31
|
-
);
|
32
|
-
}
|
33
|
-
|
34
|
-
function printVarField(path, opts, print) {
|
35
|
-
return path.getValue().body ? path.call(print, "body", 0) : "";
|
36
|
-
}
|
37
|
-
|
38
|
-
function printVarRef(path, opts, print) {
|
39
|
-
return path.call(print, "body", 0);
|
40
|
-
}
|
41
|
-
|
42
|
-
module.exports = {
|
43
|
-
assign: printAssign,
|
44
|
-
opassign: printOpAssign,
|
45
|
-
var_field: printVarField,
|
46
|
-
var_ref: printVarRef
|
47
|
-
};
|