@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.
- package/CHANGELOG.md +67 -0
- package/CONTRIBUTING.md +31 -0
- package/README.md +96 -0
- package/bin/prettier-move.js +29 -0
- package/out/cst/annotation.js +64 -0
- package/out/cst/annotation.js.map +1 -0
- package/out/cst/common.js +376 -0
- package/out/cst/common.js.map +1 -0
- package/out/cst/constant.js +92 -0
- package/out/cst/constant.js.map +1 -0
- package/out/cst/enum_definition.js +69 -0
- package/out/cst/enum_definition.js.map +1 -0
- package/out/cst/expression/abort_expression.js +32 -0
- package/out/cst/expression/abort_expression.js.map +1 -0
- package/out/cst/expression/annotation_expression.js +35 -0
- package/out/cst/expression/annotation_expression.js.map +1 -0
- package/out/cst/expression/assign_expression.js +51 -0
- package/out/cst/expression/assign_expression.js.map +1 -0
- package/out/cst/expression/binary_expression.js +70 -0
- package/out/cst/expression/binary_expression.js.map +1 -0
- package/out/cst/expression/block.js +58 -0
- package/out/cst/expression/block.js.map +1 -0
- package/out/cst/expression/block_item.js +25 -0
- package/out/cst/expression/block_item.js.map +1 -0
- package/out/cst/expression/borrow_expression.js +26 -0
- package/out/cst/expression/borrow_expression.js.map +1 -0
- package/out/cst/expression/break_expression.js +27 -0
- package/out/cst/expression/break_expression.js.map +1 -0
- package/out/cst/expression/call_expression.js +25 -0
- package/out/cst/expression/call_expression.js.map +1 -0
- package/out/cst/expression/cast_expression.js +31 -0
- package/out/cst/expression/cast_expression.js.map +1 -0
- package/out/cst/expression/continue_expression.js +26 -0
- package/out/cst/expression/continue_expression.js.map +1 -0
- package/out/cst/expression/dereference_expression.js +27 -0
- package/out/cst/expression/dereference_expression.js.map +1 -0
- package/out/cst/expression/dot_expression.js +66 -0
- package/out/cst/expression/dot_expression.js.map +1 -0
- package/out/cst/expression/expression_list.js +26 -0
- package/out/cst/expression/expression_list.js.map +1 -0
- package/out/cst/expression/identified_expression.js +28 -0
- package/out/cst/expression/identified_expression.js.map +1 -0
- package/out/cst/expression/if_expression.js +133 -0
- package/out/cst/expression/if_expression.js.map +1 -0
- package/out/cst/expression/index.js +74 -0
- package/out/cst/expression/index.js.map +1 -0
- package/out/cst/expression/index_expression.js +28 -0
- package/out/cst/expression/index_expression.js.map +1 -0
- package/out/cst/expression/lambda_expression.js +72 -0
- package/out/cst/expression/lambda_expression.js.map +1 -0
- package/out/cst/expression/let_statement.js +59 -0
- package/out/cst/expression/let_statement.js.map +1 -0
- package/out/cst/expression/loop_expression.js +27 -0
- package/out/cst/expression/loop_expression.js.map +1 -0
- package/out/cst/expression/macro_call_expression.js +66 -0
- package/out/cst/expression/macro_call_expression.js.map +1 -0
- package/out/cst/expression/match_expression.js +86 -0
- package/out/cst/expression/match_expression.js.map +1 -0
- package/out/cst/expression/move_or_copy_expression.js +27 -0
- package/out/cst/expression/move_or_copy_expression.js.map +1 -0
- package/out/cst/expression/name_expression.js +26 -0
- package/out/cst/expression/name_expression.js.map +1 -0
- package/out/cst/expression/pack_expression.js +27 -0
- package/out/cst/expression/pack_expression.js.map +1 -0
- package/out/cst/expression/return_expression.js +44 -0
- package/out/cst/expression/return_expression.js.map +1 -0
- package/out/cst/expression/unary_expression.js +26 -0
- package/out/cst/expression/unary_expression.js.map +1 -0
- package/out/cst/expression/unit_expression.js +17 -0
- package/out/cst/expression/unit_expression.js.map +1 -0
- package/out/cst/expression/vector_expression.js +80 -0
- package/out/cst/expression/vector_expression.js.map +1 -0
- package/out/cst/expression/while_expression.js +42 -0
- package/out/cst/expression/while_expression.js.map +1 -0
- package/out/cst/formatting.js +100 -0
- package/out/cst/formatting.js.map +1 -0
- package/out/cst/function_definition.js +248 -0
- package/out/cst/function_definition.js.map +1 -0
- package/out/cst/literal.js +68 -0
- package/out/cst/literal.js.map +1 -0
- package/out/cst/module.js +158 -0
- package/out/cst/module.js.map +1 -0
- package/out/cst/source_file.js +38 -0
- package/out/cst/source_file.js.map +1 -0
- package/out/cst/struct_definition.js +209 -0
- package/out/cst/struct_definition.js.map +1 -0
- package/out/cst/use_declaration.js +212 -0
- package/out/cst/use_declaration.js.map +1 -0
- package/out/imports-grouping.js +259 -0
- package/out/imports-grouping.js.map +1 -0
- package/out/index.js +97 -0
- package/out/index.js.map +1 -0
- package/out/printer.js +69 -0
- package/out/printer.js.map +1 -0
- package/out/tree.js +371 -0
- package/out/tree.js.map +1 -0
- package/out/utilities.js +251 -0
- package/out/utilities.js.map +1 -0
- package/package.json +34 -0
- package/prettier.config.js +12 -0
- package/src/cst/annotation.ts +71 -0
- package/src/cst/common.ts +430 -0
- package/src/cst/constant.ts +110 -0
- package/src/cst/enum_definition.ts +73 -0
- package/src/cst/expression/abort_expression.ts +35 -0
- package/src/cst/expression/annotation_expression.ts +38 -0
- package/src/cst/expression/assign_expression.ts +66 -0
- package/src/cst/expression/binary_expression.ts +75 -0
- package/src/cst/expression/block.ts +72 -0
- package/src/cst/expression/block_item.ts +29 -0
- package/src/cst/expression/borrow_expression.ts +28 -0
- package/src/cst/expression/break_expression.ts +33 -0
- package/src/cst/expression/call_expression.ts +28 -0
- package/src/cst/expression/cast_expression.ts +35 -0
- package/src/cst/expression/continue_expression.ts +29 -0
- package/src/cst/expression/dereference_expression.ts +33 -0
- package/src/cst/expression/dot_expression.ts +89 -0
- package/src/cst/expression/expression_list.ts +28 -0
- package/src/cst/expression/identified_expression.ts +30 -0
- package/src/cst/expression/if_expression.ts +177 -0
- package/src/cst/expression/index.ts +85 -0
- package/src/cst/expression/index_expression.ts +37 -0
- package/src/cst/expression/lambda_expression.ts +84 -0
- package/src/cst/expression/let_statement.ts +73 -0
- package/src/cst/expression/loop_expression.ts +29 -0
- package/src/cst/expression/macro_call_expression.ts +79 -0
- package/src/cst/expression/match_expression.ts +102 -0
- package/src/cst/expression/move_or_copy_expression.ts +29 -0
- package/src/cst/expression/name_expression.ts +28 -0
- package/src/cst/expression/pack_expression.ts +29 -0
- package/src/cst/expression/return_expression.ts +50 -0
- package/src/cst/expression/unary_expression.ts +28 -0
- package/src/cst/expression/unit_expression.ts +18 -0
- package/src/cst/expression/vector_expression.ts +97 -0
- package/src/cst/expression/while_expression.ts +45 -0
- package/src/cst/formatting.ts +100 -0
- package/src/cst/function_definition.ts +300 -0
- package/src/cst/literal.ts +69 -0
- package/src/cst/module.ts +191 -0
- package/src/cst/source_file.ts +38 -0
- package/src/cst/struct_definition.ts +267 -0
- package/src/cst/use_declaration.ts +238 -0
- package/src/imports-grouping.ts +300 -0
- package/src/index.ts +119 -0
- package/src/printer.ts +93 -0
- package/src/tree.ts +438 -0
- package/src/utilities.ts +387 -0
- package/tree-sitter-move.wasm +0 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,300 @@
|
|
|
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 { printBreakableBlock } from './expression/block';
|
|
8
|
+
import { list, printIdentifier } from '../utilities';
|
|
9
|
+
const { join, group } = doc.builders;
|
|
10
|
+
|
|
11
|
+
export default function (path: AstPath<Node>): treeFn | null {
|
|
12
|
+
switch (path.node.type) {
|
|
13
|
+
case FunctionDefinition.NativeFunctionDefinition:
|
|
14
|
+
return printNativeFunctionDefinition;
|
|
15
|
+
case FunctionDefinition.FunctionDefinition:
|
|
16
|
+
return printFunctionDefinition;
|
|
17
|
+
case FunctionDefinition.MacroFunctionDefinition:
|
|
18
|
+
return printMacroFunctionDefinition;
|
|
19
|
+
case FunctionDefinition.VisibilityModifier:
|
|
20
|
+
return printVisibilityModifier;
|
|
21
|
+
case FunctionDefinition.FunctionParameters:
|
|
22
|
+
return printFunctionParameters;
|
|
23
|
+
case FunctionDefinition.FunctionParameter:
|
|
24
|
+
return printFunctionParameter;
|
|
25
|
+
case FunctionDefinition.MutFunctionParameter:
|
|
26
|
+
return printMutFunctionParameter;
|
|
27
|
+
case FunctionDefinition.ReturnType:
|
|
28
|
+
return printReturnType;
|
|
29
|
+
case FunctionDefinition.TypeArguments:
|
|
30
|
+
return printTypeArguments;
|
|
31
|
+
case FunctionDefinition.TypeParameters:
|
|
32
|
+
return printTypeParameters;
|
|
33
|
+
case FunctionDefinition.TypeParameter:
|
|
34
|
+
return printTypeParameter;
|
|
35
|
+
|
|
36
|
+
// identifiers
|
|
37
|
+
case FunctionDefinition.FunctionIdentifier:
|
|
38
|
+
case FunctionDefinition.TypeParameterIdentifier:
|
|
39
|
+
return printIdentifier;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Function Definition, contains the following:
|
|
47
|
+
* ```
|
|
48
|
+
* <visibility> fun <identifier> (<parameters>) <return_type> <body>
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export enum FunctionDefinition {
|
|
52
|
+
FunctionDefinition = 'function_definition',
|
|
53
|
+
FunctionIdentifier = 'function_identifier',
|
|
54
|
+
NativeFunctionDefinition = 'native_function_definition',
|
|
55
|
+
MacroFunctionDefinition = 'macro_function_definition',
|
|
56
|
+
VisibilityModifier = 'visibility_modifier',
|
|
57
|
+
FunctionParameters = 'function_parameters',
|
|
58
|
+
FunctionParameter = 'function_parameter',
|
|
59
|
+
MutFunctionParameter = 'mut_function_parameter',
|
|
60
|
+
ReturnType = 'ret_type',
|
|
61
|
+
TypeArguments = 'type_arguments',
|
|
62
|
+
TypeParameters = 'type_parameters',
|
|
63
|
+
TypeParameter = 'type_parameter',
|
|
64
|
+
TypeParameterIdentifier = 'type_parameter_identifier',
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type Modifiers = {
|
|
68
|
+
native?: boolean;
|
|
69
|
+
public?: boolean;
|
|
70
|
+
entry?: boolean;
|
|
71
|
+
['public(friend)']?: boolean;
|
|
72
|
+
['public(package)']?: boolean;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Print `function_definition` node.
|
|
77
|
+
*/
|
|
78
|
+
export function printFunctionDefinition(
|
|
79
|
+
path: AstPath<Node>,
|
|
80
|
+
options: MoveOptions,
|
|
81
|
+
print: printFn,
|
|
82
|
+
): Doc {
|
|
83
|
+
const nodes = path.node.nonFormattingChildren;
|
|
84
|
+
const retIndex = nodes.findIndex((e) => e.type == FunctionDefinition.ReturnType);
|
|
85
|
+
const modifiers = getModifiers(path);
|
|
86
|
+
const printCb = (path: AstPath<Node>) =>
|
|
87
|
+
path.node.type === 'block' ? printBreakableBlock(path, options, print) : print(path);
|
|
88
|
+
|
|
89
|
+
const signature = [
|
|
90
|
+
printModifiers(modifiers),
|
|
91
|
+
'fun ',
|
|
92
|
+
path.map((path) => {
|
|
93
|
+
// We already added modifiers in the previous step
|
|
94
|
+
if (path.node.type == 'modifier') return '';
|
|
95
|
+
if (path.node.type == 'block') return '';
|
|
96
|
+
if (path.node.type == 'ret_type') return '';
|
|
97
|
+
if (path.node.isFormatting) return '';
|
|
98
|
+
|
|
99
|
+
return print(path);
|
|
100
|
+
}, 'nonFormattingChildren'),
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
return [
|
|
104
|
+
group([signature, path.call(print, 'nonFormattingChildren', retIndex)]),
|
|
105
|
+
' ',
|
|
106
|
+
path.call(printCb, 'nonFormattingChildren', nodes.length - 1),
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function printNativeFunctionDefinition(
|
|
111
|
+
path: AstPath<Node>,
|
|
112
|
+
_opt: MoveOptions,
|
|
113
|
+
print: printFn,
|
|
114
|
+
): Doc {
|
|
115
|
+
const modifiers = getModifiers(path);
|
|
116
|
+
|
|
117
|
+
return [
|
|
118
|
+
printModifiers(modifiers),
|
|
119
|
+
'fun ',
|
|
120
|
+
group(
|
|
121
|
+
path.map((path) => {
|
|
122
|
+
if (path.node.type == 'modifier') return '';
|
|
123
|
+
return print(path);
|
|
124
|
+
}, 'nonFormattingChildren'),
|
|
125
|
+
),
|
|
126
|
+
';',
|
|
127
|
+
];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Print `macro_function_definition` node.
|
|
132
|
+
*/
|
|
133
|
+
export function printMacroFunctionDefinition(
|
|
134
|
+
path: AstPath<Node>,
|
|
135
|
+
_opt: MoveOptions,
|
|
136
|
+
print: printFn,
|
|
137
|
+
): Doc {
|
|
138
|
+
const modifiers = getModifiers(path);
|
|
139
|
+
|
|
140
|
+
return [
|
|
141
|
+
printModifiers(modifiers),
|
|
142
|
+
'macro fun ',
|
|
143
|
+
group(
|
|
144
|
+
path.map((path) => {
|
|
145
|
+
if (path.node.type == 'modifier') return '';
|
|
146
|
+
if (path.node.type == 'block') return '';
|
|
147
|
+
return print(path);
|
|
148
|
+
}, 'nonFormattingChildren'),
|
|
149
|
+
),
|
|
150
|
+
' ',
|
|
151
|
+
path.call(print, 'nonFormattingChildren', path.node.nonFormattingChildren.length - 1),
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Print `visibility_modifier` node.
|
|
157
|
+
* Always followed by a space.
|
|
158
|
+
*/
|
|
159
|
+
export function printVisibilityModifier(
|
|
160
|
+
path: AstPath<Node>, // | Node | null,
|
|
161
|
+
_opt: MoveOptions,
|
|
162
|
+
_print: printFn,
|
|
163
|
+
): Doc {
|
|
164
|
+
return [path.node.text, ' '];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Print `function_parameters` node.
|
|
169
|
+
*/
|
|
170
|
+
export function printFunctionParameters(
|
|
171
|
+
path: AstPath<Node>,
|
|
172
|
+
options: MoveOptions,
|
|
173
|
+
print: printFn,
|
|
174
|
+
): Doc {
|
|
175
|
+
return list({
|
|
176
|
+
path,
|
|
177
|
+
print,
|
|
178
|
+
options,
|
|
179
|
+
open: '(',
|
|
180
|
+
close: ')',
|
|
181
|
+
shouldBreak: false,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Print `function_parameter` node.
|
|
187
|
+
*/
|
|
188
|
+
export function printFunctionParameter(
|
|
189
|
+
path: AstPath<Node>,
|
|
190
|
+
_opt: MoveOptions,
|
|
191
|
+
print: printFn,
|
|
192
|
+
): Doc {
|
|
193
|
+
const isMut = path.node.child(0)?.type == 'mut';
|
|
194
|
+
const isDollar = path.node.children.find((c) => c.type == '$');
|
|
195
|
+
|
|
196
|
+
return group([
|
|
197
|
+
isMut ? 'mut ' : '',
|
|
198
|
+
isDollar ? '$' : '',
|
|
199
|
+
path.call(print, 'nonFormattingChildren', 0), // variable_identifier
|
|
200
|
+
': ',
|
|
201
|
+
path.call(print, 'nonFormattingChildren', 1), // type
|
|
202
|
+
]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Print `mut` function parameter.
|
|
207
|
+
*/
|
|
208
|
+
export function printMutFunctionParameter(
|
|
209
|
+
path: AstPath<Node>,
|
|
210
|
+
_opt: MoveOptions,
|
|
211
|
+
print: printFn,
|
|
212
|
+
): Doc {
|
|
213
|
+
return ['mut ', path.call(print, 'nonFormattingChildren', 0)];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Print `ret_type` node.
|
|
218
|
+
*/
|
|
219
|
+
export function printReturnType(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
|
|
220
|
+
return [': ', path.call(print, 'nonFormattingChildren', 0)];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Print `type_arguments` node.
|
|
225
|
+
*/
|
|
226
|
+
export function printTypeArguments(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
|
|
227
|
+
return group(
|
|
228
|
+
list({
|
|
229
|
+
path,
|
|
230
|
+
print,
|
|
231
|
+
options,
|
|
232
|
+
open: '<',
|
|
233
|
+
close: '>',
|
|
234
|
+
shouldBreak: false,
|
|
235
|
+
}),
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Print `type_parameters` node.
|
|
241
|
+
*/
|
|
242
|
+
export function printTypeParameters(
|
|
243
|
+
path: AstPath<Node>,
|
|
244
|
+
options: MoveOptions,
|
|
245
|
+
print: printFn,
|
|
246
|
+
): Doc {
|
|
247
|
+
return group(
|
|
248
|
+
list({
|
|
249
|
+
path,
|
|
250
|
+
print,
|
|
251
|
+
options,
|
|
252
|
+
open: '<',
|
|
253
|
+
close: '>',
|
|
254
|
+
shouldBreak: false,
|
|
255
|
+
}),
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Print `type_parameter` node.
|
|
261
|
+
*/
|
|
262
|
+
export function printTypeParameter(path: AstPath<Node>, _opt: MoveOptions, print: printFn): Doc {
|
|
263
|
+
const isDollar = path.node.child(0)?.type == '$';
|
|
264
|
+
const isPhantom = path.node.child(0)?.type == 'phantom';
|
|
265
|
+
const parameter = path.call(print, 'nonFormattingChildren', 0);
|
|
266
|
+
const abilities = path.map(print, 'nonFormattingChildren').slice(1);
|
|
267
|
+
|
|
268
|
+
return [
|
|
269
|
+
isDollar ? '$' : '',
|
|
270
|
+
isPhantom ? 'phantom ' : '',
|
|
271
|
+
parameter,
|
|
272
|
+
abilities.length > 0 ? ': ' : '',
|
|
273
|
+
join(' + ', abilities),
|
|
274
|
+
];
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Helper function to get modifiers.
|
|
279
|
+
*/
|
|
280
|
+
function getModifiers(path: AstPath<Node>): Modifiers {
|
|
281
|
+
const nodes = path.node.nonFormattingChildren;
|
|
282
|
+
|
|
283
|
+
return nodes
|
|
284
|
+
.filter((e) => e.type == 'modifier')
|
|
285
|
+
.map((e) => e.text.replace(' ', '')) // removes the space in `public (package)`
|
|
286
|
+
.reduce((acc, e) => ({ ...acc, [e]: true }), {});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Helper function to print modifiers.
|
|
291
|
+
*/
|
|
292
|
+
function printModifiers(modifiers: Modifiers): Doc {
|
|
293
|
+
return [
|
|
294
|
+
modifiers.public ? 'public ' : '',
|
|
295
|
+
modifiers['public(package)'] ? 'public(package) ' : '',
|
|
296
|
+
modifiers['public(friend)'] ? 'public(friend) ' : '',
|
|
297
|
+
modifiers.entry ? 'entry ' : '',
|
|
298
|
+
modifiers.native ? 'native ' : '',
|
|
299
|
+
];
|
|
300
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Copyright (c) The Move Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { AstPath, Doc } from 'prettier';
|
|
5
|
+
import { Node } from '..';
|
|
6
|
+
import { treeFn } from '../printer';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Node: `_literal_value` in the grammar.json.
|
|
10
|
+
*/
|
|
11
|
+
export enum Literal {
|
|
12
|
+
AddressLiteral = 'address_literal',
|
|
13
|
+
BoolLiteral = 'bool_literal',
|
|
14
|
+
NumLiteral = 'num_literal',
|
|
15
|
+
HexStringLiteral = 'hex_string_literal',
|
|
16
|
+
ByteStringLiteral = 'byte_string_literal',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default function (path: AstPath<Node>): treeFn | null {
|
|
20
|
+
switch (path.node.type) {
|
|
21
|
+
case Literal.AddressLiteral:
|
|
22
|
+
return printAddressLiteral;
|
|
23
|
+
case Literal.BoolLiteral:
|
|
24
|
+
return printBoolLiteral;
|
|
25
|
+
case Literal.NumLiteral:
|
|
26
|
+
return printNumLiteral;
|
|
27
|
+
case Literal.HexStringLiteral:
|
|
28
|
+
return printHexStringLiteral;
|
|
29
|
+
case Literal.ByteStringLiteral:
|
|
30
|
+
return printByteStringLiteral;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Print `byte_string_literal` node.
|
|
38
|
+
*/
|
|
39
|
+
export function printByteStringLiteral(path: AstPath<Node>): Doc {
|
|
40
|
+
return path.node.text;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Print `bool_literal` node.
|
|
45
|
+
*/
|
|
46
|
+
export function printBoolLiteral(path: AstPath<Node>): Doc {
|
|
47
|
+
return path.node.text;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Print `num_literal` node.
|
|
52
|
+
*/
|
|
53
|
+
export function printNumLiteral(path: AstPath<Node>): Doc {
|
|
54
|
+
return path.node.text;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Print `address_literal` node.
|
|
59
|
+
*/
|
|
60
|
+
export function printAddressLiteral(path: AstPath<Node>): Doc {
|
|
61
|
+
return path.node.text;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Print `hex_literal` node.
|
|
66
|
+
*/
|
|
67
|
+
export function printHexStringLiteral(path: AstPath<Node>): Doc {
|
|
68
|
+
return path.node.text;
|
|
69
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
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 { FunctionDefinition } from './function_definition';
|
|
8
|
+
import { StructDefinition } from './struct_definition';
|
|
9
|
+
import * as Constant from './constant';
|
|
10
|
+
import { UseDeclaration } from './use_declaration';
|
|
11
|
+
import { printImports, collectImports } from '../imports-grouping';
|
|
12
|
+
import { EnumDefinition } from './enum_definition';
|
|
13
|
+
import { printIdentifier } from '../utilities';
|
|
14
|
+
const { join, hardline, indent } = doc.builders;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Creates a callback function to print modules and module-related nodes.
|
|
18
|
+
*/
|
|
19
|
+
export default function (path: AstPath<Node>): treeFn | null {
|
|
20
|
+
switch (path.node.type) {
|
|
21
|
+
case Module.ModuleExtensionDefinition:
|
|
22
|
+
return printModuleExtensionDefinition;
|
|
23
|
+
case Module.ModuleDefinition:
|
|
24
|
+
return printModuleDefinition;
|
|
25
|
+
case Module.ModuleIdentity:
|
|
26
|
+
return printModuleIdentity;
|
|
27
|
+
case Module.ModuleIdentifier:
|
|
28
|
+
return printIdentifier;
|
|
29
|
+
case Module.ModuleBody:
|
|
30
|
+
return printModuleBody;
|
|
31
|
+
default:
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Module - top-level definition in a Move source file.
|
|
38
|
+
*/
|
|
39
|
+
export enum Module {
|
|
40
|
+
ModuleExtensionDefinition = 'module_extension_definition',
|
|
41
|
+
ModuleDefinition = 'module_definition',
|
|
42
|
+
BlockComment = 'block_comment',
|
|
43
|
+
ModuleIdentity = 'module_identity',
|
|
44
|
+
ModuleIdentifier = 'module_identifier',
|
|
45
|
+
ModuleBody = 'module_body',
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Print `module_extension_definition` node.
|
|
50
|
+
*/
|
|
51
|
+
export function printModuleExtensionDefinition(
|
|
52
|
+
path: AstPath<Node>,
|
|
53
|
+
_options: MoveOptions,
|
|
54
|
+
print: printFn,
|
|
55
|
+
): Doc {
|
|
56
|
+
return ['extend ', path.call(print, 'nonFormattingChildren', 0)];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Print `module_definition` node.
|
|
61
|
+
*/
|
|
62
|
+
export function printModuleDefinition(
|
|
63
|
+
path: AstPath<Node>,
|
|
64
|
+
options: MoveOptions,
|
|
65
|
+
print: printFn,
|
|
66
|
+
): Doc {
|
|
67
|
+
let useLabel = false;
|
|
68
|
+
|
|
69
|
+
// when option is present we must check that there's only one module per file
|
|
70
|
+
if (options.useModuleLabel) {
|
|
71
|
+
const modules = path.parent!.nonFormattingChildren.filter(
|
|
72
|
+
(node) =>
|
|
73
|
+
node.type === 'module_definition' || node.type === 'module_extension_definition',
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
useLabel = modules.length == 1;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// module definition can be a part of the extension, do decide whether to use
|
|
80
|
+
// the label for it, we need to check its parent's parent
|
|
81
|
+
if (options.useModuleLabel && path.parent!.type === 'module_extension_definition') {
|
|
82
|
+
const modules = path.parent!.parent!.nonFormattingChildren.filter(
|
|
83
|
+
(node) =>
|
|
84
|
+
node.type === 'module_definition' || node.type === 'module_extension_definition',
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
useLabel = modules.length == 1;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const result = ['module ', path.call(print, 'nonFormattingChildren', 0)];
|
|
91
|
+
|
|
92
|
+
// if we're using the label, we must add a semicolon and print the body in a
|
|
93
|
+
// new line
|
|
94
|
+
if (useLabel) {
|
|
95
|
+
// print hard lines only if there is more than one child
|
|
96
|
+
if (path.node.nonFormattingChildren[1]!.children.length > 1) {
|
|
97
|
+
return result.concat([
|
|
98
|
+
';',
|
|
99
|
+
hardline,
|
|
100
|
+
hardline,
|
|
101
|
+
path.call(print, 'nonFormattingChildren', 1),
|
|
102
|
+
]);
|
|
103
|
+
} else {
|
|
104
|
+
return result.concat([';']);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// when not module mabel, module body is a block with curly braces and
|
|
109
|
+
// indentation
|
|
110
|
+
return result.concat([
|
|
111
|
+
' {',
|
|
112
|
+
indent(hardline),
|
|
113
|
+
indent(path.call(print, 'nonFormattingChildren', 1)),
|
|
114
|
+
hardline,
|
|
115
|
+
'}',
|
|
116
|
+
]);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Print `module_identity` node.
|
|
121
|
+
*/
|
|
122
|
+
function printModuleIdentity(path: AstPath<Node>, options: ParserOptions, print: printFn): Doc {
|
|
123
|
+
return join('::', path.map(print, 'nonFormattingChildren'));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Members that must be separated by an empty line if they are next to each other.
|
|
128
|
+
* For example, a function definition followed by a struct definition.
|
|
129
|
+
*/
|
|
130
|
+
const separatedMembers = [
|
|
131
|
+
FunctionDefinition.FunctionDefinition,
|
|
132
|
+
StructDefinition.StructDefinition,
|
|
133
|
+
Constant.NODE_TYPE,
|
|
134
|
+
UseDeclaration.UseDeclaration,
|
|
135
|
+
UseDeclaration.FriendDeclaration,
|
|
136
|
+
EnumDefinition.EnumDefinition,
|
|
137
|
+
] as string[];
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Print `module_body` node.
|
|
141
|
+
*
|
|
142
|
+
* We need to preserve spacing between members (functions, structs, constants, etc.).
|
|
143
|
+
* We need to only allow a single empty line (if there are more than one, we should remove them).
|
|
144
|
+
* Additionally, if `groupImports` is set to `package` or `module`, we should group imports and
|
|
145
|
+
* print them at the top of the module.
|
|
146
|
+
*/
|
|
147
|
+
function printModuleBody(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
|
|
148
|
+
const nodes = path.node.namedAndEmptyLineChildren;
|
|
149
|
+
const importsDoc = [] as Doc[];
|
|
150
|
+
const imports = collectImports(path.node);
|
|
151
|
+
if (imports.size > 0) {
|
|
152
|
+
importsDoc.push(
|
|
153
|
+
...(printImports(imports, options.autoGroupImports as 'package' | 'module') as Doc[]),
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const bodyDoc = [] as Doc[];
|
|
158
|
+
|
|
159
|
+
path.each((path, i) => {
|
|
160
|
+
const next = nodes[i + 1];
|
|
161
|
+
|
|
162
|
+
// empty lines should be removed if they are next to grouped imports
|
|
163
|
+
if (path.node.isEmptyLine && path.node.previousNamedSibling?.isGroupedImport) return;
|
|
164
|
+
if (path.node.isGroupedImport) return;
|
|
165
|
+
if (path.node.isEmptyLine && !path.node.previousNamedSibling) return;
|
|
166
|
+
|
|
167
|
+
if (
|
|
168
|
+
separatedMembers.includes(path.node.type) &&
|
|
169
|
+
separatedMembers.includes(next?.type || '') &&
|
|
170
|
+
path.node.type !== next?.type
|
|
171
|
+
) {
|
|
172
|
+
return bodyDoc.push([path.call(print), hardline]);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// force add empty line after function definitions
|
|
176
|
+
if (
|
|
177
|
+
path.node.type === FunctionDefinition.FunctionDefinition &&
|
|
178
|
+
next?.type === FunctionDefinition.FunctionDefinition
|
|
179
|
+
) {
|
|
180
|
+
return bodyDoc.push([path.call(print), hardline]);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return bodyDoc.push(path.call(print));
|
|
184
|
+
}, 'namedAndEmptyLineChildren');
|
|
185
|
+
|
|
186
|
+
if (bodyDoc.length > 0 && importsDoc.length > 0) {
|
|
187
|
+
bodyDoc.unshift(''); // add empty line before first member
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return join(hardline, importsDoc.concat(bodyDoc));
|
|
191
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
const { hardline, join } = doc.builders;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Print a source node.
|
|
11
|
+
*/
|
|
12
|
+
export default function (path: AstPath<Node>): treeFn | null {
|
|
13
|
+
switch (path.node.type) {
|
|
14
|
+
case SourceFile.SourceFile:
|
|
15
|
+
return printSourceFile;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export enum SourceFile {
|
|
21
|
+
SourceFile = 'source_file',
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Print `source_file` node.
|
|
26
|
+
*
|
|
27
|
+
* Print all non-formatting children separated by a hardline.
|
|
28
|
+
* Also print empty lines with leading comments, this allows us to maintain structure like this:
|
|
29
|
+
* ```
|
|
30
|
+
* // Copyright
|
|
31
|
+
* `empty_line`
|
|
32
|
+
* // module comment
|
|
33
|
+
* module book::book { ... }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function printSourceFile(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
|
|
37
|
+
return [join(hardline, path.map(print, 'namedAndEmptyLineChildren')), hardline];
|
|
38
|
+
}
|