From 8b41d52045d138bda035504a8c725eca234c379f Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Fri, 27 Aug 2021 16:54:16 +0300 Subject: [PATCH 1/3] Bring back --- src/index.ts | 1 + src/language/__tests__/visitor-test.ts | 38 +++++++++++++++++++++++++- src/language/index.ts | 2 +- src/language/visitor.ts | 20 ++++++-------- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/index.ts b/src/index.ts index be0eda9b0f..bc690b6c22 100644 --- a/src/index.ts +++ b/src/index.ts @@ -234,6 +234,7 @@ export type { /** Visitor utilities */ ASTVisitor, ASTVisitFn, + VisitorKeyMap, /** AST nodes */ ASTNode, ASTKindToNode, diff --git a/src/language/__tests__/visitor-test.ts b/src/language/__tests__/visitor-test.ts index 93b8fe072e..71f54c338b 100644 --- a/src/language/__tests__/visitor-test.ts +++ b/src/language/__tests__/visitor-test.ts @@ -3,10 +3,11 @@ import { describe, it } from 'mocha'; import { kitchenSinkQuery } from '../../__testUtils__/kitchenSinkQuery'; -import type { ASTNode, SelectionSetNode } from '../ast'; +import type { ASTKindToNode, ASTNode, SelectionSetNode } from '../ast'; import { isNode } from '../ast'; import { Kind } from '../kinds'; import { parse } from '../parser'; +import type { VisitorKeyMap, ASTVisitor } from '../visitor'; import { visit, visitInParallel, BREAK } from '../visitor'; function checkVisitorFnArgs(ast: any, args: any, isEdited: boolean = false) { @@ -893,6 +894,41 @@ describe('Visitor', () => { ]); }); + it('visits only the specified `Kind` in visitorKeyMap', () => { + const visited: Array<[string, string, ReturnType]> = []; + + const visitorKeyMap: VisitorKeyMap = { + 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(/* GraphQL */ ` + query ExampleOperation { + someField + } + `); + + visit(exampleDocumentAST, visitor, visitorKeyMap); + + expect(visited).to.deep.equal([ + ['enter', Kind.DOCUMENT, undefined], + ['enter', Kind.OPERATION_DEFINITION, undefined], + ['enter', Kind.NAME, 'ExampleOperation'], + ['leave', Kind.NAME, 'ExampleOperation'], + ['leave', Kind.OPERATION_DEFINITION, undefined], + ['leave', Kind.DOCUMENT, undefined], + ]); + }); + describe('visitInParallel', () => { // Note: nearly identical to the above test of the same test but // using visitInParallel. diff --git a/src/language/index.ts b/src/language/index.ts index dfe4e53584..996742c6f9 100644 --- a/src/language/index.ts +++ b/src/language/index.ts @@ -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, VisitorKeyMap } from './visitor'; export { Location, Token } from './ast'; export type { diff --git a/src/language/visitor.ts b/src/language/visitor.ts index 458a7af2f3..c6aed0a334 100644 --- a/src/language/visitor.ts +++ b/src/language/visitor.ts @@ -76,9 +76,12 @@ type ReducedField = T extends null | undefined ? ReadonlyArray : R; -const QueryDocumentKeys = { - Name: [], +/** +* A KeyMap describes each the traversable properties of each kind of node. +*/ +export type VisitorKeyMap = { [P in keyof KindToNode]?: ReadonlyArray }; +export const QueryDocumentKeys: VisitorKeyMap = { Document: ['definitions'], OperationDefinition: [ 'name', @@ -103,12 +106,6 @@ const QueryDocumentKeys = { 'selectionSet', ], - IntValue: [], - FloatValue: [], - StringValue: [], - BooleanValue: [], - NullValue: [], - EnumValue: [], ListValue: ['values'], ObjectValue: ['fields'], ObjectField: ['name', 'value'], @@ -242,11 +239,12 @@ export const BREAK: unknown = Object.freeze({}); * }) * ``` */ -export function visit(root: N, visitor: ASTVisitor): N; -export function visit(root: ASTNode, visitor: ASTReducer): R; +export function visit(root: N, visitor: ASTVisitor, visitorKeys?: VisitorKeyMap): N; +export function visit(root: ASTNode, visitor: ASTReducer, visitorKeys?: VisitorKeyMap): R; export function visit( root: ASTNode, visitor: ASTVisitor | ASTReducer, + visitorKeys: VisitorKeyMap = QueryDocumentKeys ): any { /* eslint-disable no-undef-init */ let stack: any = undefined; @@ -346,7 +344,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) { From 3f204ed4ca6e83f88a02b50efe6743542b25f4af Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Fri, 27 Aug 2021 17:01:20 +0300 Subject: [PATCH 2/3] Fix prettier --- src/language/__tests__/visitor-test.ts | 8 ++++---- src/language/visitor.ts | 22 ++++++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/language/__tests__/visitor-test.ts b/src/language/__tests__/visitor-test.ts index 71f54c338b..132fc96a26 100644 --- a/src/language/__tests__/visitor-test.ts +++ b/src/language/__tests__/visitor-test.ts @@ -896,7 +896,7 @@ describe('Visitor', () => { it('visits only the specified `Kind` in visitorKeyMap', () => { const visited: Array<[string, string, ReturnType]> = []; - + const visitorKeyMap: VisitorKeyMap = { Document: ['definitions'], OperationDefinition: ['name'], @@ -910,10 +910,10 @@ describe('Visitor', () => { visited.push(['leave', node.kind, getValue(node)]); }, }; - + const exampleDocumentAST = parse(/* GraphQL */ ` - query ExampleOperation { - someField + query ExampleOperation { + someField } `); diff --git a/src/language/visitor.ts b/src/language/visitor.ts index c6aed0a334..9a0c385938 100644 --- a/src/language/visitor.ts +++ b/src/language/visitor.ts @@ -77,9 +77,11 @@ type ReducedField = T extends null | undefined : R; /** -* A KeyMap describes each the traversable properties of each kind of node. -*/ -export type VisitorKeyMap = { [P in keyof KindToNode]?: ReadonlyArray }; + * A KeyMap describes each the traversable properties of each kind of node. + */ +export type VisitorKeyMap = { + [P in keyof KindToNode]?: ReadonlyArray; +}; export const QueryDocumentKeys: VisitorKeyMap = { Document: ['definitions'], @@ -239,12 +241,20 @@ export const BREAK: unknown = Object.freeze({}); * }) * ``` */ -export function visit(root: N, visitor: ASTVisitor, visitorKeys?: VisitorKeyMap): N; -export function visit(root: ASTNode, visitor: ASTReducer, visitorKeys?: VisitorKeyMap): R; +export function visit( + root: N, + visitor: ASTVisitor, + visitorKeys?: VisitorKeyMap, +): N; +export function visit( + root: ASTNode, + visitor: ASTReducer, + visitorKeys?: VisitorKeyMap, +): R; export function visit( root: ASTNode, visitor: ASTVisitor | ASTReducer, - visitorKeys: VisitorKeyMap = QueryDocumentKeys + visitorKeys: VisitorKeyMap = QueryDocumentKeys, ): any { /* eslint-disable no-undef-init */ let stack: any = undefined; From 48b0738138c87bf99d62469a24cc1aff9bd14a42 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Mon, 20 Sep 2021 17:16:29 +0300 Subject: [PATCH 3/3] Review changes --- src/index.ts | 2 +- src/language/__tests__/visitor-test.ts | 74 +++++++++++++------------- src/language/index.ts | 2 +- src/language/visitor.ts | 12 ++--- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/index.ts b/src/index.ts index bc690b6c22..836ca22d0d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -234,7 +234,7 @@ export type { /** Visitor utilities */ ASTVisitor, ASTVisitFn, - VisitorKeyMap, + ASTVisitorKeyMap, /** AST nodes */ ASTNode, ASTKindToNode, diff --git a/src/language/__tests__/visitor-test.ts b/src/language/__tests__/visitor-test.ts index 132fc96a26..e63f03ed4a 100644 --- a/src/language/__tests__/visitor-test.ts +++ b/src/language/__tests__/visitor-test.ts @@ -3,11 +3,11 @@ import { describe, it } from 'mocha'; import { kitchenSinkQuery } from '../../__testUtils__/kitchenSinkQuery'; -import type { ASTKindToNode, ASTNode, SelectionSetNode } from '../ast'; +import type { ASTNode, SelectionSetNode } from '../ast'; +import type { ASTVisitorKeyMap, ASTVisitor } from '../visitor'; import { isNode } from '../ast'; import { Kind } from '../kinds'; import { parse } from '../parser'; -import type { VisitorKeyMap, ASTVisitor } from '../visitor'; import { visit, visitInParallel, BREAK } from '../visitor'; function checkVisitorFnArgs(ast: any, args: any, isEdited: boolean = false) { @@ -463,6 +463,41 @@ describe('Visitor', () => { ]); }); + it('visits only the specified `Kind` in visitorKeyMap', () => { + const visited: Array = []; + + 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, @@ -894,41 +929,6 @@ describe('Visitor', () => { ]); }); - it('visits only the specified `Kind` in visitorKeyMap', () => { - const visited: Array<[string, string, ReturnType]> = []; - - const visitorKeyMap: VisitorKeyMap = { - 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(/* GraphQL */ ` - query ExampleOperation { - someField - } - `); - - visit(exampleDocumentAST, visitor, visitorKeyMap); - - expect(visited).to.deep.equal([ - ['enter', Kind.DOCUMENT, undefined], - ['enter', Kind.OPERATION_DEFINITION, undefined], - ['enter', Kind.NAME, 'ExampleOperation'], - ['leave', Kind.NAME, 'ExampleOperation'], - ['leave', Kind.OPERATION_DEFINITION, undefined], - ['leave', Kind.DOCUMENT, undefined], - ]); - }); - describe('visitInParallel', () => { // Note: nearly identical to the above test of the same test but // using visitInParallel. diff --git a/src/language/index.ts b/src/language/index.ts index 996742c6f9..070ca45d23 100644 --- a/src/language/index.ts +++ b/src/language/index.ts @@ -19,7 +19,7 @@ export type { ParseOptions } from './parser'; export { print } from './printer'; export { visit, visitInParallel, getVisitFn, BREAK } from './visitor'; -export type { ASTVisitor, ASTVisitFn, VisitorKeyMap } from './visitor'; +export type { ASTVisitor, ASTVisitFn, ASTVisitorKeyMap } from './visitor'; export { Location, Token } from './ast'; export type { diff --git a/src/language/visitor.ts b/src/language/visitor.ts index 9a0c385938..df3081bedd 100644 --- a/src/language/visitor.ts +++ b/src/language/visitor.ts @@ -79,11 +79,11 @@ type ReducedField = T extends null | undefined /** * A KeyMap describes each the traversable properties of each kind of node. */ -export type VisitorKeyMap = { - [P in keyof KindToNode]?: ReadonlyArray; +export type ASTVisitorKeyMap = { + [P in keyof ASTKindToNode]?: ReadonlyArray; }; -export const QueryDocumentKeys: VisitorKeyMap = { +export const QueryDocumentKeys: ASTVisitorKeyMap = { Document: ['definitions'], OperationDefinition: [ 'name', @@ -244,17 +244,17 @@ export const BREAK: unknown = Object.freeze({}); export function visit( root: N, visitor: ASTVisitor, - visitorKeys?: VisitorKeyMap, + visitorKeys?: ASTVisitorKeyMap, ): N; export function visit( root: ASTNode, visitor: ASTReducer, - visitorKeys?: VisitorKeyMap, + visitorKeys?: ASTVisitorKeyMap, ): R; export function visit( root: ASTNode, visitor: ASTVisitor | ASTReducer, - visitorKeys: VisitorKeyMap = QueryDocumentKeys, + visitorKeys: ASTVisitorKeyMap = QueryDocumentKeys, ): any { /* eslint-disable no-undef-init */ let stack: any = undefined;