Skip to content

Commit

Permalink
Bring visitorKeys back (#3250)
Browse files Browse the repository at this point in the history
Co-authored-by: Ivan Goncharov <ivan.goncharov.ua@gmail.com>
  • Loading branch information
ardatan and IvanGoncharov committed Sep 20, 2021
1 parent 505b4f8 commit 0091421
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Expand Up @@ -234,6 +234,7 @@ export type {
/** Visitor utilities */
ASTVisitor,
ASTVisitFn,
ASTVisitorKeyMap,
/** AST nodes */
ASTNode,
ASTKindToNode,
Expand Down
36 changes: 36 additions & 0 deletions src/language/__tests__/visitor-test.ts
Expand Up @@ -4,6 +4,7 @@ import { describe, it } from 'mocha';
import { kitchenSinkQuery } from '../../__testUtils__/kitchenSinkQuery';

import type { ASTNode, SelectionSetNode } from '../ast';
import type { ASTVisitorKeyMap, ASTVisitor } from '../visitor';
import { isNode } from '../ast';
import { Kind } from '../kinds';
import { parse } from '../parser';
Expand Down Expand Up @@ -462,6 +463,41 @@ describe('Visitor', () => {
]);
});

it('visits only the specified `Kind` in visitorKeyMap', () => {
const visited: Array<any> = [];

const visitorKeyMap: ASTVisitorKeyMap = {
Document: ['definitions'],
OperationDefinition: ['name'],
};

const visitor: ASTVisitor = {
enter(node) {
visited.push(['enter', node.kind, getValue(node)]);
},
leave(node) {
visited.push(['leave', node.kind, getValue(node)]);
},
};

const exampleDocumentAST = parse(`
query ExampleOperation {
someField
}
`);

visit(exampleDocumentAST, visitor, visitorKeyMap);

expect(visited).to.deep.equal([
['enter', 'Document', undefined],
['enter', 'OperationDefinition', undefined],
['enter', 'Name', 'ExampleOperation'],
['leave', 'Name', 'ExampleOperation'],
['leave', 'OperationDefinition', undefined],
['leave', 'Document', undefined],
]);
});

it('Legacy: visits variables defined in fragments', () => {
const ast = parse('fragment a($v: Boolean = false) on t { f }', {
noLocation: true,
Expand Down
2 changes: 1 addition & 1 deletion src/language/index.ts
Expand Up @@ -19,7 +19,7 @@ export type { ParseOptions } from './parser';
export { print } from './printer';

export { visit, visitInParallel, getVisitFn, BREAK } from './visitor';
export type { ASTVisitor, ASTVisitFn } from './visitor';
export type { ASTVisitor, ASTVisitFn, ASTVisitorKeyMap } from './visitor';

export { Location, Token } from './ast';
export type {
Expand Down
30 changes: 19 additions & 11 deletions src/language/visitor.ts
Expand Up @@ -76,9 +76,14 @@ type ReducedField<T, R> = T extends null | undefined
? ReadonlyArray<R>
: R;

const QueryDocumentKeys = {
Name: [],
/**
* A KeyMap describes each the traversable properties of each kind of node.
*/
export type ASTVisitorKeyMap = {
[P in keyof ASTKindToNode]?: ReadonlyArray<keyof ASTKindToNode[P]>;
};

export const QueryDocumentKeys: ASTVisitorKeyMap = {
Document: ['definitions'],
OperationDefinition: [
'name',
Expand All @@ -103,12 +108,6 @@ const QueryDocumentKeys = {
'selectionSet',
],

IntValue: [],
FloatValue: [],
StringValue: [],
BooleanValue: [],
NullValue: [],
EnumValue: [],
ListValue: ['values'],
ObjectValue: ['fields'],
ObjectField: ['name', 'value'],
Expand Down Expand Up @@ -242,11 +241,20 @@ export const BREAK: unknown = Object.freeze({});
* })
* ```
*/
export function visit<N extends ASTNode>(root: N, visitor: ASTVisitor): N;
export function visit<R>(root: ASTNode, visitor: ASTReducer<R>): R;
export function visit<N extends ASTNode>(
root: N,
visitor: ASTVisitor,
visitorKeys?: ASTVisitorKeyMap,
): N;
export function visit<R>(
root: ASTNode,
visitor: ASTReducer<R>,
visitorKeys?: ASTVisitorKeyMap,
): R;
export function visit(
root: ASTNode,
visitor: ASTVisitor | ASTReducer<any>,
visitorKeys: ASTVisitorKeyMap = QueryDocumentKeys,
): any {
/* eslint-disable no-undef-init */
let stack: any = undefined;
Expand Down Expand Up @@ -346,7 +354,7 @@ export function visit(
} else {
stack = { inArray, index, keys, edits, prev: stack };
inArray = Array.isArray(node);
keys = inArray ? node : (QueryDocumentKeys as any)[node.kind] ?? [];
keys = inArray ? node : (visitorKeys as any)[node.kind] ?? [];
index = -1;
edits = [];
if (parent) {
Expand Down

0 comments on commit 0091421

Please sign in to comment.