@haneullabs/prettier-plugin-move 0.3.3

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.
Files changed (149) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/CONTRIBUTING.md +31 -0
  3. package/README.md +96 -0
  4. package/bin/prettier-move.js +29 -0
  5. package/out/cst/annotation.js +64 -0
  6. package/out/cst/annotation.js.map +1 -0
  7. package/out/cst/common.js +376 -0
  8. package/out/cst/common.js.map +1 -0
  9. package/out/cst/constant.js +92 -0
  10. package/out/cst/constant.js.map +1 -0
  11. package/out/cst/enum_definition.js +69 -0
  12. package/out/cst/enum_definition.js.map +1 -0
  13. package/out/cst/expression/abort_expression.js +32 -0
  14. package/out/cst/expression/abort_expression.js.map +1 -0
  15. package/out/cst/expression/annotation_expression.js +35 -0
  16. package/out/cst/expression/annotation_expression.js.map +1 -0
  17. package/out/cst/expression/assign_expression.js +51 -0
  18. package/out/cst/expression/assign_expression.js.map +1 -0
  19. package/out/cst/expression/binary_expression.js +70 -0
  20. package/out/cst/expression/binary_expression.js.map +1 -0
  21. package/out/cst/expression/block.js +58 -0
  22. package/out/cst/expression/block.js.map +1 -0
  23. package/out/cst/expression/block_item.js +25 -0
  24. package/out/cst/expression/block_item.js.map +1 -0
  25. package/out/cst/expression/borrow_expression.js +26 -0
  26. package/out/cst/expression/borrow_expression.js.map +1 -0
  27. package/out/cst/expression/break_expression.js +27 -0
  28. package/out/cst/expression/break_expression.js.map +1 -0
  29. package/out/cst/expression/call_expression.js +25 -0
  30. package/out/cst/expression/call_expression.js.map +1 -0
  31. package/out/cst/expression/cast_expression.js +31 -0
  32. package/out/cst/expression/cast_expression.js.map +1 -0
  33. package/out/cst/expression/continue_expression.js +26 -0
  34. package/out/cst/expression/continue_expression.js.map +1 -0
  35. package/out/cst/expression/dereference_expression.js +27 -0
  36. package/out/cst/expression/dereference_expression.js.map +1 -0
  37. package/out/cst/expression/dot_expression.js +66 -0
  38. package/out/cst/expression/dot_expression.js.map +1 -0
  39. package/out/cst/expression/expression_list.js +26 -0
  40. package/out/cst/expression/expression_list.js.map +1 -0
  41. package/out/cst/expression/identified_expression.js +28 -0
  42. package/out/cst/expression/identified_expression.js.map +1 -0
  43. package/out/cst/expression/if_expression.js +133 -0
  44. package/out/cst/expression/if_expression.js.map +1 -0
  45. package/out/cst/expression/index.js +74 -0
  46. package/out/cst/expression/index.js.map +1 -0
  47. package/out/cst/expression/index_expression.js +28 -0
  48. package/out/cst/expression/index_expression.js.map +1 -0
  49. package/out/cst/expression/lambda_expression.js +72 -0
  50. package/out/cst/expression/lambda_expression.js.map +1 -0
  51. package/out/cst/expression/let_statement.js +59 -0
  52. package/out/cst/expression/let_statement.js.map +1 -0
  53. package/out/cst/expression/loop_expression.js +27 -0
  54. package/out/cst/expression/loop_expression.js.map +1 -0
  55. package/out/cst/expression/macro_call_expression.js +66 -0
  56. package/out/cst/expression/macro_call_expression.js.map +1 -0
  57. package/out/cst/expression/match_expression.js +86 -0
  58. package/out/cst/expression/match_expression.js.map +1 -0
  59. package/out/cst/expression/move_or_copy_expression.js +27 -0
  60. package/out/cst/expression/move_or_copy_expression.js.map +1 -0
  61. package/out/cst/expression/name_expression.js +26 -0
  62. package/out/cst/expression/name_expression.js.map +1 -0
  63. package/out/cst/expression/pack_expression.js +27 -0
  64. package/out/cst/expression/pack_expression.js.map +1 -0
  65. package/out/cst/expression/return_expression.js +44 -0
  66. package/out/cst/expression/return_expression.js.map +1 -0
  67. package/out/cst/expression/unary_expression.js +26 -0
  68. package/out/cst/expression/unary_expression.js.map +1 -0
  69. package/out/cst/expression/unit_expression.js +17 -0
  70. package/out/cst/expression/unit_expression.js.map +1 -0
  71. package/out/cst/expression/vector_expression.js +80 -0
  72. package/out/cst/expression/vector_expression.js.map +1 -0
  73. package/out/cst/expression/while_expression.js +42 -0
  74. package/out/cst/expression/while_expression.js.map +1 -0
  75. package/out/cst/formatting.js +100 -0
  76. package/out/cst/formatting.js.map +1 -0
  77. package/out/cst/function_definition.js +248 -0
  78. package/out/cst/function_definition.js.map +1 -0
  79. package/out/cst/literal.js +68 -0
  80. package/out/cst/literal.js.map +1 -0
  81. package/out/cst/module.js +158 -0
  82. package/out/cst/module.js.map +1 -0
  83. package/out/cst/source_file.js +38 -0
  84. package/out/cst/source_file.js.map +1 -0
  85. package/out/cst/struct_definition.js +209 -0
  86. package/out/cst/struct_definition.js.map +1 -0
  87. package/out/cst/use_declaration.js +212 -0
  88. package/out/cst/use_declaration.js.map +1 -0
  89. package/out/imports-grouping.js +259 -0
  90. package/out/imports-grouping.js.map +1 -0
  91. package/out/index.js +97 -0
  92. package/out/index.js.map +1 -0
  93. package/out/printer.js +69 -0
  94. package/out/printer.js.map +1 -0
  95. package/out/tree.js +371 -0
  96. package/out/tree.js.map +1 -0
  97. package/out/utilities.js +251 -0
  98. package/out/utilities.js.map +1 -0
  99. package/package.json +34 -0
  100. package/prettier.config.js +12 -0
  101. package/src/cst/annotation.ts +71 -0
  102. package/src/cst/common.ts +430 -0
  103. package/src/cst/constant.ts +110 -0
  104. package/src/cst/enum_definition.ts +73 -0
  105. package/src/cst/expression/abort_expression.ts +35 -0
  106. package/src/cst/expression/annotation_expression.ts +38 -0
  107. package/src/cst/expression/assign_expression.ts +66 -0
  108. package/src/cst/expression/binary_expression.ts +75 -0
  109. package/src/cst/expression/block.ts +72 -0
  110. package/src/cst/expression/block_item.ts +29 -0
  111. package/src/cst/expression/borrow_expression.ts +28 -0
  112. package/src/cst/expression/break_expression.ts +33 -0
  113. package/src/cst/expression/call_expression.ts +28 -0
  114. package/src/cst/expression/cast_expression.ts +35 -0
  115. package/src/cst/expression/continue_expression.ts +29 -0
  116. package/src/cst/expression/dereference_expression.ts +33 -0
  117. package/src/cst/expression/dot_expression.ts +89 -0
  118. package/src/cst/expression/expression_list.ts +28 -0
  119. package/src/cst/expression/identified_expression.ts +30 -0
  120. package/src/cst/expression/if_expression.ts +177 -0
  121. package/src/cst/expression/index.ts +85 -0
  122. package/src/cst/expression/index_expression.ts +37 -0
  123. package/src/cst/expression/lambda_expression.ts +84 -0
  124. package/src/cst/expression/let_statement.ts +73 -0
  125. package/src/cst/expression/loop_expression.ts +29 -0
  126. package/src/cst/expression/macro_call_expression.ts +79 -0
  127. package/src/cst/expression/match_expression.ts +102 -0
  128. package/src/cst/expression/move_or_copy_expression.ts +29 -0
  129. package/src/cst/expression/name_expression.ts +28 -0
  130. package/src/cst/expression/pack_expression.ts +29 -0
  131. package/src/cst/expression/return_expression.ts +50 -0
  132. package/src/cst/expression/unary_expression.ts +28 -0
  133. package/src/cst/expression/unit_expression.ts +18 -0
  134. package/src/cst/expression/vector_expression.ts +97 -0
  135. package/src/cst/expression/while_expression.ts +45 -0
  136. package/src/cst/formatting.ts +100 -0
  137. package/src/cst/function_definition.ts +300 -0
  138. package/src/cst/literal.ts +69 -0
  139. package/src/cst/module.ts +191 -0
  140. package/src/cst/source_file.ts +38 -0
  141. package/src/cst/struct_definition.ts +267 -0
  142. package/src/cst/use_declaration.ts +238 -0
  143. package/src/imports-grouping.ts +300 -0
  144. package/src/index.ts +119 -0
  145. package/src/printer.ts +93 -0
  146. package/src/tree.ts +438 -0
  147. package/src/utilities.ts +387 -0
  148. package/tree-sitter-move.wasm +0 -0
  149. package/tsconfig.json +26 -0
