Skip to content

Commit 61a07b1

Browse files
Resolve import cycle by moving 'visitWithTypeInfo' into 'TypeIn… (#2274)
1 parent 7e1c9ed commit 61a07b1

17 files changed

+326
-287
lines changed

src/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,6 @@ export {
188188
// Visit
189189
visit,
190190
visitInParallel,
191-
visitWithTypeInfo,
192191
getVisitFn,
193192
BREAK,
194193
Kind,
@@ -382,6 +381,7 @@ export {
382381
// A helper to use within recursive-descent visitors which need to be aware of
383382
// the GraphQL type system.
384383
TypeInfo,
384+
visitWithTypeInfo,
385385
// Coerces a JavaScript value to a GraphQL type, or produces errors.
386386
coerceInputValue,
387387
// Concatenates multiple AST together.

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ export {
189189
// Visit
190190
visit,
191191
visitInParallel,
192-
visitWithTypeInfo,
193192
getVisitFn,
194193
BREAK,
195194
Kind,
@@ -382,6 +381,7 @@ export {
382381
// A helper to use within recursive-descent visitors which need to be aware of
383382
// the GraphQL type system.
384383
TypeInfo,
384+
visitWithTypeInfo,
385385
// Coerces a JavaScript value to a GraphQL type, or produces errors.
386386
coerceInputValue,
387387
// Concatenates multiple AST together.

src/language/__tests__/visitor-test.js

Lines changed: 1 addition & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,11 @@
33
import { expect } from 'chai';
44
import { describe, it } from 'mocha';
55

6-
import { getNamedType, isCompositeType } from '../../type/definition';
7-
import { TypeInfo } from '../../utilities/TypeInfo';
8-
96
import { Kind } from '../kinds';
107
import { parse } from '../parser';
11-
import { print } from '../printer';
12-
import { visit, visitInParallel, visitWithTypeInfo, BREAK } from '../visitor';
8+
import { visit, visitInParallel, BREAK } from '../visitor';
139

1410
import { kitchenSinkQuery } from '../../__fixtures__';
15-
import { testSchema } from '../../validation/__tests__/harness';
1611

1712
function checkVisitorFnArgs(ast, args, isEdited) {
1813
const [node, key, parent, path, ancestors] = args;
@@ -1309,213 +1304,4 @@ describe('Visitor', () => {
13091304
]);
13101305
});
13111306
});
1312-
1313-
describe('visitWithTypeInfo', () => {
1314-
it('maintains type info during visit', () => {
1315-
const visited = [];
1316-
1317-
const typeInfo = new TypeInfo(testSchema);
1318-
1319-
const ast = parse(
1320-
'{ human(id: 4) { name, pets { ... { name } }, unknown } }',
1321-
);
1322-
visit(
1323-
ast,
1324-
visitWithTypeInfo(typeInfo, {
1325-
enter(node) {
1326-
checkVisitorFnArgs(ast, arguments);
1327-
const parentType = typeInfo.getParentType();
1328-
const type = typeInfo.getType();
1329-
const inputType = typeInfo.getInputType();
1330-
visited.push([
1331-
'enter',
1332-
node.kind,
1333-
node.kind === 'Name' ? node.value : null,
1334-
parentType ? String(parentType) : null,
1335-
type ? String(type) : null,
1336-
inputType ? String(inputType) : null,
1337-
]);
1338-
},
1339-
leave(node) {
1340-
checkVisitorFnArgs(ast, arguments);
1341-
const parentType = typeInfo.getParentType();
1342-
const type = typeInfo.getType();
1343-
const inputType = typeInfo.getInputType();
1344-
visited.push([
1345-
'leave',
1346-
node.kind,
1347-
node.kind === 'Name' ? node.value : null,
1348-
parentType ? String(parentType) : null,
1349-
type ? String(type) : null,
1350-
inputType ? String(inputType) : null,
1351-
]);
1352-
},
1353-
}),
1354-
);
1355-
1356-
expect(visited).to.deep.equal([
1357-
['enter', 'Document', null, null, null, null],
1358-
['enter', 'OperationDefinition', null, null, 'QueryRoot', null],
1359-
['enter', 'SelectionSet', null, 'QueryRoot', 'QueryRoot', null],
1360-
['enter', 'Field', null, 'QueryRoot', 'Human', null],
1361-
['enter', 'Name', 'human', 'QueryRoot', 'Human', null],
1362-
['leave', 'Name', 'human', 'QueryRoot', 'Human', null],
1363-
['enter', 'Argument', null, 'QueryRoot', 'Human', 'ID'],
1364-
['enter', 'Name', 'id', 'QueryRoot', 'Human', 'ID'],
1365-
['leave', 'Name', 'id', 'QueryRoot', 'Human', 'ID'],
1366-
['enter', 'IntValue', null, 'QueryRoot', 'Human', 'ID'],
1367-
['leave', 'IntValue', null, 'QueryRoot', 'Human', 'ID'],
1368-
['leave', 'Argument', null, 'QueryRoot', 'Human', 'ID'],
1369-
['enter', 'SelectionSet', null, 'Human', 'Human', null],
1370-
['enter', 'Field', null, 'Human', 'String', null],
1371-
['enter', 'Name', 'name', 'Human', 'String', null],
1372-
['leave', 'Name', 'name', 'Human', 'String', null],
1373-
['leave', 'Field', null, 'Human', 'String', null],
1374-
['enter', 'Field', null, 'Human', '[Pet]', null],
1375-
['enter', 'Name', 'pets', 'Human', '[Pet]', null],
1376-
['leave', 'Name', 'pets', 'Human', '[Pet]', null],
1377-
['enter', 'SelectionSet', null, 'Pet', '[Pet]', null],
1378-
['enter', 'InlineFragment', null, 'Pet', 'Pet', null],
1379-
['enter', 'SelectionSet', null, 'Pet', 'Pet', null],
1380-
['enter', 'Field', null, 'Pet', 'String', null],
1381-
['enter', 'Name', 'name', 'Pet', 'String', null],
1382-
['leave', 'Name', 'name', 'Pet', 'String', null],
1383-
['leave', 'Field', null, 'Pet', 'String', null],
1384-
['leave', 'SelectionSet', null, 'Pet', 'Pet', null],
1385-
['leave', 'InlineFragment', null, 'Pet', 'Pet', null],
1386-
['leave', 'SelectionSet', null, 'Pet', '[Pet]', null],
1387-
['leave', 'Field', null, 'Human', '[Pet]', null],
1388-
['enter', 'Field', null, 'Human', null, null],
1389-
['enter', 'Name', 'unknown', 'Human', null, null],
1390-
['leave', 'Name', 'unknown', 'Human', null, null],
1391-
['leave', 'Field', null, 'Human', null, null],
1392-
['leave', 'SelectionSet', null, 'Human', 'Human', null],
1393-
['leave', 'Field', null, 'QueryRoot', 'Human', null],
1394-
['leave', 'SelectionSet', null, 'QueryRoot', 'QueryRoot', null],
1395-
['leave', 'OperationDefinition', null, null, 'QueryRoot', null],
1396-
['leave', 'Document', null, null, null, null],
1397-
]);
1398-
});
1399-
1400-
it('maintains type info during edit', () => {
1401-
const visited = [];
1402-
const typeInfo = new TypeInfo(testSchema);
1403-
1404-
const ast = parse('{ human(id: 4) { name, pets }, alien }');
1405-
const editedAST = visit(
1406-
ast,
1407-
visitWithTypeInfo(typeInfo, {
1408-
enter(node) {
1409-
checkVisitorFnArgs(ast, arguments, /* isEdited */ true);
1410-
const parentType = typeInfo.getParentType();
1411-
const type = typeInfo.getType();
1412-
const inputType = typeInfo.getInputType();
1413-
visited.push([
1414-
'enter',
1415-
node.kind,
1416-
node.kind === 'Name' ? node.value : null,
1417-
parentType ? String(parentType) : null,
1418-
type ? String(type) : null,
1419-
inputType ? String(inputType) : null,
1420-
]);
1421-
1422-
// Make a query valid by adding missing selection sets.
1423-
if (
1424-
node.kind === 'Field' &&
1425-
!node.selectionSet &&
1426-
isCompositeType(getNamedType(type))
1427-
) {
1428-
return {
1429-
kind: 'Field',
1430-
alias: node.alias,
1431-
name: node.name,
1432-
arguments: node.arguments,
1433-
directives: node.directives,
1434-
selectionSet: {
1435-
kind: 'SelectionSet',
1436-
selections: [
1437-
{
1438-
kind: 'Field',
1439-
name: { kind: 'Name', value: '__typename' },
1440-
},
1441-
],
1442-
},
1443-
};
1444-
}
1445-
},
1446-
leave(node) {
1447-
checkVisitorFnArgs(ast, arguments, /* isEdited */ true);
1448-
const parentType = typeInfo.getParentType();
1449-
const type = typeInfo.getType();
1450-
const inputType = typeInfo.getInputType();
1451-
visited.push([
1452-
'leave',
1453-
node.kind,
1454-
node.kind === 'Name' ? node.value : null,
1455-
parentType ? String(parentType) : null,
1456-
type ? String(type) : null,
1457-
inputType ? String(inputType) : null,
1458-
]);
1459-
},
1460-
}),
1461-
);
1462-
1463-
expect(print(ast)).to.deep.equal(
1464-
print(parse('{ human(id: 4) { name, pets }, alien }')),
1465-
);
1466-
1467-
expect(print(editedAST)).to.deep.equal(
1468-
print(
1469-
parse(
1470-
'{ human(id: 4) { name, pets { __typename } }, alien { __typename } }',
1471-
),
1472-
),
1473-
);
1474-
1475-
expect(visited).to.deep.equal([
1476-
['enter', 'Document', null, null, null, null],
1477-
['enter', 'OperationDefinition', null, null, 'QueryRoot', null],
1478-
['enter', 'SelectionSet', null, 'QueryRoot', 'QueryRoot', null],
1479-
['enter', 'Field', null, 'QueryRoot', 'Human', null],
1480-
['enter', 'Name', 'human', 'QueryRoot', 'Human', null],
1481-
['leave', 'Name', 'human', 'QueryRoot', 'Human', null],
1482-
['enter', 'Argument', null, 'QueryRoot', 'Human', 'ID'],
1483-
['enter', 'Name', 'id', 'QueryRoot', 'Human', 'ID'],
1484-
['leave', 'Name', 'id', 'QueryRoot', 'Human', 'ID'],
1485-
['enter', 'IntValue', null, 'QueryRoot', 'Human', 'ID'],
1486-
['leave', 'IntValue', null, 'QueryRoot', 'Human', 'ID'],
1487-
['leave', 'Argument', null, 'QueryRoot', 'Human', 'ID'],
1488-
['enter', 'SelectionSet', null, 'Human', 'Human', null],
1489-
['enter', 'Field', null, 'Human', 'String', null],
1490-
['enter', 'Name', 'name', 'Human', 'String', null],
1491-
['leave', 'Name', 'name', 'Human', 'String', null],
1492-
['leave', 'Field', null, 'Human', 'String', null],
1493-
['enter', 'Field', null, 'Human', '[Pet]', null],
1494-
['enter', 'Name', 'pets', 'Human', '[Pet]', null],
1495-
['leave', 'Name', 'pets', 'Human', '[Pet]', null],
1496-
['enter', 'SelectionSet', null, 'Pet', '[Pet]', null],
1497-
['enter', 'Field', null, 'Pet', 'String!', null],
1498-
['enter', 'Name', '__typename', 'Pet', 'String!', null],
1499-
['leave', 'Name', '__typename', 'Pet', 'String!', null],
1500-
['leave', 'Field', null, 'Pet', 'String!', null],
1501-
['leave', 'SelectionSet', null, 'Pet', '[Pet]', null],
1502-
['leave', 'Field', null, 'Human', '[Pet]', null],
1503-
['leave', 'SelectionSet', null, 'Human', 'Human', null],
1504-
['leave', 'Field', null, 'QueryRoot', 'Human', null],
1505-
['enter', 'Field', null, 'QueryRoot', 'Alien', null],
1506-
['enter', 'Name', 'alien', 'QueryRoot', 'Alien', null],
1507-
['leave', 'Name', 'alien', 'QueryRoot', 'Alien', null],
1508-
['enter', 'SelectionSet', null, 'Alien', 'Alien', null],
1509-
['enter', 'Field', null, 'Alien', 'String!', null],
1510-
['enter', 'Name', '__typename', 'Alien', 'String!', null],
1511-
['leave', 'Name', '__typename', 'Alien', 'String!', null],
1512-
['leave', 'Field', null, 'Alien', 'String!', null],
1513-
['leave', 'SelectionSet', null, 'Alien', 'Alien', null],
1514-
['leave', 'Field', null, 'QueryRoot', 'Alien', null],
1515-
['leave', 'SelectionSet', null, 'QueryRoot', 'QueryRoot', null],
1516-
['leave', 'OperationDefinition', null, null, 'QueryRoot', null],
1517-
['leave', 'Document', null, null, null, null],
1518-
]);
1519-
});
1520-
});
15211307
});

