Skip to content

Commit 1b5448a

Browse files
committed
moving chain printer logic into a separate function
1 parent 9c1f96a commit 1b5448a

5 files changed

Lines changed: 50 additions & 47 deletions

File tree

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { NonterminalKind } from '@nomicfoundation/slang/cst';
2-
import { doc } from 'prettier';
3-
import { isLabel } from '../slang-utils/is-label.js';
4-
import { printGroupAndIndentIfBreakPair } from '../slang-printers/print-group-and-indent-if-break-pair.js';
52
import { extractVariant } from '../slang-utils/extract-variant.js';
3+
import { printPossibleMemberAccessChainItem } from '../slang-printers/print-member-access-chain-item.js';
64
import { SlangNode } from './SlangNode.js';
75
import { Expression } from './Expression.js';
86
import { ArgumentsDeclaration } from './ArgumentsDeclaration.js';
@@ -12,8 +10,6 @@ import type { AstPath, Doc, ParserOptions } from 'prettier';
1210
import type { CollectedMetadata, PrintFunction } from '../types.d.ts';
1311
import type { AstNode } from './types.d.ts';
1412

15-
const { label } = doc.builders;
16-
1713
export class FunctionCallExpression extends SlangNode {
1814
readonly kind = NonterminalKind.FunctionCallExpression;
1915

@@ -39,20 +35,9 @@ export class FunctionCallExpression extends SlangNode {
3935
}
4036

4137
print(path: AstPath<FunctionCallExpression>, print: PrintFunction): Doc {
42-
const operand = path.call(print, 'operand');
43-
const argumentsDoc = path.call(print, 'arguments');
44-
45-
// If we are at the end of a MemberAccessChain we should indent the
46-
// arguments accordingly.
47-
if (isLabel(operand) && operand.label === 'MemberAccessChain') {
48-
// We wrap the expression in a label in case there is an IndexAccess or
49-
// a FunctionCall following this IndexAccess.
50-
return label(
51-
'MemberAccessChain',
52-
printGroupAndIndentIfBreakPair(operand.contents, argumentsDoc)
53-
);
54-
}
55-
56-
return [operand, argumentsDoc].flat();
38+
return printPossibleMemberAccessChainItem(
39+
path.call(print, 'operand'),
40+
path.call(print, 'arguments')
41+
);
5742
}
5843
}

src/slang-nodes/IndexAccessExpression.ts

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { NonterminalKind } from '@nomicfoundation/slang/cst';
2-
import { doc } from 'prettier';
32
import { printSeparatedItem } from '../slang-printers/print-separated-item.js';
4-
import { printGroupAndIndentIfBreakPair } from '../slang-printers/print-group-and-indent-if-break-pair.js';
5-
import { isLabel } from '../slang-utils/is-label.js';
63
import { extractVariant } from '../slang-utils/extract-variant.js';
4+
import { printPossibleMemberAccessChainItem } from '../slang-printers/print-member-access-chain-item.js';
75
import { SlangNode } from './SlangNode.js';
86
import { Expression } from './Expression.js';
97
import { IndexAccessEnd } from './IndexAccessEnd.js';
@@ -13,8 +11,6 @@ import type { AstPath, Doc, ParserOptions } from 'prettier';
1311
import type { CollectedMetadata, PrintFunction } from '../types.d.ts';
1412
import type { AstNode } from './types.d.ts';
1513

16-
const { label } = doc.builders;
17-
1814
export class IndexAccessExpression extends SlangNode {
1915
readonly kind = NonterminalKind.IndexAccessExpression;
2016

@@ -47,24 +43,10 @@ export class IndexAccessExpression extends SlangNode {
4743
}
4844

4945
print(path: AstPath<IndexAccessExpression>, print: PrintFunction): Doc {
50-
const operand = path.call(print, 'operand');
51-
const indexDoc = [
46+
return printPossibleMemberAccessChainItem(path.call(print, 'operand'), [
5247
'[',
5348
printSeparatedItem([path.call(print, 'start'), path.call(print, 'end')]),
5449
']'
55-
];
56-
57-
// If we are at the end of a MemberAccessChain we should indent the
58-
// arguments accordingly.
59-
if (isLabel(operand) && operand.label === 'MemberAccessChain') {
60-
// We wrap the expression in a label in case there is an IndexAccess or
61-
// a FunctionCall following this IndexAccess.
62-
return label(
63-
'MemberAccessChain',
64-
printGroupAndIndentIfBreakPair(operand.contents, indexDoc)
65-
);
66-
}
67-
68-
return [operand, indexDoc].flat();
50+
]);
6951
}
7052
}

