Skip to content

Commit 7708d37

Browse files
authored
iterating only once per node's children (#1235)
1 parent dcde135 commit 7708d37

1 file changed

Lines changed: 24 additions & 32 deletions

File tree

src/slang-nodes/SlangNode.ts

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,14 @@ import {
33
TerminalNode,
44
TerminalKindExtensions
55
} from '@nomicfoundation/slang/cst';
6-
import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js';
76
import { MultiLineComment } from '../slang-nodes/MultiLineComment.js';
87
import { MultiLineNatSpecComment } from '../slang-nodes/MultiLineNatSpecComment.js';
98
import { SingleLineComment } from '../slang-nodes/SingleLineComment.js';
109
import { SingleLineNatSpecComment } from '../slang-nodes/SingleLineNatSpecComment.js';
1110

12-
import type { Edge } from '@nomicfoundation/slang/cst';
1311
import type { Comment, StrictAstNode } from '../slang-nodes/types.d.ts';
1412
import type { AstLocation, SlangAstNode } from '../types.d.ts';
1513

16-
const isCommentOrWhiteSpace = createKindCheckFunction([
17-
TerminalKind.MultiLineComment,
18-
TerminalKind.MultiLineNatSpecComment,
19-
TerminalKind.SingleLineComment,
20-
TerminalKind.SingleLineNatSpecComment,
21-
TerminalKind.EndOfLine,
22-
TerminalKind.Whitespace
23-
]);
24-
2514
const offsets = new Map<number, number>();
2615
export function clearOffsets(): void {
2716
offsets.clear();
@@ -41,19 +30,6 @@ function reversedIterator<T>(children: T[]): Iterable<T> {
4130
};
4231
}
4332

44-
function getOffset(children: Edge[] | Iterable<Edge>): number {
45-
let offset = 0;
46-
for (const { node } of children) {
47-
if (node.isNonterminalNode() || !isCommentOrWhiteSpace(node)) {
48-
// The node's content starts when we find the first non-terminal token,
49-
// or if we find a non-comment, non-whitespace token.
50-
return offset;
51-
}
52-
offset += node.textLength.utf16;
53-
}
54-
return offset;
55-
}
56-
5733
function collectComments(
5834
comments: Comment[],
5935
node: StrictAstNode | StrictAstNode[] | undefined
@@ -88,20 +64,33 @@ export class SlangNode {
8864
};
8965
return;
9066
}
91-
const parent = ast.cst;
92-
const children = parent.children();
67+
const cst = ast.cst;
9368

94-
const initialOffset = offsets.get(parent.id) || 0;
69+
const initialOffset = offsets.get(cst.id) || 0;
9570
let offset = initialOffset;
71+
let triviaLength = 0;
72+
let leadingOffset;
73+
let trailingOffset;
74+
75+
if (enclosePeripheralComments) {
76+
// We initialize the offsets to 0 to avoid them being updated later.
77+
leadingOffset = 0;
78+
trailingOffset = 0;
79+
}
9680

97-
for (const { node } of children) {
81+
for (const { node } of cst.children()) {
82+
const textLength = node.textLength.utf16;
9883
if (
9984
node.isNonterminalNode() ||
10085
!TerminalKindExtensions.isTrivia(node.kind)
10186
) {
10287
// Also tracking TerminalNodes since some variants that were not
10388
// Identifier or YulIdentifier but were upgraded to TerminalNode
10489
offsets.set(node.id, offset);
90+
// We assign the `leadingOffset` only once.
91+
leadingOffset ??= triviaLength;
92+
// Since this is a non trivia node, we reset the accumulated length
93+
triviaLength = 0;
10594
} else {
10695
switch (node.kind) {
10796
// Since the fetching the comments and calculating offsets are both done
@@ -121,14 +110,17 @@ export class SlangNode {
121110
this.comments.push(new SingleLineNatSpecComment(node, offset));
122111
break;
123112
}
113+
// We accumulate the trivia length
114+
triviaLength += textLength;
124115
}
125116

126-
offset += node.textLength.utf16;
117+
offset += textLength;
127118
}
128119

129-
const [leadingOffset, trailingOffset] = enclosePeripheralComments
130-
? [0, 0]
131-
: [getOffset(children), getOffset(reversedIterator(children))];
120+
// In case the `leadingOffset` was not initialized
121+
leadingOffset ??= 0;
122+
// The remaining `triviaLength` is the `trailingOffset`
123+
trailingOffset ??= triviaLength;
132124

133125
this.loc = {
134126
start: initialOffset + leadingOffset,

0 commit comments

Comments
 (0)