src/language/ast.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ export class Token {
8888
);
8989
}
9090

91+
/**
92+
* @internal
93+
*/
94+
export function isNode(maybeNode: any): maybeNode is ASTNode;
95+
9196
/**
9297
* The list of all possible AST node types.
9398
*/

src/language/ast.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ defineToJSON(Token, function() {
122122
};
123123
});
124124

125+
/**
126+
* @internal
127+
*/
128+
export function isNode(maybeNode: mixed): boolean %checks {
129+
return maybeNode != null && typeof maybeNode.kind === 'string';
130+
}
131+
125132
/**
126133
* The list of all possible AST node types.
127134
*/

src/language/index.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export { print } from './printer';
1111
export {
1212
visit,
1313
visitInParallel,
14-
visitWithTypeInfo,
1514
getVisitFn,
1615
BREAK,
1716
ASTVisitor,

src/language/index.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,7 @@ export type { ParseOptions } from './parser';
2020

2121
export { print } from './printer';
2222

23-
export {
24-
visit,
25-
visitInParallel,
26-
visitWithTypeInfo,
27-
getVisitFn,
28-
BREAK,
29-
} from './visitor';
23+
export { visit, visitInParallel, getVisitFn, BREAK } from './visitor';
3024
export type { ASTVisitor, Visitor, VisitFn, VisitorKeyMap } from './visitor';
3125

3226
export type {

src/language/visitor.d.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import Maybe from '../tsutils/Maybe';
2-
import { TypeInfo } from '../utilities/TypeInfo';
32
import { ASTNode, ASTKindToNode } from './ast';
43

54
/**
@@ -251,15 +250,6 @@ export function visitInParallel(
251250
visitors: ReadonlyArray<Visitor<ASTKindToNode>>,
252251
): Visitor<ASTKindToNode>;
253252

254-
/**
255-
* Creates a new visitor instance which maintains a provided TypeInfo instance
256-
* along with visiting visitor.
257-
*/
258-
export function visitWithTypeInfo(
259-
typeInfo: TypeInfo,
260-
visitor: Visitor<ASTKindToNode>,
261-
): Visitor<ASTKindToNode>;
262-
263253
/**
264254
* Given a visitor instance, if it is leaving or not, and a node kind, return
265255
* the function the visitor runtime should call.

src/language/visitor.js

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
import inspect from '../jsutils/inspect';
44

5-
import { type TypeInfo } from '../utilities/TypeInfo';
6-
7-
import { type ASTNode, type ASTKindToNode } from './ast';
5+
import { type ASTNode, type ASTKindToNode, isNode } from './ast';
86

97
/**
108
* A visitor is provided to visit, it contains the collection of
@@ -351,10 +349,6 @@ export function visit(
351349
return newRoot;
352350
}
353351

354-
function isNode(maybeNode): boolean %checks {
355-
return maybeNode != null && typeof maybeNode.kind === 'string';
356-
}
357-
358352
/**
359353
* Creates a new visitor instance which delegates to many visitors to run in
360354
* parallel. Each visitor will be visited for each node before moving on.
@@ -404,41 +398,6 @@ export function visitInParallel(
404398
};
405399
}
406400

407-
/**
408-
* Creates a new visitor instance which maintains a provided TypeInfo instance
409-
* along with visiting visitor.
410-
*/
411-
export function visitWithTypeInfo(
412-
typeInfo: TypeInfo,
413-
visitor: Visitor<ASTKindToNode>,
414-
): Visitor<ASTKindToNode> {
415-
return {
416-
enter(node) {
417-
typeInfo.enter(node);
418-
const fn = getVisitFn(visitor, node.kind, /* isLeaving */ false);
419-
if (fn) {
420-
const result = fn.apply(visitor, arguments);
421-
if (result !== undefined) {
422-
typeInfo.leave(node);
423-
if (isNode(result)) {
424-
typeInfo.enter(result);
425-
}
426-
}
427-
return result;
428-
}
429-
},
430-
leave(node) {
431-
const fn = getVisitFn(visitor, node.kind, /* isLeaving */ true);
432-
let result;
433-
if (fn) {
434-
result = fn.apply(visitor, arguments);
435-
}
436-
typeInfo.leave(node);
437-
return result;
438-
},
439-
};
440-
}
441-
442401
/**
443402
* Given a visitor instance, if it is leaving or not, and a node kind, return
444403
* the function the visitor runtime should call.

0 commit comments

Comments
 (0)