@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
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@haneullabs/prettier-plugin-move",
3
+ "author": "Mysten Labs <build@haneullabslabs.com>",
4
+ "description": "Move Plugin for Prettier",
5
+ "version": "0.3.3",
6
+ "license": "Apache-2.0",
7
+ "keywords": [
8
+ "prettier",
9
+ "move",
10
+ "plugin"
11
+ ],
12
+ "bin": {
13
+ "prettier-move": "./bin/prettier-move.js"
14
+ },
15
+ "main": "./out/index.js",
16
+ "scripts": {
17
+ "prepublishOnly": "pnpm build",
18
+ "build": "tsc -p .",
19
+ "watch": "tsc -p . -w",
20
+ "test": "npm run build && vitest run",
21
+ "prettier": "npm run build && prettier --plugin out/index.js"
22
+ },
23
+ "dependencies": {
24
+ "prettier": "^3.3.2",
25
+ "web-tree-sitter": "^0.20.8"
26
+ },
27
+ "devDependencies": {
28
+ "@types/diff": "^5.2.1",
29
+ "@types/node": "^20.14.10",
30
+ "diff": "^5.2.0",
31
+ "typescript": "^5.5.3",
32
+ "vitest": "^2.1"
33
+ }
34
+ }
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Mysten Labs, Inc.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ module.exports = {
5
+ printWidth: 100,
6
+ semi: true,
7
+ singleQuote: true,
8
+ tabWidth: 4,
9
+ trailingComma: 'all',
10
+ useTabs: false,
11
+ overrides: [],
12
+ };
@@ -0,0 +1,71 @@
1
+ // Copyright (c) The Move Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Node } from '..';
5
+ import { MoveOptions, printFn, treeFn } from '../printer';
6
+ import { AstPath, doc, Doc } from 'prettier';
7
+ import { list } from '../utilities';
8
+ const { group, join } = doc.builders;
9
+
10
+ export enum Annotation {
11
+ Annotation = 'annotation',
12
+ AnnotationItem = 'annotation_item',
13
+ AnnotationList = 'annotation_list',
14
+ AnnotationExpr = 'annotation_expr',
15
+ }
16
+
17
+ export default function (path: AstPath<Node>): treeFn | null {
18
+ switch (path.node.type) {
19
+ case Annotation.Annotation:
20
+ return printAnnotation;
21
+ case Annotation.AnnotationItem:
22
+ return printAnnotationItem;
23
+ case Annotation.AnnotationList:
24
+ return printAnnotationList;
25
+ case Annotation.AnnotationExpr:
26
+ return printAnnotationExpr;
27
+ }
28
+
29
+ return null;
30
+ }
31
+
32
+ /**
33
+ * Print `annotation` node.
34
+ */
35
+ export function printAnnotation(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
36
+ return group(['#', list({ path, print, options, open: '[', close: ']' })]);
37
+ }
38
+
39
+ /**
40
+ * Print `annotation_item` node.
41
+ */
42
+ export function printAnnotationItem(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
43
+ return path.map(print, 'nonFormattingChildren');
44
+ }
45
+
46
+ export function printAnnotationList(
47
+ path: AstPath<Node>,
48
+ options: MoveOptions,
49
+ print: printFn,
50
+ ): Doc {
51
+ return [
52
+ path.call(print, 'nonFormattingChildren', 0),
53
+ list({ path, print, options, open: '(', close: ')', skipChildren: 1 }),
54
+ ];
55
+ }
56
+
57
+ /**
58
+ * Print `annotation_expr` node.
59
+ */
60
+ export function printAnnotationExpr(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
61
+ // allow `::module::Expression` in annotations
62
+ return join(
63
+ ' = ',
64
+ path.map((path) => {
65
+ if (path.node.type === 'module_access' && path.node.previousSibling?.type == '::') {
66
+ return ['::', path.call(print)];
67
+ }
68
+ return path.call(print);
69
+ }, 'nonFormattingChildren'),
70
+ );
71
+ }
@@ -0,0 +1,430 @@
1
+ // Copyright (c) The Move Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Node } from '..';
5
+ import { MoveOptions, printFn, treeFn } from '../printer';
6
+ import { AstPath, doc, Doc } from 'prettier';
7
+ import { list, printIdentifier, shouldBreakFirstChild } from '../utilities';
8
+ const { group, join, line, indent, hardline } = doc.builders;
9
+
10
+ /**
11
+ * Creates a callback function to print common nodes.
12
+ */
13
+ export default function (path: AstPath<Node>): treeFn | null {
14
+ switch (path.node.type) {
15
+ case Common.PrimitiveType:
16
+ return printPrimitiveType;
17
+ case Common.ModuleAccess:
18
+ return printModuleAccess;
19
+
20
+ // identifiers
21
+ case Common.Identifier:
22
+ case Common.FieldIdentifier:
23
+ case Common.VariableIdentifier:
24
+ return printIdentifier;
25
+
26
+ case Common.RefType:
27
+ return printRefType;
28
+ case Common.FunctionType:
29
+ return printFunctionType;
30
+ case Common.FunctionTypeParameters:
31
+ return printFunctionTypeParameters;
32
+
33
+ case Common.Ability:
34
+ return printAbility;
35
+
36
+ case Common.TupleType:
37
+ return printTupleType;
38
+
39
+ // === Bindings ===
40
+
41
+ case Common.BindUnpack:
42
+ return printBindUnpack;
43
+ case Common.BindFields:
44
+ return printBindFields;
45
+ case Common.MutBindField:
46
+ return printMutBindField;
47
+ case Common.BindField:
48
+ return printBindField;
49
+ case Common.BindList:
50
+ return printBindList;
51
+ case Common.CommaBindList:
52
+ return printCommaBindList;
53
+ case Common.OrBindList:
54
+ return printOrBindList;
55
+ case Common.AtBind:
56
+ return printAtBind;
57
+ case Common.BindNamedFields:
58
+ return printBindNamedFields;
59
+ case Common.BindPositionalFields:
60
+ return printBindPositionalFields;
61
+ case Common.BindVar:
62
+ return printBindVar;
63
+ case Common.MutBindVar:
64
+ return printMutBindVar;
65
+ case Common.ImmRef:
66
+ return printImmRef;
67
+ case Common.MutRef:
68
+ return printMutRef;
69
+
70
+ case Common.Label:
71
+ return printLabel;
72
+ case Common.Alias:
73
+ return printAlias;
74
+ case Common.BlockIdentifier:
75
+ return printBlockIdentifier;
76
+ case Common.UnaryOperator:
77
+ return printUnaryOperator;
78
+ case Common.FieldInitializeList:
79
+ return printFieldInitializeList;
80
+ case Common.ExpressionField:
81
+ return printExpressionField;
82
+ case Common.ArgList:
83
+ return printArgList;
84
+ }
85
+
86
+ return null;
87
+ }
88
+
89
+ /**
90
+ * Nodes which are used across multiple files, yet can't be categorized.
91
+ */
92
+ export enum Common {
93
+ PrimitiveType = 'primitive_type',
94
+ VariableIdentifier = 'variable_identifier',
95
+ ModuleAccess = 'module_access',
96
+ Identifier = 'identifier',
97
+ RefType = 'ref_type',
98
+ FunctionType = 'function_type',
99
+ FunctionTypeParameters = 'function_type_parameters',
100
+ FieldIdentifier = 'field_identifier',
101
+ BlockIdentifier = 'block_identifier',
102
+
103
+ Ability = 'ability',
104
+ TupleType = 'tuple_type',
105
+
106
+ // === Bindings ===
107
+
108
+ BindUnpack = 'bind_unpack',
109
+ BindFields = 'bind_fields',
110
+ MutBindField = 'mut_bind_field',
111
+ BindField = 'bind_field',
112
+ BindList = 'bind_list',
113
+ BindNamedFields = 'bind_named_fields',
114
+ CommaBindList = 'comma_bind_list',
115
+ OrBindList = 'or_bind_list',
116
+ AtBind = 'at_bind',
117
+ BindPositionalFields = 'bind_positional_fields',
118
+ BindVar = 'bind_var',
119
+ MutBindVar = 'mut_bind_var',
120
+ ImmRef = 'imm_ref',
121
+ MutRef = 'mut_ref',
122
+
123
+ Label = 'label',
124
+ Alias = 'alias',
125
+ UnaryOperator = 'unary_op',
126
+ FieldInitializeList = 'field_initialize_list',
127
+ ExpressionField = 'exp_field',
128
+
129
+ // used in `call_expression` and `macro_call_expression`
130
+ ArgList = 'arg_list',
131
+ }
132
+
133
+ /**
134
+ * Print `primitive_type` node.
135
+ */
136
+ export function printPrimitiveType(path: AstPath<Node>, _opt: MoveOptions, _p: printFn): Doc {
137
+ return path.node.text;
138
+ }
139
+
140
+ /**
141
+ * Print `module_access` node.
142
+ */
143
+ export function printModuleAccess(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
144
+ return path.map(print, 'children');
145
+ }
146
+
147
+ /**
148
+ * Print `ref_type` node.
149
+ */
150
+ export function printRefType(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
151
+ return group([
152
+ path.call(print, 'nonFormattingChildren', 0), // ref_type
153
+ path.call(print, 'nonFormattingChildren', 1), // type
154
+ ]);
155
+ }
156
+
157
+ /**
158
+ * Print `arg_list` node.
159
+ */
160
+ function printArgList(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
161
+ const nodes = path.node.nonFormattingChildren;
162
+
163
+ if (nodes.length === 1 && nodes[0]!.isBreakableExpression) {
164
+ const child = nodes[0]!;
165
+ const shouldBreak =
166
+ nodes[0]?.trailingComment?.type === 'line_comment' ||
167
+ nodes[0]?.leadingComment.some((e) => e.type === 'line_comment');
168
+
169
+ if (shouldBreak) {
170
+ return [
171
+ '(',
172
+ indent(hardline),
173
+ indent(path.call(print, 'nonFormattingChildren', 0)),
174
+ hardline,
175
+ ')',
176
+ ];
177
+ }
178
+
179
+ return ['(', path.call(print, 'nonFormattingChildren', 0), ')'];
180
+ }
181
+
182
+ return group(list({ path, print, options, open: '(', close: ')' }), {
183
+ shouldBreak: shouldBreakFirstChild(path),
184
+ });
185
+ }
186
+
187
+ /**
188
+ * Print `ability` node.
189
+ */
190
+ export function printAbility(path: AstPath<Node>, _opt: MoveOptions, _p: printFn): Doc {
191
+ return path.node.text;
192
+ }
193
+
194
+ /**
195
+ * Print `tuple_type` node.
196
+ */
197
+ export function printTupleType(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
198
+ return group(
199
+ list({
200
+ path,
201
+ print,
202
+ options,
203
+ open: '(',
204
+ close: ')',
205
+ shouldBreak: false,
206
+ }),
207
+ );
208
+ }
209
+
210
+ // === Bindings ===
211
+
212
+ /**
213
+ * Print `bind_unpack` node.
214
+ * For easier seach: `unpack_expression`.
215
+ *
216
+ * Inside:
217
+ * - `bind_var`
218
+ * - `bind_fields`
219
+ * - `bind_fields`
220
+ *
221
+ * `let Struct { field1, field2 } = ...;`
222
+ */
223
+ function printBindUnpack(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
224
+ return path.map(print, 'nonFormattingChildren');
225
+ }
226
+
227
+ /**
228
+ * Print `bind_fields` node.
229
+ * Choice node between `bind_named_fields` and `bind_positional_fields`.
230
+ */
231
+ function printBindFields(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
232
+ return path.call(print, 'nonFormattingChildren', 0);
233
+ }
234
+
235
+ /**
236
+ * Print `bind_field` node.
237
+ */
238
+ function printBindField(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
239
+ // special case for `..` operator
240
+ if (path.node.child(0)?.type == '..') {
241
+ return '..';
242
+ }
243
+
244
+ // if there's only one child, we can just print it
245
+ // if there're two, they will be joined
246
+ return join(': ', path.map(print, 'nonFormattingChildren'));
247
+ }
248
+
249
+ /**
250
+ * Print `mut_bind_field` node.
251
+ */
252
+ function printMutBindField(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
253
+ return ['mut ', path.call(print, 'nonFormattingChildren', 0)];
254
+ }
255
+
256
+ /**
257
+ * Print `bind_list` node.
258
+ * In the bind list we have two paths:
259
+ *
260
+ * - one is just `bind_var` with potential `mut`
261
+ * - another is a list, and we know it because the first member is `(`.
262
+ */
263
+ function printBindList(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
264
+ if (path.node.nonFormattingChildren.length == 1) {
265
+ return join(' ', path.map(print, 'nonFormattingChildren'));
266
+ }
267
+
268
+ return group(list({ path, print, options, open: '(', close: ')' }));
269
+ }
270
+
271
+ /**
272
+ * Print `comma_bind_list` node.
273
+ */
274
+ function printCommaBindList(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
275
+ return group(list({ path, print, options, open: '(', close: ')' }));
276
+ }
277
+
278
+ /**
279
+ * Print `at_bind` node.
280
+ */
281
+ function printAtBind(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
282
+ return join(' @ ', path.map(print, 'nonFormattingChildren'));
283
+ }
284
+
285
+ /**
286
+ * Print `or_bind_list` node.
287
+ */
288
+ function printOrBindList(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
289
+ return group(join([' |', line], path.map(print, 'nonFormattingChildren')));
290
+ }
291
+
292
+ /**
293
+ * Print `bind_named_fields` node.
294
+ */
295
+ function printBindNamedFields(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
296
+ return [
297
+ ' ',
298
+ group(list({ path, print, options, open: '{', close: '}', addWhitespace: true }), {
299
+ shouldBreak: shouldBreakFirstChild(path),
300
+ }),
301
+ ];
302
+ }
303
+
304
+ /**
305
+ * Print `bind_positional_fields` node.
306
+ */
307
+ function printBindPositionalFields(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
308
+ return group(list({ path, print, options, open: '(', close: ')' }), {
309
+ shouldBreak: shouldBreakFirstChild(path),
310
+ });
311
+ }
312
+
313
+ /**
314
+ * Print `bind_var` node.
315
+ */
316
+ function printBindVar(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
317
+ return path.call(print, 'nonFormattingChildren', 0);
318
+ }
319
+
320
+ /**
321
+ * Print `mut_bind_var` node.
322
+ */
323
+ function printMutBindVar(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
324
+ return ['mut ', path.call(print, 'nonFormattingChildren', 0)];
325
+ }
326
+
327
+ /**
328
+ * Print `imm_ref` node.
329
+ */
330
+ function printImmRef(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
331
+ return '&';
332
+ }
333
+
334
+ /**
335
+ * Print `mut_ref` node.
336
+ */
337
+ function printMutRef(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
338
+ return '&mut ';
339
+ }
340
+
341
+ /**
342
+ * Print `alias` node. ...as `identifier`
343
+ */
344
+ export function printAlias(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
345
+ return ['as ', path.call(print, 'nonFormattingChildren', 0)];
346
+ }
347
+
348
+ /**
349
+ * Print `block_identifier` node.
350
+ */
351
+ function printBlockIdentifier(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
352
+ return path.call(print, 'nonFormattingChildren', 0);
353
+ }
354
+
355
+ /**
356
+ * Print `label` node.
357
+ */
358
+ function printLabel(path: AstPath<Node>, _opt: MoveOptions, _p: printFn): Doc {
359
+ if (path.node.nextSibling?.type == ':') {
360
+ return [path.node.text, ':'];
361
+ }
362
+
363
+ return path.node.text;
364
+ }
365
+
366
+ /**
367
+ * Print `unary_op` node.
368
+ */
369
+ function printUnaryOperator(path: AstPath<Node>, _opt: MoveOptions, _p: printFn): Doc {
370
+ return path.node.text;
371
+ }
372
+
373
+ /**
374
+ * Print `field_initialize_list` node.
375
+ */
376
+ function printFieldInitializeList(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
377
+ return [
378
+ ' ',
379
+ group(list({ path, print, options, open: '{', close: '}', addWhitespace: true }), {
380
+ shouldBreak: shouldBreakFirstChild(path),
381
+ }),
382
+ ];
383
+ }
384
+
385
+ /**
386
+ * Print `expression_field` node.
387
+ * Inside:
388
+ * - `field_identifier`
389
+ * - `expression`
390
+ */
391
+ function printExpressionField(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
392
+ const children = path.map(print, 'nonFormattingChildren');
393
+
394
+ if (children.length === 1) {
395
+ return children[0]!;
396
+ }
397
+
398
+ return group([children[0]!, ': ', children[1]!]);
399
+ }
400
+
401
+ /**
402
+ * Print `function_type` node.
403
+ * Inside:
404
+ * - `function_type_parameters`
405
+ * - `return_type`
406
+ */
407
+ function printFunctionType(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
408
+ const children = path.map(print, 'nonFormattingChildren');
409
+
410
+ if (children.length === 0) {
411
+ return '||';
412
+ }
413
+
414
+ if (children.length === 1) {
415
+ return children[0]!;
416
+ }
417
+
418
+ return join(' -> ', children);
419
+ }
420
+
421
+ /**
422
+ * Print `function_type_parameters` node.
423
+ */
424
+ function printFunctionTypeParameters(
425
+ path: AstPath<Node>,
426
+ options: MoveOptions,
427
+ print: printFn,
428
+ ): Doc {
429
+ return group(list({ path, print, options, open: '|', close: '|' }));
430
+ }
@@ -0,0 +1,110 @@
1
+ // Copyright (c) The Move Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Node } from '..';
5
+ import { MoveOptions, printFn, treeFn } from '../printer';
6
+ import { AstPath, Doc, doc } from 'prettier';
7
+ import { printIdentifier, printTrailingComment } from '../utilities';
8
+ import * as VectorExpression from './expression/vector_expression';
9
+ import { printBreakableBlock } from './expression/block';
10
+ const { line, group, join, fill, ifBreak, softline, indent, lineSuffix } = doc.builders;
11
+
12
+ /** The type of the node implemented in this file */
13
+ export const NODE_TYPE = 'constant';
14
+
15
+ /**
16
+ * Prints:
17
+ * - `constant`
18
+ * - `constant_identifier`
19
+ */
20
+ export default function (path: AstPath<Node>): treeFn | null {
21
+ if (path.node.type === NODE_TYPE) {
22
+ return printConstant;
23
+ } else if (path.node.type === 'constant_identifier') {
24
+ return printIdentifier;
25
+ }
26
+
27
+ return null;
28
+ }
29
+
30
+ /**
31
+ * Print `constant` node.
32
+ *
33
+ * See `module-members/constant.move` for tests.
34
+ */
35
+ function printConstant(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
36
+ const expression = path.node.nonFormattingChildren[2];
37
+ const trailing = lineSuffix(printTrailingComment(path));
38
+ path.node.disableTrailingComment();
39
+
40
+ const printCb = (path: AstPath<Node>) => printConstExpression(path, options, print);
41
+ const groupId = Symbol('type_group');
42
+
43
+ if (path.node.nonFormattingChildren.length !== 3) {
44
+ throw new Error('`constant` expects 3 children');
45
+ }
46
+
47
+ const [identDoc, typeDoc, exprDoc] = path.map(printCb, 'nonFormattingChildren');
48
+ const parts = [] as Doc[];
49
+
50
+ // const <ident> : <type> = <expr>;
51
+ parts.push('const ', identDoc!);
52
+ parts.push(': ', group(typeDoc!, { id: groupId }), ' =');
53
+
54
+ if (expression?.isList) {
55
+ parts.push(
56
+ group([
57
+ ifBreak(indent(line), ' ', { groupId }),
58
+ ifBreak(indent(exprDoc!), exprDoc, { groupId }),
59
+ ]),
60
+ );
61
+ } else {
62
+ parts.push(group([indent(line), indent(exprDoc!)]));
63
+ }
64
+
65
+ return parts.concat([';', trailing]);
66
+ }
67
+
68
+ // Sub-router for expressions in the const declaration. Special cases are:
69
+ //
70
+ // - for vectors with `num` and `bool` literals, we want to fill single line
71
+ // - for blocks we want breakability
72
+ function printConstExpression(path: AstPath<Node>, options: MoveOptions, print: printFn) {
73
+ if (path.node.type === VectorExpression.NODE_TYPE) {
74
+ return prettyNumVector(path, options, print);
75
+ }
76
+
77
+ if (path.node.type === 'block') {
78
+ return printBreakableBlock(path, options, print);
79
+ }
80
+
81
+ return print(path);
82
+ }
83
+
84
+ // TODO: optionally move this to `VectorExpression`
85
+ function prettyNumVector(path: AstPath<Node>, options: MoveOptions, print: printFn) {
86
+ let elType = path.node.nonFormattingChildren[0]?.type;
87
+ if (elType && ['num_literal', 'bool_literal'].includes(elType)) {
88
+ let allSameType = !path.node.nonFormattingChildren.some((e) => e.type !== elType);
89
+ let hasComments = path.node.namedChildren.some(
90
+ (e) => e.trailingComment || e.leadingComment.length > 0,
91
+ );
92
+
93
+ if (allSameType && !hasComments) {
94
+ const literals = path.map(print, 'nonFormattingChildren');
95
+
96
+ if (literals.length == 0) {
97
+ return 'vector[]';
98
+ }
99
+
100
+ const elements = join([',', line], literals);
101
+ return [
102
+ 'vector[',
103
+ group([indent(softline), indent(fill(elements)), ifBreak(','), softline]),
104
+ ']',
105
+ ];
106
+ }
107
+ }
108
+
109
+ return print(path);
110
+ }