@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,267 @@
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, ParserOptions, doc } from 'prettier';
7
+ import {
8
+ emptyBlockOrList,
9
+ list,
10
+ printIdentifier,
11
+ printLeadingComment,
12
+ printTrailingComment,
13
+ shouldBreakFirstChild,
14
+ } from '../utilities';
15
+ const { group, join } = doc.builders;
16
+
17
+ export default function (path: AstPath<Node>): treeFn | null {
18
+ switch (path.node.type) {
19
+ case StructDefinition.StructDefinition:
20
+ return printStructDefinition;
21
+ case StructDefinition.NativeStructDefinition:
22
+ return printNativeStructDefinition;
23
+ case StructDefinition.AbilityDeclarations:
24
+ return printAbilityDeclarations;
25
+ case StructDefinition.PostfixAbilityDeclarations:
26
+ return printPostfixAbilityDeclarations;
27
+ case StructDefinition.DatatypeFields:
28
+ return printDatatypeFields;
29
+ case StructDefinition.NamedFields:
30
+ return printNamedFields;
31
+ case StructDefinition.PositionalFields:
32
+ return printPositionalFields;
33
+ case StructDefinition.FieldAnnotation:
34
+ return printFieldAnnotation;
35
+ case StructDefinition.ApplyType:
36
+ return printApplyType;
37
+ case StructDefinition.StructIdentifier:
38
+ return printIdentifier;
39
+ }
40
+
41
+ return null;
42
+ }
43
+
44
+ export enum StructDefinition {
45
+ /**
46
+ * Module-level definition
47
+ * ```
48
+ * public struct identifier ...
49
+ * ```
50
+ */
51
+ StructDefinition = 'struct_definition',
52
+ /**
53
+ * Module-level definition (features `native` keyword and has no fields)
54
+ * ```
55
+ * native struct identifier ... ;
56
+ * ```
57
+ */
58
+ NativeStructDefinition = 'native_struct_definition',
59
+ AbilityDeclarations = 'ability_decls',
60
+ /**
61
+ * Postfix ability declarations must be printed after the fields
62
+ * and be followed by a semicolon.
63
+ * ```
64
+ * struct ident {} has store;
65
+ * struct Point(u8) has store, drop;
66
+ * ```
67
+ */
68
+ PostfixAbilityDeclarations = 'postfix_ability_decls',
69
+ DatatypeFields = 'datatype_fields',
70
+ NamedFields = 'named_fields',
71
+ PositionalFields = 'positional_fields',
72
+ FieldAnnotation = 'field_annotation',
73
+ ApplyType = 'apply_type',
74
+ StructIdentifier = 'struct_identifier',
75
+ }
76
+
77
+ /**
78
+ * Print `struct_definition` node.
79
+ */
80
+ export function printNativeStructDefinition(
81
+ path: AstPath<Node>,
82
+ options: ParserOptions,
83
+ print: printFn,
84
+ ): Doc {
85
+ const isPublic = path.node.child(0)!.type === 'public' ? ['public', ' '] : [];
86
+ return group([
87
+ ...isPublic, // insert `public` keyword if present
88
+ 'native',
89
+ ' ',
90
+ 'struct',
91
+ ' ',
92
+ path.map(print, 'nonFormattingChildren'),
93
+ ';',
94
+ ]);
95
+ }
96
+
97
+ /**
98
+ * Print `struct_definition` node.
99
+ * Insert a newline before the comment if the previous node is not a line comment.
100
+ */
101
+ export function printStructDefinition(
102
+ path: AstPath<Node>,
103
+ options: ParserOptions,
104
+ print: printFn,
105
+ ): Doc {
106
+ const isPublic = path.node.child(0)!.type === 'public' ? ['public', ' '] : [];
107
+ return group([
108
+ ...isPublic, // insert `public` keyword if present
109
+ 'struct',
110
+ ' ',
111
+ path.map(print, 'nonFormattingChildren'),
112
+ ]);
113
+ }
114
+
115
+ type Ability = { name: 'key' | 'store' | 'drop'; text: Doc };
116
+
117
+ /**
118
+ * Print `ability_decls` node.
119
+ */
120
+ export function printAbilityDeclarations(
121
+ path: AstPath<Node>,
122
+ options: MoveOptions,
123
+ print: printFn,
124
+ ): Doc {
125
+ const abilities = formatAndSortAbilities(path, options, print);
126
+ return [
127
+ ' has ',
128
+ join(
129
+ ', ',
130
+ abilities.map((ability) => ability.text),
131
+ ),
132
+ path.next?.namedChildren[0]?.type === StructDefinition.PositionalFields ? ' ' : '',
133
+ ];
134
+ }
135
+
136
+ /**
137
+ * Print `postfix_ability_decls` node.
138
+ */
139
+ export function printPostfixAbilityDeclarations(
140
+ path: AstPath<Node>,
141
+ options: MoveOptions,
142
+ print: printFn,
143
+ ): Doc {
144
+ const abilities = formatAndSortAbilities(path, options, print);
145
+ return group([
146
+ ' has ',
147
+ join(
148
+ ', ',
149
+ abilities.map((ability) => ability.text),
150
+ ),
151
+ ';',
152
+ ]);
153
+ }
154
+
155
+ /**
156
+ * Print `datatype_fields` node.
157
+ * Prints the underlying fields of a datatype.
158
+ */
159
+ export function printDatatypeFields(
160
+ path: AstPath<Node>,
161
+ options: ParserOptions,
162
+ print: printFn,
163
+ ): Doc {
164
+ return path.map(print, 'nonFormattingChildren');
165
+ }
166
+
167
+ /**
168
+ * Print `named_fields` node.
169
+ * Prints the underlying fields of a struct.
170
+ */
171
+ export function printNamedFields(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
172
+ const children = path.map(print, 'nonFormattingChildren');
173
+
174
+ if (children.length === 0) {
175
+ return [' ', emptyBlockOrList(path, '{', '}', doc.builders.line)];
176
+ }
177
+
178
+ return [
179
+ ' ',
180
+ group(list({ path, print, options, open: '{', close: '}', addWhitespace: true }), {
181
+ shouldBreak: shouldBreakFirstChild(path),
182
+ }),
183
+ ];
184
+ }
185
+
186
+ /**
187
+ * Print `positional_fields` node.
188
+ * Prints the underlying fields of a struct.
189
+ */
190
+ export function printPositionalFields(
191
+ path: AstPath<Node>,
192
+ options: MoveOptions,
193
+ print: printFn,
194
+ ): Doc {
195
+ const children = path.map(print, 'nonFormattingChildren');
196
+
197
+ if (children.length === 0) {
198
+ return emptyBlockOrList(path, '(', ')', doc.builders.line);
199
+ }
200
+
201
+ return group(list({ path, print, options, open: '(', close: ')' }), {
202
+ shouldBreak: false,
203
+ });
204
+ }
205
+
206
+ /**
207
+ * Print `field_annotation` node.
208
+ */
209
+ export function printFieldAnnotation(
210
+ path: AstPath<Node>,
211
+ options: ParserOptions,
212
+ print: printFn,
213
+ ): Doc {
214
+ return group([
215
+ path.call(print, 'nonFormattingChildren', 0), // field_identifier
216
+ ':',
217
+ ' ',
218
+ path.call(print, 'nonFormattingChildren', 1), // type
219
+ ]);
220
+ }
221
+
222
+ /**
223
+ * Print `apply_type` node.
224
+ */
225
+ export function printApplyType(path: AstPath<Node>, options: ParserOptions, print: printFn): Doc {
226
+ return path.map(print, 'nonFormattingChildren');
227
+ }
228
+
229
+ /**
230
+ * Utility function which formats and sorts abilities in the following order::
231
+ *
232
+ * - key
233
+ * - copy
234
+ * - drop
235
+ * - store
236
+ *
237
+ * Key always goes first, the rest are sorted alphabetically.
238
+ */
239
+ function formatAndSortAbilities(
240
+ path: AstPath<Node>,
241
+ options: MoveOptions,
242
+ print: printFn,
243
+ ): Ability[] {
244
+ const abilities: Ability[] = path.map(
245
+ (path) => ({
246
+ name: path.node.text as Ability['name'],
247
+ text: [
248
+ printLeadingComment(path, options),
249
+ path.node.text,
250
+ printTrailingComment(path, true),
251
+ ] as Doc,
252
+ }),
253
+ 'nonFormattingChildren',
254
+ );
255
+
256
+ // alphabetical but `key` always goes first
257
+ const priority = {
258
+ key: 0,
259
+ copy: 1,
260
+ drop: 2,
261
+ store: 3,
262
+ };
263
+
264
+ abilities.sort((a, b) => priority[a.name] - priority[b.name]);
265
+
266
+ return abilities;
267
+ }
@@ -0,0 +1,238 @@
1
+ // Copyright (c) The Move Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Node } from '..';
5
+ import { AstPath, Doc, doc } from 'prettier';
6
+ import { MoveOptions, printFn, treeFn } from '../printer';
7
+ const { group, indent, line, softline, ifBreak, join } = doc.builders;
8
+
9
+ export default function (path: AstPath<Node>): treeFn | null {
10
+ switch (path.node.type) {
11
+ case UseDeclaration.UseDeclaration:
12
+ return printUseDeclaration;
13
+ case UseDeclaration.UseModule:
14
+ return printUseModule;
15
+ case UseDeclaration.UseMember:
16
+ return printUseMember;
17
+ case UseDeclaration.UseModuleMember:
18
+ return printUseModuleMember;
19
+ case UseDeclaration.UseModuleMembers:
20
+ return printUseModuleMembers;
21
+ case UseDeclaration.UseFun:
22
+ return printUseFun;
23
+ case UseDeclaration.ModuleIdentity:
24
+ return printModuleIdentity;
25
+ case UseDeclaration.FriendDeclaration:
26
+ return printFriendDeclaration;
27
+ case UseDeclaration.FriendAccess:
28
+ return printFriendAccess;
29
+ default:
30
+ return null;
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Use Declaration
36
+ *
37
+ * Contains one of the following:
38
+ *
39
+ * `use_declaration` (
40
+ * - use `use_module` <as `alias`>;
41
+ * - use `use_module_member` <as `use_member`>;
42
+ * - use `use_module_members`;
43
+ * - use `use_fun`;
44
+ * )
45
+ *
46
+ * `use_member` (
47
+ * - `identifier` <as `alias`>;
48
+ * )
49
+ */
50
+ export enum UseDeclaration {
51
+ /**
52
+ * Module-level definition
53
+ * ```
54
+ * `<public> use ...;
55
+ * ```
56
+ */
57
+ UseDeclaration = 'use_declaration',
58
+ FriendDeclaration = 'friend_declaration',
59
+ FriendAccess = 'friend_access',
60
+ UseFun = 'use_fun',
61
+
62
+ // all of the nodes below are implemented in `import-grouping.ts`
63
+ // hence should never be printed directly.
64
+
65
+ UseModule = 'use_module',
66
+ UseMember = 'use_member',
67
+ UseModuleMember = 'use_module_member',
68
+ UseModuleMembers = 'use_module_members',
69
+ ModuleIdentity = 'module_identity',
70
+ }
71
+
72
+ /**
73
+ * Print @see `UseDeclaration.UseDeclaration` node.
74
+ */
75
+ export function printUseDeclaration(
76
+ path: AstPath<Node>,
77
+ options: MoveOptions,
78
+ print: printFn,
79
+ ): Doc {
80
+ const firstChild = path.node.child(0);
81
+ const isPublic = firstChild && firstChild.type === 'public' ? ['public', ' '] : [];
82
+ return [
83
+ ...isPublic, // insert `public` keyword if present
84
+ 'use ',
85
+ path.call(print, 'nonFormattingChildren', 0),
86
+ ';',
87
+ ];
88
+ }
89
+
90
+ /**
91
+ * Print `use_fun` node `module_access` as `module_access`.`function_identifier`
92
+ */
93
+ export function printUseFun(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
94
+ return group([
95
+ 'fun ',
96
+ path.call(print, 'nonFormattingChildren', 0), // module_access
97
+ ' as',
98
+ indent(line),
99
+ path.call(print, 'nonFormattingChildren', 1), // module_access
100
+ '.',
101
+ path.call(print, 'nonFormattingChildren', 2), // function_identifier
102
+ ]);
103
+ }
104
+
105
+ /**
106
+ * Print `friend_declaration` node.
107
+ */
108
+ export function printFriendDeclaration(
109
+ path: AstPath<Node>,
110
+ options: MoveOptions,
111
+ print: printFn,
112
+ ): Doc {
113
+ return group([
114
+ 'friend',
115
+ indent(line),
116
+ path.call(print, 'nonFormattingChildren', 0), // module_access
117
+ ';',
118
+ ]);
119
+ }
120
+
121
+ /**
122
+ * Print `friend_access` node.
123
+ */
124
+ export function printFriendAccess(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
125
+ return path.map(print, 'nonFormattingChildren');
126
+ }
127
+
128
+ /**
129
+ * Print `use_module` node. `module_name`
130
+ * Currently only used for `use` with annotations.
131
+ */
132
+ export function printUseModule(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
133
+ return path.map((e) => {
134
+ if (e.node.type == 'as') return ' as ';
135
+ return print(e);
136
+ }, 'children');
137
+ }
138
+
139
+ /**
140
+ * Print `use_member` node. `member_name`
141
+ * Currently only used for `use` with annotations.
142
+ */
143
+ export function printUseMember(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
144
+ const isGroup = path.node.children.findIndex((e) => e.type == '{');
145
+
146
+ // not found `::{...}`
147
+ if (isGroup == -1) {
148
+ return group(
149
+ path.map((e) => {
150
+ if (e.node.type == 'as') return ' as ';
151
+ if (e.node.type == ',') return [',', line];
152
+ return print(e);
153
+ }, 'children'),
154
+ );
155
+ }
156
+
157
+ const children = path.map(print, 'nonFormattingChildren');
158
+
159
+ return group([
160
+ children[0]!,
161
+ '::{',
162
+ indent(softline),
163
+ indent(join([',', line], children.slice(1))),
164
+ ifBreak(','), // trailing comma
165
+ softline,
166
+ '}',
167
+ ]);
168
+ }
169
+
170
+ /**
171
+ * Print `use_module_member` node. `module_name::member_name`
172
+ * Single statement of direct import;
173
+ * `use address::module_name::member_name;`
174
+ *
175
+ * Wraps the member into a group `{}` if it's too long (if line breaks).
176
+ * Currently only used for `use` with annotations.
177
+ */
178
+ export function printUseModuleMember(
179
+ path: AstPath<Node>,
180
+ options: MoveOptions,
181
+ print: printFn,
182
+ ): Doc {
183
+ return group([
184
+ path.call(print, 'nonFormattingChildren', 0), // module_access
185
+ '::',
186
+ ifBreak(['{', indent(line)]), // wrap with `{` if the member is too long
187
+ indent(path.call(print, 'nonFormattingChildren', 1)), // module_access
188
+ ifBreak([line, '}']), // trailing comma
189
+ ]);
190
+ }
191
+
192
+ /**
193
+ * Print `use_module_members` node. `module_identity::{member_name, member_name}`
194
+ * Currently only used for `use` with annotations.
195
+ */
196
+ export function printUseModuleMembers(
197
+ path: AstPath<Node>,
198
+ options: MoveOptions,
199
+ print: printFn,
200
+ ): Doc {
201
+ const children = path.map(print, 'nonFormattingChildren');
202
+ return group([
203
+ children[0]!,
204
+ '::{',
205
+ indent(softline),
206
+ indent(join([',', line], children.slice(1))),
207
+ ifBreak(','), // trailing comma
208
+ softline,
209
+ '}',
210
+ ]);
211
+ }
212
+
213
+ /**
214
+ * Print the `module_identity` node. `module_identifier::module_name`.
215
+ * Is present in the `use_module_member` and `use_module_members` nodes.
216
+ * Currently only used for `use` with annotations.
217
+ */
218
+ export function printModuleIdentity(
219
+ path: AstPath<Node>,
220
+ options: MoveOptions,
221
+ print: printFn,
222
+ ): Doc {
223
+ return join('::', path.map(print, 'nonFormattingChildren'));
224
+ }
225
+
226
+ /**
227
+ * Checks whether the given path is a `use` import.
228
+ */
229
+ export function isUseImport(node: Node): boolean {
230
+ const firstChild = node.nonFormattingChildren[0]!;
231
+
232
+ return (
233
+ node.type === UseDeclaration.UseDeclaration &&
234
+ (firstChild.type === UseDeclaration.UseModule ||
235
+ firstChild.type === UseDeclaration.UseModuleMember ||
236
+ firstChild.type === UseDeclaration.UseModuleMembers)
237
+ );
238
+ }