Skip to content

Commit 91f326f

Browse files
authored
review of printing patterns (#1223)
* small refactor * a printer for a pattern where a condition forks into a space or an indented line prepending the same item * a printer for a pattern where a group is followed by an indentIfBreak pointing to said group. * standardising `printPreservingEmptyLines` * automatically set `grouped: false` when the `firstSeparator` is a `hardline` * unnecessary group since the contents are already being grouped * `expression` is not that complicated that it deserves its own function * more accurate return types for printers * storing document in const * preserve empty lines between dangling comments * only attempt to print the dangling comments if there are no items to be printed
1 parent 8f6bc4e commit 91f326f

39 files changed

Lines changed: 319 additions & 224 deletions

src/common/printer-helpers.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,33 @@ const { isNextLineEmpty } = util;
55

66
export const printComments = (node, path, options, filter = () => true) => {
77
if (!node.comments) return '';
8+
function isPrintable(comment) {
9+
return (
10+
!comment.trailing &&
11+
!comment.leading &&
12+
!comment.printed &&
13+
filter(comment)
14+
);
15+
}
816
const document = join(
917
line,
1018
path
11-
.map((commentPath) => {
19+
.map((commentPath, index, comments) => {
1220
const comment = commentPath.getValue();
13-
if (comment.trailing || comment.leading || comment.printed) {
14-
return null;
15-
}
16-
if (!filter(comment)) {
21+
if (!isPrintable(comment)) {
1722
return null;
1823
}
1924
comment.printed = true;
20-
return options.printer.printComment(commentPath, options);
25+
const isLast =
26+
index === comments.length - 1 ||
27+
comments.slice(index + 1).findIndex(isPrintable) === -1;
28+
return [
29+
options.printer.printComment(commentPath, options),
30+
!isLast &&
31+
util.isNextLineEmpty(options.originalText, options.locEnd(comment))
32+
? hardline
33+
: ''
34+
];
2135
}, 'comments')
2236
.filter(Boolean)
2337
);

src/nodes/SourceUnit.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { doc } from 'prettier';
2-
import { printPreservingEmptyLines } from '../common/printer-helpers.js';
2+
import {
3+
printComments,
4+
printPreservingEmptyLines
5+
} from '../common/printer-helpers.js';
36

47
const { line } = doc.builders;
58

69
export const SourceUnit = {
7-
print: ({ options, path, print }) => [
10+
print: ({ node, options, path, print }) => [
811
printPreservingEmptyLines(path, 'children', options, print),
12+
printComments(node, path, options),
913
options.parentParser ? '' : line
1014
]
1115
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { NonterminalKind } from '@nomicfoundation/slang/cst';
2+
import addCollectionFirstComment from './add-collection-first-comment.js';
3+
import addCollectionLastComment from './add-collection-last-comment.js';
4+
5+
import type { HandlerParams } from './types.js';
6+
7+
export default function handleSourceUnitMembersComments({
8+
precedingNode,
9+
followingNode,
10+
comment
11+
}: HandlerParams): boolean {
12+
if (
13+
followingNode &&
14+
followingNode.kind === NonterminalKind.SourceUnitMembers
15+
) {
16+
addCollectionFirstComment(followingNode, comment);
17+
return true;
18+
}
19+
if (
20+
precedingNode &&
21+
precedingNode.kind === NonterminalKind.SourceUnitMembers
22+
) {
23+
addCollectionLastComment(precedingNode, comment);
24+
return true;
25+
}
26+
27+
return false;
28+
}

src/slang-comments/handlers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import handleLibraryDefinitionComments from './handle-library-definition-comment
88
import handleModifierInvocationComments from './handle-modifier-invocation-comments.js';
99
import handleParametersDeclarationComments from './handle-parameters-declaration-comments.js';
1010
import handlePositionalArgumentsDeclarationComments from './handle-positional-arguments-declaration-comments.js';
11+
import handleSourceUnitMembersComments from './handle-source-unit-members-comments.js';
1112
import handleStorageLayoutSpecifierComments from './handle-storage-layout-specifier-comments.js';
1213
import handleStructComments from './handle-struct-comments.js';
1314
import handleWhileStatementComments from './handle-while-statement-comments.js';
@@ -24,6 +25,7 @@ export default [
2425
handleModifierInvocationComments,
2526
handleParametersDeclarationComments,
2627
handlePositionalArgumentsDeclarationComments,
28+
handleSourceUnitMembersComments,
2729
handleStorageLayoutSpecifierComments,
2830
handleStructComments,
2931
handleWhileStatementComments,

src/slang-nodes/AddressType.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { NonterminalKind } from '@nomicfoundation/slang/cst';
2-
import { joinExisting } from '../slang-utils/join-existing.js';
32
import { SlangNode } from './SlangNode.js';
43

54
import type * as ast from '@nomicfoundation/slang/ast';
@@ -17,6 +16,6 @@ export class AddressType extends SlangNode {
1716
}
1817

1918
print(): Doc {
20-
return joinExisting(' ', ['address', this.payableKeyword]);
19+
return ['address', this.payableKeyword ? ' payable' : ''];
2120
}
2221
}

src/slang-nodes/ArrayExpression.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { doc } from 'prettier';
21
import { NonterminalKind } from '@nomicfoundation/slang/cst';
32
import { SlangNode } from './SlangNode.js';
43
import { ArrayValues } from './ArrayValues.js';
@@ -8,8 +7,6 @@ import type { AstPath, Doc, ParserOptions } from 'prettier';
87
import type { AstNode } from './types.d.ts';
98
import type { PrintFunction } from '../types.d.ts';
109

11-
const { group } = doc.builders;
12-
1310
export class ArrayExpression extends SlangNode {
1411
readonly kind = NonterminalKind.ArrayExpression;
1512

@@ -24,6 +21,6 @@ export class ArrayExpression extends SlangNode {
2421
}
2522

2623
print(path: AstPath<ArrayExpression>, print: PrintFunction): Doc {
27-
return group(['[', path.call(print, 'items'), ']']);
24+
return ['[', path.call(print, 'items'), ']'];
2825
}
2926
}

src/slang-nodes/AssignmentExpression.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { NonterminalKind, TerminalKind } from '@nomicfoundation/slang/cst';
2-
import { doc } from 'prettier';
32
import { isBinaryOperation } from '../slang-utils/is-binary-operation.js';
3+
import { printIndentedGroupOrSpacedDocument } from '../slang-printers/print-indented-group-or-spaced-document.js';
44
import { SlangNode } from './SlangNode.js';
55
import { Expression } from './Expression.js';
66

@@ -9,8 +9,6 @@ import type { AstPath, Doc, ParserOptions } from 'prettier';
99
import type { AstNode } from './types.d.ts';
1010
import type { PrintFunction } from '../types.d.ts';
1111

12-
const { group, indent, line } = doc.builders;
13-
1412
export class AssignmentExpression extends SlangNode {
1513
readonly kind = NonterminalKind.AssignmentExpression;
1614

@@ -32,14 +30,14 @@ export class AssignmentExpression extends SlangNode {
3230

3331
print(path: AstPath<AssignmentExpression>, print: PrintFunction): Doc {
3432
const rightOperandVariant = this.rightOperand.variant;
35-
const rightOperand = path.call(print, 'rightOperand');
3633
return [
3734
path.call(print, 'leftOperand'),
3835
` ${this.operator}`,
39-
rightOperandVariant.kind !== TerminalKind.Identifier &&
40-
isBinaryOperation(rightOperandVariant)
41-
? group(indent([line, rightOperand]))
42-
: [' ', rightOperand]
36+
printIndentedGroupOrSpacedDocument(
37+
path.call(print, 'rightOperand'),
38+
rightOperandVariant.kind !== TerminalKind.Identifier &&
39+
isBinaryOperation(rightOperandVariant)
40+
)
4341
];
4442
}
4543
}

src/slang-nodes/ContractMembers.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { doc } from 'prettier';
22
import { NonterminalKind } from '@nomicfoundation/slang/cst';
33
import { printSeparatedItem } from '../slang-printers/print-separated-item.js';
4-
import { printComments } from '../slang-printers/print-comments.js';
54
import { printPreservingEmptyLines } from '../slang-printers/print-preserving-empty-lines.js';
65
import { SlangNode } from './SlangNode.js';
76
import { ContractMember } from './ContractMember.js';
@@ -31,14 +30,10 @@ export class ContractMembers extends SlangNode {
3130
print: PrintFunction,
3231
options: ParserOptions<AstNode>
3332
): Doc {
34-
return this.items.length === 0 && this.comments.length === 0
35-
? ''
36-
: printSeparatedItem(
37-
[
38-
printPreservingEmptyLines(path, print, options),
39-
printComments(path)
40-
],
41-
{ firstSeparator: hardline, grouped: false }
42-
);
33+
return this.items.length > 0 || this.comments.length > 0
34+
? printSeparatedItem(printPreservingEmptyLines(path, print, options), {
35+
firstSeparator: hardline
36+
})
37+
: '';
4338
}
4439
}

src/slang-nodes/ElseBranch.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { doc } from 'prettier';
21
import { NonterminalKind } from '@nomicfoundation/slang/cst';
32
import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js';
3+
import { printIndentedGroupOrSpacedDocument } from '../slang-printers/print-indented-group-or-spaced-document.js';
44
import { SlangNode } from './SlangNode.js';
55
import { Statement } from './Statement.js';
66

@@ -9,8 +9,6 @@ import type { AstPath, Doc, ParserOptions } from 'prettier';
99
import type { AstNode } from './types.d.ts';
1010
import type { PrintFunction } from '../types.d.ts';
1111

12-
const { group, indent, line } = doc.builders;
13-
1412
const isIfStatementOrBlock = createKindCheckFunction([
1513
NonterminalKind.Block,
1614
NonterminalKind.IfStatement
@@ -30,12 +28,12 @@ export class ElseBranch extends SlangNode {
3028
}
3129

3230
print(path: AstPath<ElseBranch>, print: PrintFunction): Doc {
33-
const body = path.call(print, 'body');
3431
return [
3532
'else',
36-
isIfStatementOrBlock(this.body.variant)
37-
? [' ', body]
38-
: group(indent([line, body]))
33+
printIndentedGroupOrSpacedDocument(
34+
path.call(print, 'body'),
35+
!isIfStatementOrBlock(this.body.variant)
36+
)
3937
];
4038
}
4139
}

src/slang-nodes/EventDefinition.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ export class EventDefinition extends SlangNode {
3232
'event ',
3333
path.call(print, 'name'),
3434
path.call(print, 'parameters'),
35-
this.anonymousKeyword ? ' anonymous' : '',
36-
';'
35+
this.anonymousKeyword ? ' anonymous;' : ';'
3736
];
3837
}
3938
}

0 commit comments

Comments
 (0)