Skip to content

Commit

Permalink
visitor: remove visitorKeys argument (#2930)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov committed Feb 20, 2021
1 parent 2af9885 commit b67ed17
Show file tree
Hide file tree
Showing 7 changed files with 6 additions and 164 deletions.
1 change: 0 additions & 1 deletion src/index.d.ts
Expand Up @@ -229,7 +229,6 @@ export {
ASTVisitor,
Visitor,
VisitFn,
VisitorKeyMap,
// AST nodes
ASTNode,
ASTKindToNode,
Expand Down
1 change: 0 additions & 1 deletion src/index.js
Expand Up @@ -216,7 +216,6 @@ export type {
ASTVisitor,
Visitor,
VisitFn,
VisitorKeyMap,
// AST nodes
ASTNode,
ASTKindToNode,
Expand Down
41 changes: 1 addition & 40 deletions src/language/__tests__/visitor-test.js
Expand Up @@ -8,7 +8,7 @@ import { invariant } from '../../jsutils/invariant';
import type { ASTNode } from '../ast';
import { Kind } from '../kinds';
import { parse } from '../parser';
import { visit, visitInParallel, BREAK, QueryDocumentKeys } from '../visitor';
import { visit, visitInParallel, BREAK } from '../visitor';

function checkVisitorFnArgs(ast: any, args: any, isEdited: boolean = false) {
const [node, key, parent, path, ancestors] = args;
Expand Down Expand Up @@ -913,45 +913,6 @@ describe('Visitor', () => {
['leave', 'Document', undefined],
]);
});

it('does traverse unknown node kinds with visitor keys', () => {
const customQueryDocumentKeys = { ...QueryDocumentKeys };
(customQueryDocumentKeys: any).CustomField = ['name', 'selectionSet'];

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

expect(visited).to.deep.equal([
['enter', 'Document', undefined],
['enter', 'OperationDefinition', undefined],
['enter', 'SelectionSet', undefined],
['enter', 'Field', undefined],
['enter', 'Name', 'a'],
['leave', 'Name', 'a'],
['leave', 'Field', undefined],
['enter', 'CustomField', undefined],
['enter', 'Name', 'b'],
['leave', 'Name', 'b'],
['enter', 'SelectionSet', undefined],
['enter', 'CustomField', undefined],
['enter', 'Name', 'c'],
['leave', 'Name', 'c'],
['leave', 'CustomField', undefined],
['leave', 'SelectionSet', undefined],
['leave', 'CustomField', undefined],
['leave', 'SelectionSet', undefined],
['leave', 'OperationDefinition', undefined],
['leave', 'Document', undefined],
]);
});
});