src/slang-nodes/MemberAccessExpression.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { doc } from 'prettier';
33
import { isLabel } from '../slang-utils/is-label.js';
44
import { extractVariant } from '../slang-utils/extract-variant.js';
55
import { isChainableExpression } from '../slang-utils/is-chainable-expression.js';
6+
import { memberAccessChainLabel } from '../slang-printers/print-member-access-chain-item.js';
67
import { SlangNode } from './SlangNode.js';
78
import { Expression } from './Expression.js';
89
import { TerminalNode } from './TerminalNode.js';
@@ -14,6 +15,8 @@ import type { AstNode, ChainableExpression, StrictAstNode } from './types.d.ts';
1415

1516
const { group, indent, label, softline } = doc.builders;
1617

18+
const separatorLabel = Symbol('separator');
19+
1720
function isEndOfChain(
1821
node: ChainableExpression,
1922
path: AstPath<StrictAstNode>
@@ -91,13 +94,13 @@ function isEndOfChain(
9194
* be printed.
9295
*/
9396
function processChain(chain: Doc[]): Doc {
94-
const firstSeparatorIndex = chain.findIndex(
95-
(element) => isLabel(element) && element.label === 'separator'
97+
const firstSeparatorIndex = chain.findIndex((element) =>
98+
isLabel(element, separatorLabel)
9699
);
97100

98101
// We wrap the expression in a label in case there is an IndexAccess or
99102
// a FunctionCall following this MemberAccess.
100-
return label('MemberAccessChain', [
103+
return label(memberAccessChainLabel, [
101104
// The doc[] before the first separator
102105
chain.slice(0, firstSeparatorIndex),
103106
// The doc[] containing the rest of the chain
@@ -135,7 +138,7 @@ export class MemberAccessExpression extends SlangNode {
135138

136139
const document = [
137140
operandDoc,
138-
label('separator', [softline, '.']),
141+
label(separatorLabel, [softline, '.']),
139142
path.call(print, 'member')
140143
].flat();
141144

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { doc } from 'prettier';
2+
import { isLabel } from '../slang-utils/is-label.js';
3+
import { printGroupAndIndentIfBreakPair } from './print-group-and-indent-if-break-pair.js';
4+
5+
import type { Doc } from 'prettier';
6+
7+
const { label } = doc.builders;
8+
9+
export const memberAccessChainLabel = Symbol('MemberAccessChain');
10+
11+
export function printPossibleMemberAccessChainItem(
12+
operand: Doc,
13+
predicate: Doc
14+
): Doc {
15+
// If we are at the end of a MemberAccessChain we should indent the
16+
// arguments accordingly.
17+
if (isLabel(operand, memberAccessChainLabel)) {
18+
// We wrap the expression in a label in case there is an IndexAccess or
19+
// a FunctionCall following Node.
20+
return label(
21+
memberAccessChainLabel,
22+
printGroupAndIndentIfBreakPair(operand.contents, predicate)
23+
);
24+
}
25+
26+
return [operand, predicate].flat();
27+
}

src/slang-utils/is-label.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import type { Doc, doc } from 'prettier';
22

3-
export function isLabel(document: Doc): document is doc.builders.Label {
4-
return (document as doc.builders.DocCommand).type === 'label';
3+
export function isLabel(
4+
document: Doc,
5+
value: symbol
6+
): document is doc.builders.Label {
7+
return (
8+
(document as doc.builders.DocCommand).type === 'label' &&
9+
(document as doc.builders.Label).label === value
10+
);
511
}

0 commit comments

Comments
 (0)