prettier 1.5.5 → 2.0.0.pre.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +344 -282
  3. data/CONTRIBUTING.md +8 -11
  4. data/LICENSE +1 -1
  5. data/README.md +30 -12
  6. data/dist/haml/embed.js +53 -0
  7. data/dist/haml/parser.js +31 -0
  8. data/{src → dist}/haml/parser.rb +0 -0
  9. data/dist/haml/printer.js +336 -0
  10. data/dist/parser/getInfo.js +17 -0
  11. data/{src → dist}/parser/netcat.js +1 -0
  12. data/dist/parser/parseSync.js +142 -0
  13. data/dist/parser/server.rb +140 -0
  14. data/dist/plugin.js +143 -0
  15. data/dist/prettier.js +15 -0
  16. data/dist/rbs/parser.js +34 -0
  17. data/{src → dist}/rbs/parser.rb +0 -0
  18. data/dist/rbs/printer.js +517 -0
  19. data/dist/ruby/embed.js +110 -0
  20. data/dist/ruby/nodes/alias.js +59 -0
  21. data/{src → dist}/ruby/nodes/aref.js +26 -35
  22. data/dist/ruby/nodes/args.js +165 -0
  23. data/dist/ruby/nodes/arrays.js +126 -0
  24. data/dist/ruby/nodes/assign.js +41 -0
  25. data/dist/ruby/nodes/blocks.js +68 -0
  26. data/dist/ruby/nodes/calls.js +260 -0
  27. data/dist/ruby/nodes/case.js +50 -0
  28. data/dist/ruby/nodes/class.js +54 -0
  29. data/dist/ruby/nodes/commands.js +124 -0
  30. data/dist/ruby/nodes/conditionals.js +242 -0
  31. data/dist/ruby/nodes/constants.js +38 -0
  32. data/dist/ruby/nodes/flow.js +66 -0
  33. data/dist/ruby/nodes/hashes.js +130 -0
  34. data/dist/ruby/nodes/heredocs.js +30 -0
  35. data/dist/ruby/nodes/hooks.js +35 -0
  36. data/dist/ruby/nodes/ints.js +27 -0
  37. data/dist/ruby/nodes/lambdas.js +69 -0
  38. data/dist/ruby/nodes/loops.js +73 -0
  39. data/dist/ruby/nodes/massign.js +73 -0
  40. data/dist/ruby/nodes/methods.js +70 -0
  41. data/dist/ruby/nodes/operators.js +70 -0
  42. data/dist/ruby/nodes/params.js +89 -0
  43. data/dist/ruby/nodes/patterns.js +109 -0
  44. data/dist/ruby/nodes/regexp.js +45 -0
  45. data/dist/ruby/nodes/rescue.js +82 -0
  46. data/dist/ruby/nodes/return.js +75 -0
  47. data/dist/ruby/nodes/statements.js +111 -0
  48. data/dist/ruby/nodes/strings.js +218 -0
  49. data/dist/ruby/nodes/super.js +30 -0
  50. data/dist/ruby/nodes/undef.js +26 -0
  51. data/dist/ruby/nodes.js +151 -0
  52. data/dist/ruby/parser.js +34 -0
  53. data/{src → dist}/ruby/parser.rb +1274 -288
  54. data/dist/ruby/printer.js +125 -0
  55. data/dist/ruby/toProc.js +93 -0
  56. data/dist/types/haml.js +4 -0
  57. data/dist/types/plugin.js +3 -0
  58. data/dist/types/rbs.js +4 -0
  59. data/dist/types/ruby.js +4 -0
  60. data/dist/types/utils.js +2 -0
  61. data/dist/types.js +30 -0
  62. data/dist/utils/containsAssignment.js +15 -0
  63. data/dist/utils/getTrailingComma.js +6 -0
  64. data/dist/utils/hasAncestor.js +15 -0
  65. data/{src → dist}/utils/inlineEnsureParens.js +16 -16
  66. data/dist/utils/isEmptyBodyStmt.js +10 -0
  67. data/dist/utils/isEmptyStmts.js +10 -0
  68. data/dist/utils/literal.js +8 -0
  69. data/dist/utils/literallineWithoutBreakParent.js +8 -0
  70. data/dist/utils/makeCall.js +13 -0
  71. data/dist/utils/noIndent.js +11 -0
  72. data/dist/utils/printEmptyCollection.js +44 -0
  73. data/dist/utils/skipAssignIndent.js +15 -0
  74. data/dist/utils.js +30 -0
  75. data/node_modules/prettier/bin-prettier.js +13343 -10961
  76. data/node_modules/prettier/doc.js +4829 -0
  77. data/node_modules/prettier/index.js +23988 -22229
  78. data/node_modules/prettier/package.json +23 -0
  79. data/node_modules/prettier/parser-angular.js +60 -40
  80. data/node_modules/prettier/parser-babel.js +22 -1
  81. data/node_modules/prettier/parser-espree.js +22 -1
  82. data/node_modules/prettier/parser-flow.js +22 -1
  83. data/node_modules/prettier/parser-glimmer.js +1 -1
  84. data/node_modules/prettier/parser-graphql.js +1 -1
  85. data/node_modules/prettier/parser-html.js +82 -63
  86. data/node_modules/prettier/parser-markdown.js +24 -9
  87. data/node_modules/prettier/parser-meriyah.js +22 -1
  88. data/node_modules/prettier/parser-postcss.js +22 -1
  89. data/node_modules/prettier/parser-typescript.js +22 -1
  90. data/node_modules/prettier/parser-yaml.js +2 -2
  91. data/node_modules/prettier/third-party.js +1734 -862
  92. data/package.json +27 -19
  93. data/rubocop.yml +9 -0
  94. metadata +77 -77
  95. data/src/haml/embed.js +0 -87
  96. data/src/haml/nodes/comment.js +0 -27
  97. data/src/haml/nodes/doctype.js +0 -34
  98. data/src/haml/nodes/filter.js +0 -16
  99. data/src/haml/nodes/hamlComment.js +0 -21
  100. data/src/haml/nodes/plain.js +0 -6
  101. data/src/haml/nodes/root.js +0 -8
  102. data/src/haml/nodes/script.js +0 -33
  103. data/src/haml/nodes/silentScript.js +0 -59
  104. data/src/haml/nodes/tag.js +0 -232
  105. data/src/haml/parser.js +0 -22
  106. data/src/haml/printer.js +0 -28
  107. data/src/parser/parseSync.js +0 -170
  108. data/src/parser/server.rb +0 -66
  109. data/src/plugin.js +0 -148
  110. data/src/prettier.js +0 -16
  111. data/src/rbs/parser.js +0 -39
  112. data/src/rbs/printer.js +0 -615
  113. data/src/ruby/embed.js +0 -142
  114. data/src/ruby/nodes/alias.js +0 -73
  115. data/src/ruby/nodes/args.js +0 -178
  116. data/src/ruby/nodes/arrays.js +0 -162
  117. data/src/ruby/nodes/assign.js +0 -47
  118. data/src/ruby/nodes/blocks.js +0 -90
  119. data/src/ruby/nodes/calls.js +0 -199
  120. data/src/ruby/nodes/case.js +0 -65
  121. data/src/ruby/nodes/class.js +0 -64
  122. data/src/ruby/nodes/commands.js +0 -131
  123. data/src/ruby/nodes/conditionals.js +0 -280
  124. data/src/ruby/nodes/constants.js +0 -43
  125. data/src/ruby/nodes/flow.js +0 -74
  126. data/src/ruby/nodes/hashes.js +0 -164
  127. data/src/ruby/nodes/heredocs.js +0 -36
  128. data/src/ruby/nodes/hooks.js +0 -34
  129. data/src/ruby/nodes/ints.js +0 -31
  130. data/src/ruby/nodes/lambdas.js +0 -76
  131. data/src/ruby/nodes/loops.js +0 -98
  132. data/src/ruby/nodes/massign.js +0 -98
  133. data/src/ruby/nodes/methods.js +0 -74
  134. data/src/ruby/nodes/operators.js +0 -83
  135. data/src/ruby/nodes/params.js +0 -113
  136. data/src/ruby/nodes/patterns.js +0 -157
  137. data/src/ruby/nodes/regexp.js +0 -56
  138. data/src/ruby/nodes/rescue.js +0 -101
  139. data/src/ruby/nodes/return.js +0 -94
  140. data/src/ruby/nodes/statements.js +0 -142
  141. data/src/ruby/nodes/strings.js +0 -177
  142. data/src/ruby/nodes/super.js +0 -35
  143. data/src/ruby/nodes/undef.js +0 -42
  144. data/src/ruby/nodes.js +0 -34
  145. data/src/ruby/parser.js +0 -39
  146. data/src/ruby/printer.js +0 -138
  147. data/src/ruby/toProc.js +0 -105
  148. data/src/utils/containsAssignment.js +0 -11
  149. data/src/utils/getTrailingComma.js +0 -5
  150. data/src/utils/hasAncestor.js +0 -17
  151. data/src/utils/isEmptyBodyStmt.js +0 -7
  152. data/src/utils/isEmptyStmts.js +0 -11
  153. data/src/utils/literal.js +0 -7
  154. data/src/utils/literallineWithoutBreakParent.js +0 -7
  155. data/src/utils/makeCall.js +0 -14
  156. data/src/utils/noIndent.js +0 -11
  157. data/src/utils/printEmptyCollection.js +0 -49
  158. data/src/utils/skipAssignIndent.js +0 -10
  159. data/src/utils.js +0 -13
