prettier 1.5.2 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +58 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +41 -12
- data/node_modules/prettier/bin-prettier.js +13848 -11589
- data/node_modules/prettier/doc.js +4961 -0
- data/node_modules/prettier/index.js +19466 -16783
- data/node_modules/prettier/package.json +23 -0
- data/node_modules/prettier/parser-angular.js +67 -0
- data/node_modules/prettier/parser-babel.js +22 -0
- data/node_modules/prettier/parser-espree.js +22 -0
- data/node_modules/prettier/parser-flow.js +22 -0
- data/node_modules/prettier/parser-glimmer.js +1 -0
- data/node_modules/prettier/parser-graphql.js +1 -0
- data/node_modules/prettier/parser-html.js +132 -0
- data/node_modules/prettier/parser-markdown.js +34 -0
- data/node_modules/prettier/parser-meriyah.js +22 -0
- data/node_modules/prettier/parser-postcss.js +22 -0
- data/node_modules/prettier/parser-typescript.js +22 -0
- data/node_modules/prettier/parser-yaml.js +15 -0
- data/node_modules/prettier/third-party.js +1671 -864
- data/package.json +5 -5
- data/rubocop.yml +12 -0
- data/src/haml/parser.js +6 -5
- data/src/haml/parser.rb +8 -3
- data/src/haml/printer.js +428 -18
- data/src/parser/netcat.js +0 -2
- data/src/parser/parseSync.js +153 -14
- data/src/parser/server.rb +5 -0
- data/src/plugin.js +7 -1
- data/src/rbs/parser.js +3 -5
- data/src/rbs/parser.rb +7 -3
- data/src/rbs/printer.js +46 -8
- data/src/ruby/nodes/args.js +111 -19
- data/src/ruby/nodes/calls.js +50 -3
- 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 +97 -2
- data/src/ruby/parser.js +3 -5
- data/src/ruby/parser.rb +76 -31
- data/src/ruby/printer.js +10 -1
- data/src/utils/inlineEnsureParens.js +1 -0
- data/src/utils/noIndent.js +0 -1
- data/src/utils/skipAssignIndent.js +8 -1
- metadata +16 -14
- 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 -193
- data/src/parser/getLang.js +0 -32
- data/src/parser/getNetcat.js +0 -50
- data/src/parser/requestParse.js +0 -74
data/src/parser/netcat.js
CHANGED
@@ -5,11 +5,9 @@
|
|
5
5
|
const { createConnection } = require("net");
|
6
6
|
|
7
7
|
const sock = process.argv[process.argv.length - 1];
|
8
|
-
|
9
8
|
const client = createConnection(sock, () => process.stdin.pipe(client));
|
10
9
|
|
11
10
|
client.on("data", (data) => process.stdout.write(data));
|
12
|
-
|
13
11
|
client.on("error", (error) => {
|
14
12
|
console.error(error);
|
15
13
|
});
|
data/src/parser/parseSync.js
CHANGED
@@ -1,30 +1,169 @@
|
|
1
|
-
const
|
1
|
+
const { spawn, spawnSync, execSync } = require("child_process");
|
2
|
+
const { existsSync, mkdtempSync } = require("fs");
|
3
|
+
const os = require("os");
|
4
|
+
const path = require("path");
|
5
|
+
const process = require("process");
|
6
|
+
|
7
|
+
let sockfile = process.env.PRETTIER_RUBY_HOST;
|
8
|
+
let netcat;
|
9
|
+
|
10
|
+
// In order to properly parse ruby code, we need to tell the ruby process to
|
11
|
+
// parse using UTF-8. Unfortunately, the way that you accomplish this looks
|
12
|
+
// differently depending on your platform.
|
13
|
+
/* istanbul ignore next */
|
14
|
+
function getLang() {
|
15
|
+
const { env, platform } = process;
|
16
|
+
const envValue = env.LC_ALL || env.LC_CTYPE || env.LANG;
|
17
|
+
|
18
|
+
// If an env var is set for the locale that already includes UTF-8 in the
|
19
|
+
// name, then assume we can go with that.
|
20
|
+
if (envValue && envValue.includes("UTF-8")) {
|
21
|
+
return envValue;
|
22
|
+
}
|
23
|
+
|
24
|
+
// Otherwise, we're going to guess which encoding to use based on the system.
|
25
|
+
// This is probably not the best approach in the world, as you could be on
|
26
|
+
// linux and not have C.UTF-8, but in that case you're probably passing an env
|
27
|
+
// var for it. This object below represents all of the possible values of
|
28
|
+
// process.platform per:
|
29
|
+
// https://nodejs.org/api/process.html#process_process_platform
|
30
|
+
return {
|
31
|
+
aix: "C.UTF-8",
|
32
|
+
darwin: "en_US.UTF-8",
|
33
|
+
freebsd: "C.UTF-8",
|
34
|
+
linux: "C.UTF-8",
|
35
|
+
openbsd: "C.UTF-8",
|
36
|
+
sunos: "C.UTF-8",
|
37
|
+
win32: ".UTF-8"
|
38
|
+
}[platform];
|
39
|
+
}
|
40
|
+
|
41
|
+
// Spawn the parser.rb subprocess. We do this since booting Ruby is slow, and we
|
42
|
+
// can re-use the parser process multiple times since it is statelesss.
|
43
|
+
function spawnParseServer() {
|
44
|
+
const tmpDir = mkdtempSync(path.join(os.tmpdir(), "prettier-ruby"));
|
45
|
+
const tmpFile = path.join(tmpDir, `${process.pid}.sock`);
|
46
|
+
|
47
|
+
const server = spawn("ruby", [path.join(__dirname, "./server.rb"), tmpFile], {
|
48
|
+
env: Object.assign({}, process.env, { LANG: getLang() }),
|
49
|
+
detached: true,
|
50
|
+
stdio: "inherit"
|
51
|
+
});
|
52
|
+
|
53
|
+
process.on("exit", () => {
|
54
|
+
try {
|
55
|
+
process.kill(-server.pid);
|
56
|
+
} catch (e) {
|
57
|
+
// ignore
|
58
|
+
}
|
59
|
+
});
|
60
|
+
|
61
|
+
server.unref();
|
62
|
+
const now = new Date();
|
63
|
+
|
64
|
+
// Wait for server to go live.
|
65
|
+
while (!existsSync(tmpFile) && new Date() - now < 3000) {
|
66
|
+
execSync("sleep 0.1");
|
67
|
+
}
|
68
|
+
|
69
|
+
return tmpFile;
|
70
|
+
}
|
71
|
+
|
72
|
+
// Checks to see if an executable is available.
|
73
|
+
function hasCommand(name) {
|
74
|
+
let result;
|
75
|
+
|
76
|
+
if (os.type() === "Windows_NT") {
|
77
|
+
result = spawnSync("where", [name]);
|
78
|
+
} else {
|
79
|
+
result = spawnSync("command", ["-v", name]);
|
80
|
+
}
|
81
|
+
|
82
|
+
return result.status === 0;
|
83
|
+
}
|
84
|
+
|
85
|
+
// Finds a netcat-like adapter to use for sending data to a socket. We order
|
86
|
+
// these by likelihood of being found so we can avoid some shell-outs.
|
87
|
+
function findNetcat(opts) {
|
88
|
+
if (opts.rubyNetcatCommand) {
|
89
|
+
const splits = opts.rubyNetcatCommand.split(" ");
|
90
|
+
return { command: splits[0], args: splits.slice(1) };
|
91
|
+
}
|
92
|
+
|
93
|
+
if (hasCommand("nc")) {
|
94
|
+
return { command: "nc", args: ["-U"] };
|
95
|
+
}
|
96
|
+
|
97
|
+
if (hasCommand("telnet")) {
|
98
|
+
return { command: "telnet", args: ["-u"] };
|
99
|
+
}
|
100
|
+
|
101
|
+
if (hasCommand("ncat")) {
|
102
|
+
return { command: "ncat", args: ["-U"] };
|
103
|
+
}
|
104
|
+
|
105
|
+
if (hasCommand("socat")) {
|
106
|
+
return { command: "socat", args: ["-"] };
|
107
|
+
}
|
108
|
+
|
109
|
+
return { command: "node", args: [require.resolve("./netcat.js")] };
|
110
|
+
}
|
2
111
|
|
3
112
|
// Formats and sends a request to the parser server. We use netcat (or something
|
4
113
|
// like it) here since Prettier requires the results of `parse` to be
|
5
114
|
// synchronous and Node.js does not offer a mechanism for synchronous socket
|
6
115
|
// requests.
|
7
|
-
function parseSync(parser, source) {
|
8
|
-
|
116
|
+
function parseSync(parser, source, opts) {
|
117
|
+
if (!sockfile) {
|
118
|
+
sockfile = spawnParseServer();
|
119
|
+
}
|
120
|
+
|
121
|
+
if (!netcat) {
|
122
|
+
netcat = findNetcat(opts);
|
123
|
+
}
|
9
124
|
|
125
|
+
const response = spawnSync(netcat.command, netcat.args.concat(sockfile), {
|
126
|
+
input: `${parser}|${source}`,
|
127
|
+
maxBuffer: 15 * 1024 * 1024
|
128
|
+
});
|
129
|
+
|
130
|
+
const stdout = response.stdout.toString();
|
131
|
+
const stderr = response.stderr.toString();
|
132
|
+
const { status } = response;
|
133
|
+
|
134
|
+
// We need special handling in case the user's version of nc doesn't support
|
135
|
+
// using unix sockets.
|
10
136
|
if (
|
11
|
-
|
12
|
-
(
|
137
|
+
stderr.includes("invalid option -- U") ||
|
138
|
+
stderr.includes("invalid option -- 'u'") ||
|
139
|
+
stderr.includes("Protocol not supported")
|
13
140
|
) {
|
14
|
-
|
15
|
-
|
141
|
+
throw new Error(`
|
142
|
+
@prettier/plugin-ruby uses unix sockets to communicate between the node.js
|
143
|
+
process running prettier and an underlying Ruby process used for parsing.
|
144
|
+
Unfortunately the command that it tried to use to do that
|
145
|
+
(${netcat.command}) does not support unix sockets. To solve this either
|
146
|
+
uninstall the version of ${netcat.command} that you're using and use a
|
147
|
+
different implementation, or change the value of the rubyNetcatCommand
|
148
|
+
option in your prettier configuration.
|
149
|
+
`);
|
150
|
+
}
|
16
151
|
|
17
|
-
|
152
|
+
// If we didn't receive anything over stdout or we have a bad exit status,
|
153
|
+
// then throw whatever we can.
|
154
|
+
if (stdout.length === 0 || (status !== null && status !== 0)) {
|
155
|
+
throw new Error(stderr || "An unknown error occurred");
|
18
156
|
}
|
19
157
|
|
20
|
-
const parsed = JSON.parse(
|
158
|
+
const parsed = JSON.parse(stdout);
|
21
159
|
|
22
160
|
if (parsed.error) {
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
161
|
+
const error = new Error(parsed.error);
|
162
|
+
if (parsed.loc) {
|
163
|
+
error.loc = parsed.loc;
|
164
|
+
}
|
165
|
+
|
166
|
+
throw error;
|
28
167
|
}
|
29
168
|
|
30
169
|
return parsed;
|
data/src/parser/server.rb
CHANGED
@@ -48,6 +48,11 @@ loop do
|
|
48
48
|
else
|
49
49
|
socket.write('{ "error": true }')
|
50
50
|
end
|
51
|
+
rescue Prettier::Parser::ParserError => error
|
52
|
+
loc = { start: { line: error.lineno, column: error.column } }
|
53
|
+
socket.write(JSON.fast_generate(error: error.message, loc: loc))
|
54
|
+
rescue StandardError => error
|
55
|
+
socket.write(JSON.fast_generate(error: error.message))
|
51
56
|
ensure
|
52
57
|
socket.close
|
53
58
|
end
|
data/src/plugin.js
CHANGED
@@ -10,7 +10,7 @@ const hamlParser = require("./haml/parser");
|
|
10
10
|
/*
|
11
11
|
* metadata mostly pulled from linguist and rubocop:
|
12
12
|
* https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
|
13
|
-
* https://github.com/rubocop
|
13
|
+
* https://github.com/rubocop/rubocop/blob/master/spec/rubocop/target_finder_spec.rb
|
14
14
|
*/
|
15
15
|
|
16
16
|
module.exports = {
|
@@ -119,6 +119,12 @@ module.exports = {
|
|
119
119
|
description:
|
120
120
|
"When it fits on one line, allows if, unless, while, and until statements to use the modifier form."
|
121
121
|
},
|
122
|
+
rubyNetcatCommand: {
|
123
|
+
type: "string",
|
124
|
+
category: "Ruby",
|
125
|
+
description:
|
126
|
+
'The prefix of the command to execute to communicate between the node.js process and the Ruby process. (For example, "nc -U" or "telnet -u") Normally you should not set this option.'
|
127
|
+
},
|
122
128
|
rubySingleQuote: {
|
123
129
|
type: "boolean",
|
124
130
|
category: "Ruby",
|
data/src/rbs/parser.js
CHANGED
@@ -4,16 +4,14 @@ const parseSync = require("../parser/parseSync");
|
|
4
4
|
// to prettier a JavaScript object that is the equivalent AST that represents
|
5
5
|
// the code stored in that string. We accomplish this by spawning a new Ruby
|
6
6
|
// process of parser.rb and reading JSON off STDOUT.
|
7
|
-
function parse(text, _parsers,
|
8
|
-
return parseSync("rbs", text);
|
7
|
+
function parse(text, _parsers, opts) {
|
8
|
+
return parseSync("rbs", text, opts);
|
9
9
|
}
|
10
10
|
|
11
|
-
const pragmaPattern = /#\s*@(prettier|format)/;
|
12
|
-
|
13
11
|
// This function handles checking whether or not the source string has the
|
14
12
|
// pragma for prettier. This is an optional workflow for incremental adoption.
|
15
13
|
function hasPragma(text) {
|
16
|
-
return
|
14
|
+
return /^\s*#[^\S\n]*@(format|prettier)\s*(\n|$)/.test(text);
|
17
15
|
}
|
18
16
|
|
19
17
|
// This function is critical for comments and cursor support, and is responsible
|
data/src/rbs/parser.rb
CHANGED
@@ -86,9 +86,13 @@ end
|
|
86
86
|
module Prettier
|
87
87
|
class RBSParser
|
88
88
|
def self.parse(text)
|
89
|
-
{
|
90
|
-
|
91
|
-
|
89
|
+
{
|
90
|
+
declarations: RBS::Parser.parse_signature(text),
|
91
|
+
location: {
|
92
|
+
start_pos: 0,
|
93
|
+
end_pos: text.length
|
94
|
+
}
|
95
|
+
}
|
92
96
|
end
|
93
97
|
end
|
94
98
|
end
|
data/src/rbs/printer.js
CHANGED
@@ -147,7 +147,7 @@ function printNode(path, opts, print) {
|
|
147
147
|
|
148
148
|
// This is the big function that prints out any individual type, which can
|
149
149
|
// look like all kinds of things, listed in the case statement below.
|
150
|
-
function printType(path) {
|
150
|
+
function printType(path, { forceParens = false } = {}) {
|
151
151
|
const node = path.getValue();
|
152
152
|
|
153
153
|
switch (node.class) {
|
@@ -157,7 +157,13 @@ function printNode(path, opts, print) {
|
|
157
157
|
}
|
158
158
|
return node.literal;
|
159
159
|
case "optional":
|
160
|
-
return concat([
|
160
|
+
return concat([
|
161
|
+
path.call(
|
162
|
+
(typePath) => printType(typePath, { forceParens: true }),
|
163
|
+
"type"
|
164
|
+
),
|
165
|
+
"?"
|
166
|
+
]);
|
161
167
|
case "tuple":
|
162
168
|
// If we don't have any sub types, we explicitly need the space in between
|
163
169
|
// the brackets to not confuse the parser.
|
@@ -173,11 +179,29 @@ function printNode(path, opts, print) {
|
|
173
179
|
join(concat([line, "| "]), path.map(printType, "types"))
|
174
180
|
);
|
175
181
|
|
176
|
-
|
177
|
-
|
182
|
+
if (forceParens) {
|
183
|
+
return concat(["(", doc, ")"]);
|
184
|
+
}
|
185
|
+
|
186
|
+
return doc;
|
187
|
+
}
|
188
|
+
case "intersection": {
|
189
|
+
const doc = group(
|
190
|
+
join(
|
191
|
+
concat([line, "& "]),
|
192
|
+
path.map(
|
193
|
+
(typePath) => printType(typePath, { forceParens: true }),
|
194
|
+
"types"
|
195
|
+
)
|
196
|
+
)
|
197
|
+
);
|
198
|
+
|
199
|
+
if (forceParens) {
|
200
|
+
return concat(["(", doc, ")"]);
|
201
|
+
}
|
202
|
+
|
203
|
+
return doc;
|
178
204
|
}
|
179
|
-
case "intersection":
|
180
|
-
return group(join(concat([line, "& "]), path.map(printType, "types")));
|
181
205
|
case "class_singleton":
|
182
206
|
return concat(["singleton(", node.name, ")"]);
|
183
207
|
case "proc":
|
@@ -515,7 +539,14 @@ function printNode(path, opts, print) {
|
|
515
539
|
);
|
516
540
|
}
|
517
541
|
|
518
|
-
parts.push(
|
542
|
+
parts.push(
|
543
|
+
"-> ",
|
544
|
+
path.call(
|
545
|
+
(typePath) => printType(typePath, { forceParens: true }),
|
546
|
+
"type",
|
547
|
+
"return_type"
|
548
|
+
)
|
549
|
+
);
|
519
550
|
|
520
551
|
return group(concat(parts));
|
521
552
|
}
|
@@ -599,7 +630,14 @@ function hasPrettierIgnore(path) {
|
|
599
630
|
return node.comment && node.comment.string.includes("prettier-ignore");
|
600
631
|
}
|
601
632
|
|
633
|
+
// This function handles adding the format pragma to a source string. This is an
|
634
|
+
// optional workflow for incremental adoption.
|
635
|
+
function insertPragma(text) {
|
636
|
+
return `# @format\n${text}`;
|
637
|
+
}
|
638
|
+
|
602
639
|
module.exports = {
|
603
640
|
print: printNode,
|
604
|
-
hasPrettierIgnore
|
641
|
+
hasPrettierIgnore,
|
642
|
+
insertPragma
|
605
643
|
};
|
data/src/ruby/nodes/args.js
CHANGED
@@ -58,7 +58,7 @@ function printArgParen(path, opts, print) {
|
|
58
58
|
concat([
|
59
59
|
softline,
|
60
60
|
join(concat([",", line]), path.call(print, "body", 0)),
|
61
|
-
getTrailingComma(opts)
|
61
|
+
getTrailingComma(opts) ? getArgParenTrailingComma(argsNode) : ""
|
62
62
|
])
|
63
63
|
),
|
64
64
|
softline,
|
@@ -106,25 +106,117 @@ function printArgs(path, { rubyToProc }, print) {
|
|
106
106
|
return args;
|
107
107
|
}
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
+
}
|
114
175
|
|
115
|
-
|
116
|
-
|
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;
|
117
181
|
}
|
118
182
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
130
222
|
};
|