@@ -0,0 +1,387 @@
1
+ // Copyright (c) The Move Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Node } from '.';
5
+ import { AstPath, Doc, ParserOptions, doc } from 'prettier';
6
+ import { MoveOptions, printFn } from './printer';
7
+
8
+ const {
9
+ indent,
10
+ join,
11
+ fill,
12
+ softline,
13
+ dedent,
14
+ hardline,
15
+ line,
16
+ lineSuffix,
17
+ group,
18
+ indentIfBreak,
19
+ hardlineWithoutBreakParent,
20
+ breakParent,
21
+ ifBreak,
22
+ } = doc.builders;
23
+
24
+ /**
25
+ * Prints an `identifier` node.
26
+ */
27
+ export function printIdentifier(path: AstPath<Node>): Doc {
28
+ return path.node.text;
29
+ }
30
+
31
+ /**
32
+ * Returns `true` if the first non-formatting child of the path starts on a new line.
33
+ * This function is useful for respecting developer formatting if they choose to break
34
+ * the list.
35
+ *
36
+ * ```move
37
+ * // input
38
+ * fun args(a: u8) {} // no break
39
+ * fun args(
40
+ * a: u8 // first child starts on a new line
41
+ * ) {}
42
+ *
43
+ * // output
44
+ * fun args(a: u8) {} // no break
45
+ * fun args(
46
+ * a: u8 // respect developer formatting
47
+ * ) {}
48
+ * ```
49
+ *
50
+ * @param path
51
+ * @returns
52
+ */
53
+ export function shouldBreakFirstChild(path: AstPath<Node>): boolean {
54
+ return path.node.nonFormattingChildren[0]?.startsOnNewLine || false;
55
+ }
56
+
57
+ /**
58
+ * Prints all comments that are leading the node. This function is injected into
59
+ * the `printFn` to print comments before the node. See the `print` function in
60
+ * `printer.ts` for more information.
61
+ *
62
+ * @param path
63
+ * @returns
64
+ */
65
+ export function printLeadingComment(path: AstPath<Node>, options: MoveOptions): Doc[] {
66
+ const comments = path.node.leadingComment;
67
+ if (!comments || !comments.length) return [];
68
+ if (!path.node.enableLeadingComment) return [];
69
+
70
+ if (comments.length == 1 && comments[0]!.type == 'block_comment') {
71
+ return [comments[0]!.text, comments[0]!.newline ? hardlineWithoutBreakParent : ' '];
72
+ }
73
+
74
+ if (options.wrapComments == false) {
75
+ return [
76
+ join(
77
+ hardlineWithoutBreakParent,
78
+ comments.map((c) =>
79
+ c.type == 'line_comment' ? [c.text, /* used to be breakParent */ ''] : [c.text],
80
+ ),
81
+ ),
82
+ hardlineWithoutBreakParent,
83
+ ];
84
+ }
85
+
86
+ // we do not concatenate the comments into a single string, and treat each
87
+ // line separately.
88
+ return comments.map((comment) => {
89
+ if (comment.type == 'line_comment') {
90
+ const isDoc = comment.text.startsWith('///');
91
+ const parts = comment.text.slice(isDoc ? 4 : 3).split(' ');
92
+
93
+ return [
94
+ isDoc ? '/// ' : '// ',
95
+ fill(join(ifBreak([softline, isDoc ? '/// ' : '// '], ' '), parts)),
96
+ hardlineWithoutBreakParent,
97
+ ];
98
+ }
99
+
100
+ return comment.text;
101
+ });
102
+ }
103
+
104
+ /**
105
+ * Prints the trailing comments of the node. Currently, we only allow a single line
106
+ * comment to be printed. This function is injected into the `printFn` to print
107
+ * comments after the node. See the `print` function in `printer.ts` for more information.
108
+ *
109
+ * @param path
110
+ * @returns
111
+ */
112
+ export function printTrailingComment(path: AstPath<Node>, shouldBreak: boolean = false): Doc {
113
+ // we do not allow comments on empty lines
114
+ if (path.node.isEmptyLine) return '';
115
+ if (!path.node.enableTrailingComment) return '';
116
+ const comment = path.node.trailingComment;
117
+ if (!comment) return '';
118
+ if (comment.type == 'line_comment' && shouldBreak) {
119
+ return [' ', comment.text, hardline];
120
+ }
121
+
122
+ return [' ', comment.text];
123
+ }
124
+
125
+ export function emptyBlockOrList(
126
+ path: AstPath<Node>,
127
+ open: string,
128
+ close: string,
129
+ line: Doc = hardline,
130
+ ): Doc {
131
+ const length = path.node.nonFormattingChildren.length;
132
+ const comments = path.node.namedChildren.filter((e) => e.isComment);
133
+
134
+ if (length != 0) {
135
+ throw new Error('The list is not empty');
136
+ }
137
+
138
+ if (comments.length == 0) {
139
+ return [open, close];
140
+ }
141
+
142
+ if (comments.length == 1 && comments[0]!.type == 'block_comment') {
143
+ return group([open, indent(line), indent(comments[0]!.text), line, close]);
144
+ }
145
+
146
+ return group(
147
+ [
148
+ open,
149
+ indent(line),
150
+ indent(
151
+ join(
152
+ line,
153
+ comments.map((c) => c.text),
154
+ ),
155
+ ),
156
+ line,
157
+ close,
158
+ ],
159
+ { shouldBreak: true },
160
+ );
161
+ }
162
+
163
+ /**
164
+ * TODO: use this type for the `block()` function.
165
+ */
166
+ export type BlockOptions = {
167
+ path: AstPath<Node>;
168
+ print: printFn;
169
+ options: ParserOptions;
170
+ breakDependency?: Symbol;
171
+
172
+ lastLine?: boolean;
173
+ lineEnding?: Doc;
174
+ skipChildren?: number;
175
+ shouldBreak?: boolean;
176
+ };
177
+
178
+ /**
179
+ */
180
+ export function block({ path, print, options, shouldBreak, skipChildren }: BlockOptions) {
181
+ const length = path.node.nonFormattingChildren.length;
182
+
183
+ if (length == 0) {
184
+ return emptyBlockOrList(path, '{', '}', hardline);
185
+ }
186
+
187
+ return group(
188
+ [
189
+ '{',
190
+ options.bracketSpacing ? ifBreak('', ' ') : '',
191
+ indent(softline),
192
+ indent(join(line, path.map(print, 'namedAndEmptyLineChildren').slice(skipChildren))),
193
+ softline,
194
+ options.bracketSpacing ? ifBreak('', ' ') : '',
195
+ '}',
196
+ ],
197
+ { shouldBreak },
198
+ );
199
+ }
200
+
201
+ export function nonBreakingBlock({
202
+ path,
203
+ print,
204
+ options,
205
+ shouldBreak, // always breaks
206
+ skipChildren,
207
+ }: BlockOptions) {
208
+ const length = path.node.nonFormattingChildren.length;
209
+
210
+ if (length == 0) {
211
+ return emptyBlockOrList(path, '{', '}', hardlineWithoutBreakParent);
212
+ }
213
+
214
+ return group([
215
+ '{',
216
+ indent(hardlineWithoutBreakParent),
217
+ indent(
218
+ join(
219
+ hardlineWithoutBreakParent,
220
+ path.map(print, 'namedAndEmptyLineChildren').slice(skipChildren || 0),
221
+ ),
222
+ ),
223
+ hardlineWithoutBreakParent,
224
+ '}',
225
+ ]);
226
+ }
227
+
228
+ export type ListOptions = {
229
+ path: AstPath<Node>;
230
+ print: printFn;
231
+ options: MoveOptions;
232
+ /** Opening bracket. */
233
+ open: string;
234
+ /** Closing bracket. */
235
+ close: string;
236
+ /**
237
+ * The number of children to skip when printing the list.
238
+ */
239
+ skipChildren?: number;
240
+ /**
241
+ * Whether to add a whitespace after the open bracket and before the close bracket.
242
+ * ```
243
+ * { a, b, c } // addWhitespace = true
244
+ * {a, b, c} // addWhitespace = false
245
+ * ```
246
+ */
247
+ addWhitespace?: boolean;
248
+ /**
249
+ * Whether to break the list.
250
+ */
251
+ shouldBreak?: boolean;
252
+ /**
253
+ * Group ID for `indentIfBreak` to break the list.
254
+ */
255
+ indentGroup?: symbol | null;
256
+ };
257
+
258
+ /**
259
+ * Prints a list of non-formatting children. Handles commas and trailing comments.
260
+ * TODO: keep trailing comments after the last element of the list.
261
+ */
262
+ export function list({
263
+ path,
264
+ print,
265
+ options,
266
+ open,
267
+ close,
268
+ indentGroup = null,
269
+ addWhitespace = false,
270
+ skipChildren = 0,
271
+ shouldBreak = false,
272
+ }: ListOptions) {
273
+ const length = path.node.nonFormattingChildren.length;
274
+ const indentCb: (el: Doc) => Doc = (el) =>
275
+ indentGroup ? indentIfBreak(el, { groupId: indentGroup }) : indent(el);
276
+
277
+ // if there's no children the list should print, we still look up for non-
278
+ // formatting nodes, namely comments, to print them.
279
+ if (length == skipChildren) {
280
+ const lastNode = path.node.nonFormattingChildren[length - 1]!;
281
+ const indexInNamedChildren = path.node.namedChildren.indexOf(lastNode);
282
+ const otherNamedChildren = path.node.namedChildren
283
+ .slice(indexInNamedChildren + 1)
284
+ .filter((e) => e.isComment);
285
+
286
+ if (!otherNamedChildren.length) {
287
+ return [open, close];
288
+ }
289
+
290
+ return [
291
+ open,
292
+ indentCb(softline),
293
+ indentCb(
294
+ join(
295
+ hardline,
296
+ otherNamedChildren.map((c) => c.text),
297
+ ),
298
+ ),
299
+ hardline,
300
+ dedent(close),
301
+ ];
302
+ }
303
+
304
+ const lastNode = path.node.nonFormattingChildren[length - 1]!;
305
+ const indexInNamedChildren = path.node.namedChildren.indexOf(lastNode);
306
+
307
+ // collect all trailing comments
308
+ // after `nonFormattingChildren` and before end
309
+ let trailingComments = [] as Doc[];
310
+ if (indexInNamedChildren != -1) {
311
+ path.each((path, idx) => {
312
+ if (idx + 1 > indexInNamedChildren && path.node.isComment) {
313
+ return trailingComments.push(path.node.text);
314
+ }
315
+ return;
316
+ }, 'namedChildren');
317
+ }
318
+
319
+ return [
320
+ open,
321
+ indentCb(addWhitespace ? line : softline),
322
+ shouldBreak ? breakParent : '',
323
+ indentCb(
324
+ path
325
+ .map((path, i) => {
326
+ const leading = printLeadingComment(path, options);
327
+ const comment = printTrailingComment(path, false);
328
+ let shouldBreak = false;
329
+
330
+ // if the node has a trailing comment, we should break
331
+ if (path.node.trailingComment?.type == 'line_comment') {
332
+ shouldBreak = true;
333
+ }
334
+
335
+ const leadComment = path.node.leadingComment;
336
+
337
+ if (leadComment.length > 0 && leadComment![0]!.type == 'line_comment') {
338
+ shouldBreak = true;
339
+ }
340
+
341
+ if (
342
+ leadComment.length > 0 &&
343
+ leadComment[0]!.type == 'block_comment' &&
344
+ leadComment[0]!.newline
345
+ ) {
346
+ shouldBreak = true;
347
+ }
348
+
349
+ path.node.disableTrailingComment();
350
+ path.node.disableLeadingComment();
351
+
352
+ const breakExpr = shouldBreak ? breakParent : '';
353
+ const shouldDedent = trailingComments.length == 0;
354
+ const endingExpr = addWhitespace ? line : softline;
355
+ const isLastChild = i == length - 1;
356
+
357
+ if (isLastChild) {
358
+ return [
359
+ leading,
360
+ breakExpr,
361
+ print(path),
362
+ ifBreak(','),
363
+ shouldBreak ? lineSuffix(comment) : comment,
364
+ shouldDedent ? dedent(endingExpr) : endingExpr,
365
+ ];
366
+ }
367
+
368
+ // if we are not at the last child, add a comma
369
+ return [
370
+ leading,
371
+ breakExpr,
372
+ print(path),
373
+ ',',
374
+ shouldBreak ? lineSuffix(comment) : comment,
375
+ line,
376
+ ];
377
+ }, 'nonFormattingChildren')
378
+ .slice(skipChildren)
379
+ .concat(
380
+ trailingComments.length
381
+ ? [join(hardline, trailingComments), dedent(hardline)]
382
+ : [],
383
+ ),
384
+ ),
385
+ dedent(close),
386
+ ];
387
+ }
Binary file
package/tsconfig.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "CommonJS",
4
+ "target": "es2021",
5
+ "outDir": "out",
6
+ "lib": ["es2021"],
7
+ "sourceMap": true,
8
+ "rootDir": "src",
9
+ "newLine": "LF",
10
+ "strict": true,
11
+ "allowUnreachableCode": false,
12
+ "allowUnusedLabels": false,
13
+ "exactOptionalPropertyTypes": true,
14
+ "noFallthroughCasesInSwitch": true,
15
+ "noImplicitAny": true,
16
+ "noImplicitOverride": true,
17
+ "noImplicitReturns": true,
18
+ "noImplicitThis": true,
19
+ "noPropertyAccessFromIndexSignature": true,
20
+ "noUncheckedIndexedAccess": true,
21
+ "noUnusedLocals": false,
22
+ "noUnusedParameters": false
23
+ },
24
+ "exclude": ["node_modules", "out"],
25
+ "include": ["src"]
26
+ }