describe('visitInParallel', () => {
Expand Down
1 change: 0 additions & 1 deletion src/language/index.d.ts
Expand Up @@ -16,7 +16,6 @@ export {
ASTVisitor,
Visitor,
VisitFn,
VisitorKeyMap,
} from './visitor';

export {
Expand Down
2 changes: 1 addition & 1 deletion src/language/index.js
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, Visitor, VisitFn, VisitorKeyMap } from './visitor';
export type { ASTVisitor, Visitor, VisitFn } from './visitor';

export { Location, Token } from './ast';
export type {
Expand Down
106 changes: 1 addition & 105 deletions src/language/visitor.d.ts
Expand Up @@ -47,106 +47,6 @@ export type VisitFn<TAnyNode, TVisitedNode = TAnyNode> = (
ancestors: ReadonlyArray<TAnyNode | ReadonlyArray<TAnyNode>>,
) => any;

/**
* A KeyMap describes each the traversable properties of each kind of node.
*/
export type VisitorKeyMap<T> = { [P in keyof T]: ReadonlyArray<keyof T[P]> };

// TODO: Should be `[]`, but that requires TypeScript@3
type EmptyTuple = Array<never>;

export const QueryDocumentKeys: {
Name: EmptyTuple;

Document: ['definitions'];
// Prettier forces trailing commas, but TS pre 3.2 doesn't allow them.
// prettier-ignore
OperationDefinition: [
'name',
'variableDefinitions',
'directives',
'selectionSet'
];
VariableDefinition: ['variable', 'type', 'defaultValue', 'directives'];
Variable: ['name'];
SelectionSet: ['selections'];
Field: ['alias', 'name', 'arguments', 'directives', 'selectionSet'];
Argument: ['name', 'value'];

FragmentSpread: ['name', 'directives'];
InlineFragment: ['typeCondition', 'directives', 'selectionSet'];
// prettier-ignore
FragmentDefinition: [
'name',
// Note: fragment variable definitions are deprecated and will removed in v17.0.0
'variableDefinitions',
'typeCondition',
'directives',
'selectionSet'
];

IntValue: EmptyTuple;
FloatValue: EmptyTuple;
StringValue: EmptyTuple;
BooleanValue: EmptyTuple;
NullValue: EmptyTuple;
EnumValue: EmptyTuple;
ListValue: ['values'];
ObjectValue: ['fields'];
ObjectField: ['name', 'value'];

Directive: ['name', 'arguments'];

NamedType: ['name'];
ListType: ['type'];
NonNullType: ['type'];

SchemaDefinition: ['description', 'directives', 'operationTypes'];
OperationTypeDefinition: ['type'];

ScalarTypeDefinition: ['description', 'name', 'directives'];
// prettier-ignore
ObjectTypeDefinition: [
'description',
'name',
'interfaces',
'directives',
'fields'
];
FieldDefinition: ['description', 'name', 'arguments', 'type', 'directives'];
// prettier-ignore
InputValueDefinition: [
'description',
'name',
'type',
'defaultValue',
'directives'
];
// prettier-ignore
InterfaceTypeDefinition: [
'description',
'name',
'interfaces',
'directives',
'fields'
];
UnionTypeDefinition: ['description', 'name', 'directives', 'types'];
EnumTypeDefinition: ['description', 'name', 'directives', 'values'];
EnumValueDefinition: ['description', 'name', 'directives'];
InputObjectTypeDefinition: ['description', 'name', 'directives', 'fields'];

DirectiveDefinition: ['description', 'name', 'arguments', 'locations'];

SchemaExtension: ['directives', 'operationTypes'];

ScalarTypeExtension: ['name', 'directives'];
ObjectTypeExtension: ['name', 'interfaces', 'directives', 'fields'];
InterfaceTypeExtension: ['name', 'interfaces', 'directives', 'fields'];
UnionTypeExtension: ['name', 'directives', 'types'];
EnumTypeExtension: ['name', 'directives', 'values'];
InputObjectTypeExtension: ['name', 'directives', 'fields'];
};

export const BREAK: any;

/**
Expand Down Expand Up @@ -235,11 +135,7 @@ export const BREAK: any;
* }
* })
*/
export function visit(
root: ASTNode,
visitor: Visitor<ASTKindToNode>,
visitorKeys?: VisitorKeyMap<ASTKindToNode>, // default: QueryDocumentKeys
): any;
export function visit(root: ASTNode, visitor: Visitor<ASTKindToNode>): any;

/**
* Creates a new visitor instance which delegates to many visitors to run in
Expand Down
18 changes: 3 additions & 15 deletions src/language/visitor.js
Expand Up @@ -39,15 +39,7 @@ export type VisitFn<TAnyNode, TVisitedNode: TAnyNode = TAnyNode> = (
ancestors: $ReadOnlyArray<TAnyNode | $ReadOnlyArray<TAnyNode>>,
) => any;

/**
* A KeyMap describes each the traversable properties of each kind of node.
*/
export type VisitorKeyMap<KindToNode> = $ObjMap<
KindToNode,
<T>(T) => $ReadOnlyArray<$Keys<T>>,
>;

export const QueryDocumentKeys: VisitorKeyMap<ASTKindToNode> = {
const QueryDocumentKeys = {
Name: [],

Document: ['definitions'],
Expand Down Expand Up @@ -221,11 +213,7 @@ export const BREAK: { ... } = Object.freeze({});
* }
* })
*/
export function visit(
root: ASTNode,
visitor: Visitor<ASTKindToNode>,
visitorKeys: VisitorKeyMap<ASTKindToNode> = QueryDocumentKeys,
): any {
export function visit(root: ASTNode, visitor: Visitor<ASTKindToNode>): any {
/* eslint-disable no-undef-init */
let stack: any = undefined;
let inArray = Array.isArray(root);
Expand Down Expand Up @@ -330,7 +318,7 @@ export function visit(
} else {
stack = { inArray, index, keys, edits, prev: stack };
inArray = Array.isArray(node);
keys = inArray ? node : visitorKeys[node.kind] ?? [];
keys = inArray ? node : QueryDocumentKeys[node.kind] ?? [];
index = -1;
edits = [];
if (parent) {
Expand Down

0 comments on commit b67ed17

Please sign in to comment.