data/src/rbs/parser.js DELETED
@@ -1,39 +0,0 @@
1
- const parseSync = require("../parser/parseSync");
2
-
3
- // This function is responsible for taking an input string of text and returning
4
- // to prettier a JavaScript object that is the equivalent AST that represents
5
- // the code stored in that string. We accomplish this by spawning a new Ruby
6
- // process of parser.rb and reading JSON off STDOUT.
7
- function parse(text, _parsers, opts) {
8
- return parseSync("rbs", text, opts);
9
- }
10
-
11
- const pragmaPattern = /#\s*@(prettier|format)/;
12
-
13
- // This function handles checking whether or not the source string has the
14
- // pragma for prettier. This is an optional workflow for incremental adoption.
15
- function hasPragma(text) {
16
- return pragmaPattern.test(text);
17
- }
18
-
19
- // This function is critical for comments and cursor support, and is responsible
20
- // for returning the index of the character within the source string that is the
21
- // beginning of the given node.
22
- function locStart(node) {
23
- return (node.location || node.type.location).start_pos;
24
- }
25
-
26
- // This function is critical for comments and cursor support, and is responsible
27
- // for returning the index of the character within the source string that is the
28
- // ending of the given node.
29
- function locEnd(node) {
30
- return (node.location || node.type.location).end_pos;
31
- }
32
-
33
- module.exports = {
34
- parse,
35
- astFormat: "rbs",
36
- hasPragma,
37
- locStart,
38
- locEnd
39
- };
data/src/rbs/printer.js DELETED
@@ -1,615 +0,0 @@
1
- const {
2
- concat,
3
- group,
4
- hardline,
5
- indent,
6
- makeString,
7
- join,
8
- line,
9
- softline
10
- } = require("../prettier");
11
-
12
- // For some lists of entities in the AST, the parser returns them as an unsorted
13
- // object (presumably because Ruby hashes have implicit ordering). We do not
14
- // have that in JavaScript, so here we sort each object by its position in the
15
- // source string.
16
- function getSortedKeys(object) {
17
- return Object.keys(object).sort(
18
- (left, right) =>
19
- object[left].type.location.start_pos -
20
- object[right].type.location.start_pos
21
- );
22
- }
23
-
24
- // In some cases, we want to just defer to whatever was in the source.
25
- function getSource(node, opts) {
26
- return opts.originalText.slice(
27
- node.location.start_pos,
28
- node.location.end_pos
29
- );
30
- }
31
-
32
- // This is the generic node print function, used to convert any node in the AST
33
- // into its equivalent Doc representation.
34
- function printNode(path, opts, print) {
35
- const node = path.getValue();
36
- let doc = null;
37
-
38
- if (node.declarations) {
39
- return printRoot();
40
- }
41
-
42
- /* istanbul ignore else */
43
- if (node.declaration) {
44
- switch (node.declaration) {
45
- case "alias":
46
- doc = printTypeAlias();
47
- break;
48
- case "class":
49
- doc = printClass();
50
- break;
51
- case "constant":
52
- case "global":
53
- doc = printConstant();
54
- break;
55
- case "interface":
56
- doc = printInterface();
57
- break;
58
- case "module":
59
- doc = printModule();
60
- break;
61
- /* istanbul ignore next */
62
- default:
63
- throw new Error(`unknown declaration: ${node.declaration}`);
64
- }
65
- } else if (node.member) {
66
- switch (node.member) {
67
- case "alias":
68
- doc = printAlias();
69
- break;
70
- case "attr_accessor":
71
- case "attr_reader":
72
- case "attr_writer":
73
- doc = printAttr();
74
- break;
75
- case "class_variable":
76
- case "instance_variable":
77
- doc = printVariable();
78
- break;
79
- case "class_instance_variable":
80
- doc = concat(["self.", printVariable()]);
81
- break;
82
- case "include":
83
- case "extend":
84
- case "prepend":
85
- doc = printMixin();
86
- break;
87
- case "public":
88
- case "private":
89
- doc = node.member;
90
- break;
91
- case "method_definition":
92
- doc = printMethodDefinition();
93
- break;
94
- /* istanbul ignore next */
95
- default:
96
- throw new Error(`unknown member: ${node.member}`);
97
- }
98
- } else {
99
- const ast = JSON.stringify(node, null, 2);
100
- throw new Error(`Unsupported node encountered:\n${ast}`);
101
- }
102
-
103
- // Certain nodes can't have annotations at all
104
- if (node.annotations && node.annotations.length > 0) {
105
- doc = concat([printAnnotations(), hardline, doc]);
106
- }
107
-
108
- if (node.comment) {
109
- doc = concat([printComment(), hardline, doc]);
110
- }
111
-
112
- return doc;
113
-
114
- // Prints out a string in the source, which looks like:
115
- // 'foo'
116
- function printString(node) {
117
- // We're going to go straight to the source here, as if we don't then we're
118
- // going to end up with the result of String#inspect, which does weird
119
- // things to escape sequences.
120
- const value = getSource(node, opts);
121
-
122
- // Get the quote that was used in the source and the quote that we want to
123
- // be using.
124
- const originalQuote = value[0];
125
- const preferredQuote = opts.rubySingleQuote ? "'" : '"';
126
-
127
- // Determine if we're allowed to change the quote based on whether or not
128
- // there is an escape sequence in the source string.
129
- const quote = node.literal.includes("\\") ? originalQuote : preferredQuote;
130
-
131
- return makeString(value.slice(1, -1), quote, false);
132
- }
133
-
134
- // Certain nodes are names with optional arguments attached, as in Array[A].
135
- // We handle all of that printing centralized here.
136
- function printNameAndArgs(path) {
137
- const node = path.getValue();
138
-
139
- if (node.args.length === 0) {
140
- return node.name;
141
- }
142
-
143
- return group(
144
- concat([node.name, "[", join(", ", path.map(printType, "args")), "]"])
145
- );
146
- }
147
-
148
- // This is the big function that prints out any individual type, which can
149
- // look like all kinds of things, listed in the case statement below.
150
- function printType(path, { forceUnionParens = false } = {}) {
151
- const node = path.getValue();
152
-
153
- switch (node.class) {
154
- case "literal":
155
- if (node.literal[0] === '"') {
156
- return printString(node);
157
- }
158
- return node.literal;
159
- case "optional":
160
- return concat([path.call(printType, "type"), "?"]);
161
- case "tuple":
162
- // If we don't have any sub types, we explicitly need the space in between
163
- // the brackets to not confuse the parser.
164
- if (node.types.length === 0) {
165
- return "[ ]";
166
- }
167
-
168
- return group(
169
- concat(["[", join(", ", path.map(printType, "types")), "]"])
170
- );
171
- case "union": {
172
- const doc = group(
173
- join(concat([line, "| "]), path.map(printType, "types"))
174
- );
175
-
176
- if (forceUnionParens || path.getParentNode().class === "intersection") {
177
- return concat(["(", doc, ")"]);
178
- }
179
-
180
- return doc;
181
- }
182
- case "intersection":
183
- return group(join(concat([line, "& "]), path.map(printType, "types")));
184
- case "class_singleton":
185
- return concat(["singleton(", node.name, ")"]);
186
- case "proc":
187
- return concat(["^", printMethodSignature(path)]);
188
- case "record": {
189
- const parts = [];
190
-
191
- getSortedKeys(node.fields).forEach((field) => {
192
- const fieldParts = [];
193
-
194
- if (node.fields[field].joiner === "rocket") {
195
- fieldParts.push(`${field} => `);
196
- } else {
197
- fieldParts.push(`${field}: `);
198
- }
199
-
200
- fieldParts.push(path.call(printType, "fields", field, "type"));
201
- parts.push(concat(fieldParts));
202
- });
203
-
204
- return group(
205
- concat([
206
- "{",
207
- indent(concat([line, join(concat([",", line]), parts)])),
208
- line,
209
- "}"
210
- ])
211
- );
212
- }
213
- case "class_instance":
214
- case "interface":
215
- return printNameAndArgs(path);
216
- case "alias":
217
- case "variable":
218
- return node.name;
219
- case "bool":
220
- case "bot":
221
- case "class":
222
- case "instance":
223
- case "nil":
224
- case "self":
225
- case "top":
226
- case "untyped":
227
- case "void":
228
- return node.class;
229
- /* istanbul ignore next */
230
- default:
231
- throw new Error(`unknown type: ${node.class}`);
232
- }
233
- }
234
-
235
- // Prints out the root of the tree, which includes zero or more declarations.
236
- function printRoot() {
237
- return concat([
238
- join(concat([hardline, hardline]), path.map(print, "declarations")),
239
- hardline
240
- ]);
241
- }
242
-
243
- // Prints out the members of a class, module, or interface.
244
- function printMembers() {
245
- let lastLine = null;
246
- const docs = [];
247
-
248
- path.each((memberPath) => {
249
- const memberNode = memberPath.getValue();
250
-
251
- if (lastLine !== null && memberNode.location.start.line - lastLine >= 2) {
252
- docs.push(concat([hardline, hardline]));
253
- } else {
254
- docs.push(hardline);
255
- }
256
-
257
- docs.push(print(memberPath));
258
- lastLine = memberNode.location.end.line;
259
- }, "members");
260
-
261
- return concat(docs);
262
- }
263
-
264
- // Prints out a type alias, which is a declaration that looks like:
265
- // type foo = String
266
- function printTypeAlias() {
267
- return group(
268
- concat([
269
- "type ",
270
- node.name,
271
- " =",
272
- indent(group(concat([line, path.call(printType, "type")])))
273
- ])
274
- );
275
- }
276
-
277
- // Prints out the name of a class, interface, or module declaration.
278
- // Additionally loops through each type parameter if there are any and print
279
- // them out joined by commas. Checks for validation and variance.
280
- function printNameAndTypeParams() {
281
- if (node.type_params.params.length === 0) {
282
- return node.name;
283
- }
284
-
285
- const docs = path.map(
286
- (paramPath) => {
287
- const node = paramPath.getValue();
288
- const parts = [];
289
-
290
- if (node.skip_validation) {
291
- parts.push("unchecked");
292
- }
293
-
294
- if (node.variance === "covariant") {
295
- parts.push("out");
296
- } else if (node.variance === "contravariant") {
297
- parts.push("in");
298
- }
299
-
300
- return join(" ", parts.concat(node.name));
301
- },
302
- "type_params",
303
- "params"
304
- );
305
-
306
- return concat([node.name, "[", join(", ", docs), "]"]);
307
- }
308
-
309
- // Prints out a class declarations, which looks like:
310
- // class Foo end
311
- function printClass() {
312
- const parts = ["class ", printNameAndTypeParams()];
313
-
314
- if (node.super_class) {
315
- parts.push(" < ", path.call(printNameAndArgs, "super_class"));
316
- }
317
-
318
- parts.push(indent(printMembers()), hardline, "end");
319
-
320
- return group(concat(parts));
321
- }
322
-
323
- // Prints out a constant or a global declaration, which looks like:
324
- // Foo: String
325
- // $foo: String
326
- function printConstant() {
327
- return group(concat([node.name, ": ", path.call(printType, "type")]));
328
- }
329
-
330
- // Prints out an interface declaration, which looks like:
331
- // interface _Foo end
332
- function printInterface() {
333
- return group(
334
- concat([
335
- "interface ",
336
- printNameAndTypeParams(),
337
- indent(printMembers()),
338
- hardline,
339
- "end"
340
- ])
341
- );
342
- }
343
-
344
- // Prints out a module declaration, which looks like:
345
- // module Foo end
346
- function printModule() {
347
- const parts = ["module ", printNameAndTypeParams()];
348
-
349
- if (node.self_types.length > 0) {
350
- parts.push(" : ", join(", ", path.map(printNameAndArgs, "self_types")));
351
- }
352
-
353
- parts.push(indent(printMembers()), hardline, "end");
354
-
355
- return group(concat(parts));
356
- }
357
-
358
- // Prints out an alias within a declaration, which looks like:
359
- // alias foo bar
360
- // alias self.foo self.bar
361
- function printAlias() {
362
- if (node.kind === "singleton") {
363
- return concat(["alias self.", node.new_name, " self.", node.old_name]);
364
- }
365
-
366
- return concat(["alias ", node.new_name, " ", node.old_name]);
367
- }
368
-
369
- // Prints out an attr_* meta method, which looks like:
370
- // attr_accessor foo
371
- // attr_reader self.foo()
372
- // attr_writer self.foo(@bar): String
373
- function printAttr() {
374
- const parts = [node.member, " "];
375
-
376
- if (node.kind === "singleton") {
377
- parts.push("self.");
378
- }
379
-
380
- parts.push(node.name);
381
-
382
- if (node.ivar_name === false) {
383
- parts.push("()");
384
- } else if (node.ivar_name) {
385
- parts.push("(", node.ivar_name, ")");
386
- }
387
-
388
- parts.push(": ", path.call(printType, "type"));
389
-
390
- return group(concat(parts));
391
- }
392
-
393
- // Prints out a variable member, which looks like:
394
- // @foo: String
395
- // self.@foo: String
396
- // @@foo: String
397
- function printVariable() {
398
- return group(concat([node.name, ": ", path.call(printType, "type")]));
399
- }
400
-
401
- // Prints out a mixin, which looks like:
402
- // include Foo
403
- // prepend Foo
404
- // extend Foo
405
- function printMixin() {
406
- return group(concat([node.member, " ", printNameAndArgs(path)]));
407
- }
408
-
409
- // Returns an array of printed parameters so that the calling function can
410
- // join them together in whatever way.
411
- function printMethodParams(path) {
412
- const node = path.getValue();
413
- let parts = [];
414
-
415
- // required positionals, as in (A)
416
- parts = parts.concat(path.map(printMethodParam, "required_positionals"));
417
-
418
- // optional positionals, as in (?A)
419
- parts = parts.concat(
420
- path.map(
421
- (paramPath) => concat(["?", printMethodParam(paramPath)]),
422
- "optional_positionals"
423
- )
424
- );
425
-
426
- // rest positional, as in (*A)
427
- if (node.rest_positionals) {
428
- parts.push(
429
- concat(["*", path.call(printMethodParam, "rest_positionals")])
430
- );
431
- }
432
-
433
- // trailing positionals are required positionals after a rest
434
- parts = parts.concat(path.map(printMethodParam, "trailing_positionals"));
435
-
436
- // required keywords, as in (a: A)
437
- getSortedKeys(node.required_keywords).forEach((name) => {
438
- parts.push(
439
- concat([
440
- name,
441
- ": ",
442
- path.call(printMethodParam, "required_keywords", name)
443
- ])
444
- );
445
- });
446
-
447
- // optional keywords, as in (?a: A)
448
- getSortedKeys(node.optional_keywords).forEach((name) => {
449
- parts.push(
450
- concat([
451
- "?",
452
- name,
453
- ": ",
454
- path.call(printMethodParam, "optional_keywords", name)
455
- ])
456
- );
457
- });
458
-
459
- // rest keyword, as in (**A)
460
- if (node.rest_keywords) {
461
- parts.push(concat(["**", path.call(printMethodParam, "rest_keywords")]));
462
- }
463
-
464
- return parts;
465
-
466
- // Prints out a method parameter at a given path. Handles printing out the
467
- // name if there is one (and whether or not it's escaped).
468
- function printMethodParam(path) {
469
- const node = path.getValue();
470
- const parts = [path.call(printType, "type")];
471
-
472
- if (node.name) {
473
- parts.push(" ");
474
-
475
- if (node.escaped) {
476
- parts.push("`", node.name, "`");
477
- } else {
478
- parts.push(node.name);
479
- }
480
- }
481
-
482
- return concat(parts);
483
- }
484
- }
485
-
486
- // Prints out a specific method signature, which looks like:
487
- // (T t) -> void
488
- function printMethodSignature(path) {
489
- const node = path.getValue();
490
- const parts = [];
491
-
492
- // We won't have a type_params key if we're printing a block
493
- if (node.type_params && node.type_params.length > 0) {
494
- parts.push("[", join(", ", node.type_params), "] ");
495
- }
496
-
497
- let params = path.call(printMethodParams, "type");
498
-
499
- if (params.length > 0) {
500
- parts.push(
501
- "(",
502
- indent(concat([softline, join(concat([",", line]), params)])),
503
- softline,
504
- ") "
505
- );
506
- }
507
-
508
- if (node.block) {
509
- if (!node.block.required) {
510
- parts.push("?");
511
- }
512
-
513
- parts.push(
514
- "{",
515
- indent(concat([line, path.call(printMethodSignature, "block")])),
516
- line,
517
- "} "
518
- );
519
- }
520
-
521
- parts.push(
522
- "-> ",
523
- path.call(
524
- (typePath) => printType(typePath, { forceUnionParens: true }),
525
- "type",
526
- "return_type"
527
- )
528
- );
529
-
530
- return group(concat(parts));
531
- }
532
-
533
- // Prints out a method definition, which looks like:
534
- // def t: (T t) -> void
535
- function printMethodDefinition() {
536
- let typeDocs = path.map(printMethodSignature, "types");
537
-
538
- if (node.overload) {
539
- typeDocs.push("...");
540
- }
541
-
542
- if (typeDocs.length === 1) {
543
- typeDocs = concat([" ", typeDocs[0]]);
544
- } else {
545
- typeDocs = indent(
546
- group(concat([line, join(concat([line, "| "]), typeDocs)]))
547
- );
548
- }
549
-
550
- const parts = ["def "];
551
-
552
- if (node.kind === "singleton") {
553
- parts.push("self.");
554
- } else if (node.kind === "singleton_instance") {
555
- parts.push("self?.");
556
- }
557
-
558
- const escaped = isMethodNameEscaped();
559
- parts.push(escaped ? `\`${node.name}\`` : node.name, ":", typeDocs);
560
-
561
- return group(concat(parts));
562
-
563
- // Determine if a method name is escaped in the original source.
564
- function isMethodNameEscaped() {
565
- const pos = node.location.start_pos + 4;
566
- const name = opts.originalText.slice(pos, pos + 2).trimStart();
567
-
568
- return name[0] === "`" && name[1] !== ":";
569
- }
570
- }
571
-
572
- // An annotation can be attached to most kinds of nodes, and should be printed
573
- // using %a{}.
574
- function printAnnotations() {
575
- return join(hardline, path.map(printAnnotation, "annotations"));
576
-
577
- function printAnnotation(path) {
578
- const node = path.getValue();
579
-
580
- // If there are already braces inside the annotation, then we're just
581
- // going to print out the original string to avoid having to escape
582
- // anything.
583
- if (/[{}]/.test(node.string)) {
584
- return getSource(node, opts);
585
- }
586
-
587
- return concat(["%a{", node.string, "}"]);
588
- }
589
- }
590
-
591
- // Comments come in as one whole string, so here we split it up into multiple
592
- // lines and then prefix it with the pound sign.
593
- function printComment() {
594
- const lines = node.comment.string.slice(0, -1).split("\n");
595
-
596
- return join(
597
- hardline,
598
- lines.map((segment) => `# ${segment}`)
599
- );
600
- }
601
- }
602
-
603
- // This is an escape-hatch to ignore nodes in the tree. If you have a comment
604
- // that includes this pattern, then the entire node will be ignored and just the
605
- // original source will be printed out.
606
- function hasPrettierIgnore(path) {
607
- const node = path.getValue();
608
-
609
- return node.comment && node.comment.string.includes("prettier-ignore");
610
- }
611
-
612
- module.exports = {
613
- print: printNode,
614
- hasPrettierIgnore
615
- };