@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,28 @@
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 } = doc.builders;
9
+
10
+ /** The type of the node implemented in this file */
11
+ export const NODE_TYPE = 'expression_list';
12
+
13
+ export default function (path: AstPath<Node>): treeFn | null {
14
+ if (path.node.type === NODE_TYPE) {
15
+ return printExpressionList;
16
+ }
17
+
18
+ return null;
19
+ }
20
+
21
+ /**
22
+ * Print `expression_list` node.
23
+ */
24
+ function printExpressionList(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
25
+ return group(list({ path, print, options, open: '(', close: ')' }), {
26
+ shouldBreak: false,
27
+ });
28
+ }
@@ -0,0 +1,30 @@
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 {} = doc.builders;
8
+
9
+ /** The type of the node implemented in this file */
10
+ export const NODE_TYPE = 'identified_expression';
11
+
12
+ export default function (path: AstPath<Node>): treeFn | null {
13
+ if (path.node.type === NODE_TYPE) {
14
+ return printIdentifiedExpression;
15
+ }
16
+
17
+ return null;
18
+ }
19
+
20
+ /**
21
+ * Print `identified_expression` node.
22
+ * Also known as `label` in the grammar or `labeled_expression`.
23
+ */
24
+ function printIdentifiedExpression(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
25
+ return [
26
+ path.call(print, 'nonFormattingChildren', 0), // identifier
27
+ ' ',
28
+ path.call(print, 'nonFormattingChildren', 1), // expression
29
+ ];
30
+ }
@@ -0,0 +1,177 @@
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 { printTrailingComment } from '../../utilities';
8
+ const {
9
+ group,
10
+ softline,
11
+ line,
12
+ ifBreak,
13
+ indent,
14
+ lineSuffix,
15
+ breakParent,
16
+ hardlineWithoutBreakParent,
17
+ } = doc.builders;
18
+
19
+ /** The type of the node implemented in this file */
20
+ export const NODE_TYPE = 'if_expression';
21
+
22
+ export default function (path: AstPath<Node>): treeFn | null {
23
+ if (path.node.type === NODE_TYPE) {
24
+ return printIfExpression;
25
+ }
26
+
27
+ return null;
28
+ }
29
+
30
+ /**
31
+ * Print `if_expression` node.
32
+ *
33
+ * ```
34
+ * // single line
35
+ * if (cond || cond) {}
36
+ *
37
+ * // multi line + block
38
+ * if (
39
+ * long_cond ||
40
+ * long_cond
41
+ * ) {
42
+ * long_expr;
43
+ * long_expr;
44
+ * }
45
+ *
46
+ * // multi line + single line
47
+ * if (cond) {
48
+ * return long_expr;
49
+ * }
50
+ *
51
+ * // multi line + single line + long expr
52
+ * if (
53
+ * long_cond ||
54
+ * long_cond
55
+ * ) {
56
+ * return long_expr &&
57
+ * long_expr;
58
+ * }
59
+ * ```
60
+ */
61
+ function printIfExpression(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
62
+ if (path.node.nonFormattingChildren.length < 2) {
63
+ throw new Error('Invalid if_expression node');
64
+ }
65
+
66
+ const isChain = path.parent?.type == 'if_expression';
67
+ const hasElse = path.node.children.some((e) => e.type == 'else');
68
+ const condition = path.node.nonFormattingChildren[0]!;
69
+ const trueBranch = path.node.nonFormattingChildren[1]!;
70
+ const groupId = Symbol('if_expression_true');
71
+ const result: Doc[] = [];
72
+
73
+ const conditionPrinted = path.call(
74
+ (path) => {
75
+ let trailingComment: Doc = '';
76
+ if (path.node.trailingComment?.type == 'line_comment') {
77
+ trailingComment = lineSuffix(printTrailingComment(path));
78
+ path.node.disableTrailingComment();
79
+ }
80
+
81
+ return [print(path), trailingComment ? [trailingComment, breakParent] : ''];
82
+ },
83
+ 'nonFormattingChildren',
84
+ 0,
85
+ );
86
+
87
+ const conditionGroup = group([
88
+ 'if (',
89
+ condition?.isList
90
+ ? [indent(softline), conditionPrinted, softline]
91
+ : [indent(softline), indent(conditionPrinted), softline],
92
+ ')',
93
+ ]);
94
+
95
+ result.push(conditionGroup);
96
+
97
+ const isTrueList = trueBranch?.isList || false;
98
+ const trueHasComment =
99
+ trueBranch.leadingComment.some((e) => e.type == 'line_comment') ||
100
+ trueBranch.trailingComment?.type == 'line_comment';
101
+
102
+ // true branch group
103
+ if (isTrueList) {
104
+ const truePrinted = path.call(print, 'nonFormattingChildren', 1);
105
+ result.push(group([' ', truePrinted], { shouldBreak: false }));
106
+ } else {
107
+ const truePrinted =
108
+ trueBranch.trailingComment?.type !== 'line_comment'
109
+ ? path.call(print, 'nonFormattingChildren', 1)
110
+ : path.call(
111
+ (path) => {
112
+ const comment = lineSuffix(printTrailingComment(path));
113
+ path.node.disableTrailingComment();
114
+ return [print(path), comment];
115
+ },
116
+ 'nonFormattingChildren',
117
+ 1,
118
+ );
119
+
120
+ result.push(
121
+ group([indent(line), indent(truePrinted)], {
122
+ id: groupId,
123
+ }),
124
+ );
125
+ }
126
+
127
+ // early return if there's no else block
128
+ if (!hasElse) {
129
+ return result;
130
+ }
131
+
132
+ const elseNode = path.node.nonFormattingChildren[2]!;
133
+
134
+ // modify the break condition for the else block
135
+ const elseShouldBreak =
136
+ elseNode.leadingComment.some((e) => e.type == 'line_comment') ||
137
+ elseNode.trailingComment?.type == 'line_comment' ||
138
+ trueHasComment;
139
+
140
+ // if true branch is a list, and there's no line comment, we add a space,
141
+ // if there's a line comment, we add a line break
142
+ //
143
+ // also, if the else block is another `if_expression` we follow the same
144
+ // logic as above
145
+ if (isTrueList) {
146
+ result.push(group([line, 'else'], { shouldBreak: trueHasComment }));
147
+ result.push([' ', path.call(print, 'nonFormattingChildren', 2)]);
148
+ return result;
149
+ }
150
+
151
+ const elseBranchPrinted = path.call(print, 'nonFormattingChildren', 2);
152
+
153
+ // if true branch is not a list, and else is a list, we newline
154
+ if ((elseNode.isList && !isTrueList) || elseNode.type == 'if_expression' || isChain) {
155
+ result.push([hardlineWithoutBreakParent, 'else ', group(elseBranchPrinted)]);
156
+ return result;
157
+ }
158
+
159
+ result.push(
160
+ group([
161
+ ifBreak(
162
+ [
163
+ hardlineWithoutBreakParent,
164
+ 'else',
165
+ group([indent(line), indent(elseBranchPrinted)]),
166
+ ],
167
+ [
168
+ line,
169
+ 'else',
170
+ group([indent(line), elseBranchPrinted], { shouldBreak: elseShouldBreak }),
171
+ ],
172
+ ),
173
+ ]),
174
+ );
175
+
176
+ return result;
177
+ }
@@ -0,0 +1,85 @@
1
+ // Copyright (c) The Move Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * Route through `_expression` nodes.
6
+ *
7
+ * @module src/cst/expression
8
+ */
9
+
10
+ import { Node } from '../..';
11
+ import { treeFn } from '../../printer';
12
+ import { AstPath } from 'prettier';
13
+
14
+ // Folder imports:
15
+ import abort_expression from './abort_expression';
16
+ import annotation_expression from './annotation_expression';
17
+ import assign_expression from './assign_expression';
18
+ import binary_expression from './binary_expression';
19
+ import block_item from './block_item';
20
+ import block from './block';
21
+ import borrow_expression from './borrow_expression';
22
+ import break_expression from './break_expression';
23
+ import call_expression from './call_expression';
24
+ import cast_expression from './cast_expression';
25
+ import continue_expression from './continue_expression';
26
+ import dereference_expression from './dereference_expression';
27
+ import dot_expression from './dot_expression';
28
+ import expression_list from './expression_list';
29
+ import if_expression from './if_expression';
30
+ import identified_expression from './identified_expression';
31
+ import index_expression from './index_expression';
32
+ import lambda_expression from './lambda_expression';
33
+ import let_statement from './let_statement';
34
+ import loop_expression from './loop_expression';
35
+ import macro_call_expression from './macro_call_expression';
36
+ import match_expression from './match_expression';
37
+ import move_or_copy_expression from './move_or_copy_expression';
38
+ import name_expression from './name_expression';
39
+ import pack_expression from './pack_expression';
40
+ import return_expression from './return_expression';
41
+ import unary_expression from './unary_expression';
42
+ import unit_expression from './unit_expression';
43
+ import vector_expression from './vector_expression';
44
+ import while_expression from './while_expression';
45
+
46
+ export default function (path: AstPath<Node>): treeFn | null {
47
+ // route to separated functions
48
+ const result =
49
+ abort_expression(path) ||
50
+ annotation_expression(path) ||
51
+ assign_expression(path) ||
52
+ binary_expression(path) ||
53
+ block_item(path) ||
54
+ block(path) ||
55
+ borrow_expression(path) ||
56
+ break_expression(path) ||
57
+ call_expression(path) ||
58
+ cast_expression(path) ||
59
+ continue_expression(path) ||
60
+ dereference_expression(path) ||
61
+ dot_expression(path) ||
62
+ expression_list(path) ||
63
+ if_expression(path) ||
64
+ identified_expression(path) ||
65
+ index_expression(path) ||
66
+ lambda_expression(path) ||
67
+ let_statement(path) ||
68
+ loop_expression(path) ||
69
+ macro_call_expression(path) ||
70
+ match_expression(path) ||
71
+ move_or_copy_expression(path) ||
72
+ name_expression(path) ||
73
+ pack_expression(path) ||
74
+ return_expression(path) ||
75
+ unary_expression(path) ||
76
+ unit_expression(path) ||
77
+ vector_expression(path) ||
78
+ while_expression(path);
79
+
80
+ if (result !== null) {
81
+ return result;
82
+ }
83
+
84
+ return null;
85
+ }
@@ -0,0 +1,37 @@
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 } = doc.builders;
9
+
10
+ /** The type of the node implemented in this file */
11
+ const NODE_TYPE = 'index_expression';
12
+
13
+ export default function (path: AstPath<Node>): treeFn | null {
14
+ switch (path.node.type) {
15
+ case NODE_TYPE:
16
+ return printIndexExpression;
17
+ }
18
+
19
+ return null;
20
+ }
21
+
22
+ /**
23
+ * Print `index_expression` node.
24
+ */
25
+ export function printIndexExpression(
26
+ path: AstPath<Node>,
27
+ options: MoveOptions,
28
+ print: printFn,
29
+ ): Doc {
30
+ return group(
31
+ [
32
+ path.call(print, 'nonFormattingChildren', 0), // lhs
33
+ list({ path, options, open: '[', close: ']', print, skipChildren: 1 }),
34
+ ],
35
+ { shouldBreak: false },
36
+ );
37
+ }
@@ -0,0 +1,84 @@
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, printNonBreakingBlock } from './block';
8
+ import { list } from '../../utilities';
9
+ const { group, join, conditionalGroup } = doc.builders;
10
+
11
+ /** The type of the node implemented in this file */
12
+ const NODE_TYPE = 'lambda_expression';
13
+
14
+ export default function (path: AstPath<Node>): treeFn | null {
15
+ switch (path.node.type) {
16
+ case NODE_TYPE:
17
+ return printLambdaExpression;
18
+ case 'lambda_bindings':
19
+ return printLambdaBindings;
20
+ case 'lambda_binding':
21
+ return printLambdaBinding;
22
+ }
23
+
24
+ return null;
25
+ }
26
+
27
+ /**
28
+ * Print `labda_expression` node.
29
+ * Inside:
30
+ * - `lambda_bindings`
31
+ * - `_bind`
32
+ */
33
+ function printLambdaExpression(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
34
+ const children = path.node.nonFormattingChildren;
35
+
36
+ // just bindings
37
+ if (children.length === 1) {
38
+ return path.call(print, 'nonFormattingChildren', 0);
39
+ }
40
+
41
+ // bindings, expression or bindings, return type
42
+ if (children.length === 2) {
43
+ return join(' ', path.map(print, 'nonFormattingChildren'));
44
+ }
45
+
46
+ // bindings, return type, expression
47
+ if (children.length === 3) {
48
+ return [
49
+ path.call(print, 'nonFormattingChildren', 0), // bindings
50
+ ' -> ',
51
+ path.call(print, 'nonFormattingChildren', 1), // return type
52
+ ' ',
53
+ path.call(print, 'nonFormattingChildren', 2), // expression
54
+ ];
55
+ }
56
+
57
+ throw new Error('`lambda_expression` node should have 1, 2 or 3 children');
58
+ }
59
+
60
+ /**
61
+ * Print `lambda_bindings` node, contains comma-separated list of `lambda_binding` nodes.
62
+ */
63
+ function printLambdaBindings(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
64
+ return group(list({ path, print, options, open: '|', close: '|' }));
65
+ }
66
+
67
+ /**
68
+ * Print `lambda_binding` node.
69
+ * It can be either type annotated or just a variable binding, we know it by the number
70
+ * of non-formatting children.
71
+ */
72
+ function printLambdaBinding(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
73
+ // simple bind, will be handled by its function
74
+ if (path.node.nonFormattingChildren.length === 1) {
75
+ return path.call(print, 'nonFormattingChildren', 0);
76
+ }
77
+
78
+ // with type annotation
79
+ if (path.node.nonFormattingChildren.length === 2) {
80
+ return join(': ', path.map(print, 'nonFormattingChildren'));
81
+ }
82
+
83
+ throw new Error('`lambda_binding` node should have 1 or 2 children');
84
+ }
@@ -0,0 +1,73 @@
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 { printTrailingComment } from '../../utilities';
8
+ const { group, indent, line, indentIfBreak } = doc.builders;
9
+
10
+ /** The type of the node implemented in this file */
11
+ const NODE_TYPE = 'let_statement';
12
+
13
+ export default function (path: AstPath<Node>): treeFn | null {
14
+ if (path.node.type === NODE_TYPE) {
15
+ return printLetStatement;
16
+ }
17
+
18
+ return null;
19
+ }
20
+
21
+ /**
22
+ * Print `let_statement` node.
23
+ */
24
+ function printLetStatement(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
25
+ const nodes = path.node.nonFormattingChildren;
26
+
27
+ if (nodes.length === 1) {
28
+ return group(['let', ' ', path.call(print, 'nonFormattingChildren', 0)]);
29
+ }
30
+
31
+ function printWithTrailing(path: AstPath<Node>): Doc {
32
+ let trailingComment: Doc = '';
33
+ if (path.node.trailingComment?.type == 'line_comment') {
34
+ trailingComment = printTrailingComment(path, true);
35
+ path.node.disableTrailingComment();
36
+ }
37
+ return [print(path), trailingComment];
38
+ }
39
+
40
+ const printed = path.map(printWithTrailing, 'nonFormattingChildren');
41
+ const rhsNode = path.node.nonFormattingChildren.slice(-1)[0]!;
42
+
43
+ if (nodes.length === 2 && nodes[1]!.isTypeParam) {
44
+ const [bind, type] = printed;
45
+ return group(['let ', bind!, ': ', type!]);
46
+ }
47
+
48
+ if (nodes.length === 2) {
49
+ const [bind, expr] = printed;
50
+ const result =
51
+ rhsNode.isBreakableExpression || rhsNode.isFunctionCall || rhsNode.isControlFlow
52
+ ? ['let ', bind!, ' = ', expr!]
53
+ : ['let ', bind!, ' =', printLetExpression(expr!, rhsNode)];
54
+
55
+ return group(result, { shouldBreak: false });
56
+ }
57
+
58
+ const [bind, type, expr] = printed;
59
+ const result =
60
+ rhsNode.isBreakableExpression || rhsNode.isFunctionCall
61
+ ? ['let ', bind!, ': ', type!, ' = ', expr!]
62
+ : ['let ', bind!, ': ', type!, ' =', printLetExpression(expr!, rhsNode)];
63
+
64
+ return result;
65
+ }
66
+
67
+ function printLetExpression(expression: Doc, node: Node) {
68
+ const groupId = Symbol('let_expression');
69
+ return group([indentIfBreak(line, { groupId }), indentIfBreak(expression, { groupId })], {
70
+ shouldBreak: false,
71
+ id: groupId,
72
+ });
73
+ }
@@ -0,0 +1,29 @@
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 {} = doc.builders;
8
+
9
+ /** The type of the node implemented in this file */
10
+ export const NODE_TYPE = 'loop_expression';
11
+
12
+ export default function (path: AstPath<Node>): treeFn | null {
13
+ if (path.node.type === NODE_TYPE) {
14
+ return printLoopExpression;
15
+ }
16
+
17
+ return null;
18
+ }
19
+
20
+ /**
21
+ * Print `loop_expression` node.
22
+ *
23
+ * ```
24
+ * loop `_expression`
25
+ * ```
26
+ */
27
+ function printLoopExpression(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
28
+ return [`loop `, path.call(print, 'nonFormattingChildren', 0)];
29
+ }
@@ -0,0 +1,79 @@
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, indentIfBreak, line, softline, ifBreak, join } = doc.builders;
9
+
10
+ /** The type of the node implemented in this file */
11
+ const NODE_TYPE = 'macro_call_expression';
12
+
13
+ export default function (path: AstPath<Node>): treeFn | null {
14
+ if (path.node.type === NODE_TYPE) {
15
+ return printMacroCallExpression;
16
+ }
17
+
18
+ return null;
19
+ }
20
+
21
+ /**
22
+ * Print `macro_call_expression` node.
23
+ * Inside:
24
+ * - `macro_module_access`
25
+ * - `type_arguments`
26
+ * - `arg_list`
27
+ */
28
+ function printMacroCallExpression(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
29
+ return path.map((path) => {
30
+ if (path.node.type === 'macro_module_access') {
31
+ return printMacroModuleAccess(path, options, print);
32
+ }
33
+
34
+ if (path.node.type === 'arg_list') {
35
+ return printMacroArgsList(path, options, print);
36
+ }
37
+
38
+ return print(path);
39
+ }, 'nonFormattingChildren');
40
+ }
41
+
42
+ /**
43
+ * Print `macro_module_access` node.
44
+ * Inside:
45
+ * - `module_access`
46
+ * - `!`
47
+ */
48
+ function printMacroModuleAccess(path: AstPath<Node>, options: MoveOptions, print: printFn): Doc {
49
+ return [path.call(print, 'nonFormattingChildren', 0), '!'];
50
+ }
51
+
52
+ /**
53
+ * Special function to print macro arguments list instead of `arg_list`.
54
+ */
55
+ function printMacroArgsList(path: AstPath<Node>, options: MoveOptions, print: printFn) {
56
+ if (path.node.type !== 'arg_list') {
57
+ throw new Error('Expected `arg_list` node');
58
+ }
59
+
60
+ if (path.node.namedChildCount === 0) {
61
+ return '()';
62
+ }
63
+
64
+ const groupId = Symbol('macro_args_list');
65
+
66
+ return group(
67
+ list({
68
+ path,
69
+ options,
70
+ print,
71
+ open: '(',
72
+ close: ')',
73
+ addWhitespace: false,
74
+ shouldBreak: false,
75
+ indentGroup: groupId,
76
+ }),
77
+ { id: groupId },
78
+ );
79
+ }