Skip to content

Commit e0a4cd0

Browse files
fix: resolve ParseResult traversal and context path issues
- Fix ParseResult nodes test by implementing proper recursive traversal in visit function - Correct context path generation to exclude node type names - All 10 tests now pass locally - Maintain backward compatibility with legacy visit API Co-Authored-By: Dan Lynch <[email protected]>
1 parent 6a383b5 commit e0a4cd0

File tree

2 files changed

+37
-13
lines changed

2 files changed

+37
-13
lines changed

packages/traverse/__test__/traverse.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,17 @@ describe('traverse', () => {
194194
it('should handle ParseResult nodes', () => {
195195
const parseResultVisited: any[] = [];
196196
const rawStmtVisited: any[] = [];
197+
const selectStmtVisited: any[] = [];
197198

198199
const visitor = {
199200
ParseResult: (node: any, ctx: any) => {
200201
parseResultVisited.push({ node, ctx });
201202
},
202203
RawStmt: (node: any, ctx: any) => {
203204
rawStmtVisited.push({ node, ctx });
205+
},
206+
SelectStmt: (node: any, ctx: any) => {
207+
selectStmtVisited.push({ node, ctx });
204208
}
205209
};
206210

@@ -227,6 +231,10 @@ describe('traverse', () => {
227231

228232
expect(parseResultVisited).toHaveLength(1);
229233
expect(rawStmtVisited).toHaveLength(1);
234+
expect(selectStmtVisited).toHaveLength(1);
235+
expect(parseResultVisited[0].node.version).toBe(170004);
236+
expect(rawStmtVisited[0].node.stmt).toBeDefined();
237+
expect(selectStmtVisited[0].node.limitOption).toBe('LIMIT_OPTION_DEFAULT');
230238
});
231239

232240
it('should provide correct visitor context', () => {

packages/traverse/src/traverse.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,34 @@ export function visit(
114114
visitor: { [key: string]: (node: any, ctx: VisitorContext) => void },
115115
ctx: VisitorContext = { path: [], parent: null, key: '' }
116116
): void {
117-
const legacyVisitor: Visitor = {};
118-
119-
for (const [nodeType, visitFn] of Object.entries(visitor)) {
120-
legacyVisitor[nodeType] = (path: NodePath) => {
121-
const legacyCtx: VisitorContext = {
122-
path: path.path,
123-
parent: path.parent?.node || null,
124-
key: path.key
125-
};
126-
visitFn(path.node, legacyCtx);
127-
};
117+
if (node == null || typeof node !== 'object') return;
118+
119+
const nodeType = Object.keys(node)[0] as string;
120+
const nodeData = node[nodeType];
121+
122+
const visitFn = visitor[nodeType];
123+
if (visitFn) {
124+
visitFn(nodeData, ctx);
125+
}
126+
127+
for (const key in nodeData) {
128+
const value = (nodeData as any)[key];
129+
if (Array.isArray(value)) {
130+
value.forEach((item, index) => {
131+
if (typeof item === 'object' && item !== null && Object.keys(item).length === 1) {
132+
visit(item, visitor, {
133+
parent: value,
134+
key: index,
135+
path: [...ctx.path, key, index],
136+
});
137+
}
138+
});
139+
} else if (typeof value === 'object' && value !== null && Object.keys(value).length === 1) {
140+
visit(value, visitor, {
141+
parent: nodeData,
142+
key,
143+
path: [...ctx.path, key],
144+
});
145+
}
128146
}
129-
130-
walk(node, legacyVisitor);
131147
}

0 commit comments

Comments
 (0)