Skip to content

Commit 5eea2b1

Browse files
committed
add enum syntax
1 parent 52c78d9 commit 5eea2b1

File tree

11 files changed

+134
-53
lines changed

11 files changed

+134
-53
lines changed

src/language/__tests__/parser-test.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,14 +703,14 @@ describe('Parser', () => {
703703
it('parses Name . Name', () => {
704704
const result = parseSchemaCoordinate('MyType.field');
705705
expectJSON(result).toDeepEqual({
706-
kind: Kind.MEMBER_COORDINATE,
706+
kind: Kind.FIELD_COORDINATE,
707707
loc: { start: 0, end: 12 },
708708
name: {
709709
kind: Kind.NAME,
710710
loc: { start: 0, end: 6 },
711711
value: 'MyType',
712712
},
713-
memberName: {
713+
fieldName: {
714714
kind: Kind.NAME,
715715
loc: { start: 7, end: 12 },
716716
value: 'field',
@@ -727,6 +727,24 @@ describe('Parser', () => {
727727
});
728728
});
729729

730+
it('parses Name :: Name', () => {
731+
const result = parseSchemaCoordinate('MyEnum::value');
732+
expectJSON(result).toDeepEqual({
733+
kind: Kind.VALUE_COORDINATE,
734+
loc: { start: 0, end: 13 },
735+
name: {
736+
kind: Kind.NAME,
737+
loc: { start: 0, end: 6 },
738+
value: 'MyEnum',
739+
},
740+
valueName: {
741+
kind: Kind.NAME,
742+
loc: { start: 8, end: 13 },
743+
value: 'value',
744+
},
745+
});
746+
});
747+
730748
it('parses Name . Name ( Name : )', () => {
731749
const result = parseSchemaCoordinate('MyType.field(arg:)');
732750
expectJSON(result).toDeepEqual({

src/language/__tests__/predicates-test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ describe('AST node predicates', () => {
148148
'ArgumentCoordinate',
149149
'DirectiveArgumentCoordinate',
150150
'DirectiveCoordinate',
151-
'MemberCoordinate',
151+
'FieldCoordinate',
152152
'TypeCoordinate',
153+
'ValueCoordinate',
153154
]);
154155
});
155156
});

src/language/ast.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,9 @@ export type ASTNode =
183183
| EnumTypeExtensionNode
184184
| InputObjectTypeExtensionNode
185185
| TypeCoordinateNode
186-
| MemberCoordinateNode
186+
| FieldCoordinateNode
187187
| ArgumentCoordinateNode
188+
| ValueCoordinateNode
188189
| DirectiveCoordinateNode
189190
| DirectiveArgumentCoordinateNode;
190191

@@ -295,8 +296,9 @@ export const QueryDocumentKeys: {
295296

296297
// Schema Coordinates
297298
TypeCoordinate: ['name'],
298-
MemberCoordinate: ['name', 'memberName'],
299+
FieldCoordinate: ['name', 'fieldName'],
299300
ArgumentCoordinate: ['name', 'fieldName', 'argumentName'],
301+
ValueCoordinate: ['name', 'valueName'],
300302
DirectiveCoordinate: ['name'],
301303
DirectiveArgumentCoordinate: ['name', 'argumentName'],
302304
};
@@ -779,8 +781,9 @@ export interface InputObjectTypeExtensionNode {
779781

780782
export type SchemaCoordinateNode =
781783
| TypeCoordinateNode
782-
| MemberCoordinateNode
784+
| FieldCoordinateNode
783785
| ArgumentCoordinateNode
786+
| ValueCoordinateNode
784787
| DirectiveCoordinateNode
785788
| DirectiveArgumentCoordinateNode;
786789

@@ -790,11 +793,11 @@ export interface TypeCoordinateNode {
790793
readonly name: NameNode;
791794
}
792795

793-
export interface MemberCoordinateNode {
794-
readonly kind: typeof Kind.MEMBER_COORDINATE;
796+
export interface FieldCoordinateNode {
797+
readonly kind: typeof Kind.FIELD_COORDINATE;
795798
readonly loc?: Location;
796799
readonly name: NameNode;
797-
readonly memberName: NameNode;
800+
readonly fieldName: NameNode;
798801
}
799802

800803
export interface ArgumentCoordinateNode {
@@ -805,6 +808,13 @@ export interface ArgumentCoordinateNode {
805808
readonly argumentName: NameNode;
806809
}
807810

811+
export interface ValueCoordinateNode {
812+
readonly kind: typeof Kind.VALUE_COORDINATE;
813+
readonly loc?: Location;
814+
readonly name: NameNode;
815+
readonly valueName: NameNode;
816+
}
817+
808818
export interface DirectiveCoordinateNode {
809819
readonly kind: typeof Kind.DIRECTIVE_COORDINATE;
810820
readonly loc?: Location;

src/language/kinds_.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,15 @@ export type INPUT_OBJECT_TYPE_EXTENSION = typeof INPUT_OBJECT_TYPE_EXTENSION;
113113
export const TYPE_COORDINATE = 'TypeCoordinate';
114114
export type TYPE_COORDINATE = typeof TYPE_COORDINATE;
115115

116-
export const MEMBER_COORDINATE = 'MemberCoordinate';
117-
export type MEMBER_COORDINATE = typeof MEMBER_COORDINATE;
116+
export const FIELD_COORDINATE = 'FieldCoordinate';
117+
export type FIELD_COORDINATE = typeof FIELD_COORDINATE;
118118

119119
export const ARGUMENT_COORDINATE = 'ArgumentCoordinate';
120120
export type ARGUMENT_COORDINATE = typeof ARGUMENT_COORDINATE;
121121

122+
export const VALUE_COORDINATE = 'ValueCoordinate';
123+
export type VALUE_COORDINATE = typeof VALUE_COORDINATE;
124+
122125
export const DIRECTIVE_COORDINATE = 'DirectiveCoordinate';
123126
export type DIRECTIVE_COORDINATE = typeof DIRECTIVE_COORDINATE;
124127

src/language/lexer.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export function isPunctuatorTokenKind(kind: TokenKind): boolean {
9898
kind === TokenKind.DOT ||
9999
kind === TokenKind.SPREAD ||
100100
kind === TokenKind.COLON ||
101+
kind === TokenKind.TWO_COLON ||
101102
kind === TokenKind.EQUALS ||
102103
kind === TokenKind.AT ||
103104
kind === TokenKind.BRACKET_L ||
@@ -271,6 +272,14 @@ function readNextToken(lexer: Lexer, start: number): Token {
271272
return readDot(lexer, position);
272273
}
273274
case 0x003a: // :
275+
if (body.charCodeAt(position + 1) === 0x003a) {
276+
return createToken(
277+
lexer,
278+
TokenKind.TWO_COLON,
279+
position,
280+
position + 2,
281+
);
282+
}
274283
return createToken(lexer, TokenKind.COLON, position, position + 1);
275284
case 0x003d: // =
276285
return createToken(lexer, TokenKind.EQUALS, position, position + 1);

src/language/parser.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import type {
2323
EnumTypeExtensionNode,
2424
EnumValueDefinitionNode,
2525
EnumValueNode,
26+
FieldCoordinateNode,
2627
FieldDefinitionNode,
2728
FieldNode,
2829
FloatValueNode,
@@ -38,7 +39,6 @@ import type {
3839
IntValueNode,
3940
ListTypeNode,
4041
ListValueNode,
41-
MemberCoordinateNode,
4242
NamedTypeNode,
4343
NameNode,
4444
NonNullTypeNode,
@@ -63,6 +63,7 @@ import type {
6363
TypeSystemExtensionNode,
6464
UnionTypeDefinitionNode,
6565
UnionTypeExtensionNode,
66+
ValueCoordinateNode,
6667
ValueNode,
6768
VariableDefinitionNode,
6869
VariableNode,
@@ -1466,13 +1467,24 @@ export class Parser {
14661467
* - Name
14671468
* - Name . Name
14681469
* - Name . Name ( Name : )
1470+
* - Name :: Name
14691471
* - @ Name
14701472
* - @ Name ( Name : )
14711473
*/
14721474
parseSchemaCoordinate(): SchemaCoordinateNode {
14731475
const start = this._lexer.token;
14741476
const ofDirective = this.expectOptionalToken(TokenKind.AT);
14751477
const name = this.parseName();
1478+
1479+
if (!ofDirective && this.expectOptionalToken(TokenKind.TWO_COLON)) {
1480+
const valueName = this.parseName();
1481+
return this.node<ValueCoordinateNode>(start, {
1482+
kind: Kind.VALUE_COORDINATE,
1483+
name,
1484+
valueName,
1485+
});
1486+
}
1487+
14761488
let memberName: NameNode | undefined;
14771489
if (!ofDirective && this.expectOptionalToken(TokenKind.DOT)) {
14781490
memberName = this.parseName();
@@ -1508,10 +1520,10 @@ export class Parser {
15081520
argumentName,
15091521
});
15101522
}
1511-
return this.node<MemberCoordinateNode>(start, {
1512-
kind: Kind.MEMBER_COORDINATE,
1523+
return this.node<FieldCoordinateNode>(start, {
1524+
kind: Kind.FIELD_COORDINATE,
15131525
name,
1514-
memberName,
1526+
fieldName: memberName,
15151527
});
15161528
}
15171529

src/language/predicates.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@ export function isSchemaCoordinateNode(
117117
): node is SchemaCoordinateNode {
118118
return (
119119
node.kind === Kind.TYPE_COORDINATE ||
120-
node.kind === Kind.MEMBER_COORDINATE ||
120+
node.kind === Kind.FIELD_COORDINATE ||
121121
node.kind === Kind.ARGUMENT_COORDINATE ||
122+
node.kind === Kind.VALUE_COORDINATE ||
122123
node.kind === Kind.DIRECTIVE_COORDINATE ||
123124
node.kind === Kind.DIRECTIVE_ARGUMENT_COORDINATE
124125
);

src/language/printer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,15 +325,19 @@ const printDocASTReducer: ASTReducer<string> = {
325325

326326
TypeCoordinate: { leave: ({ name }) => name },
327327

328-
MemberCoordinate: {
329-
leave: ({ name, memberName }) => join([name, wrap('.', memberName)]),
328+
FieldCoordinate: {
329+
leave: ({ name, fieldName }) => join([name, wrap('.', fieldName)]),
330330
},
331331

332332
ArgumentCoordinate: {
333333
leave: ({ name, fieldName, argumentName }) =>
334334
join([name, wrap('.', fieldName), wrap('(', argumentName, ':)')]),
335335
},
336336

337+
ValueCoordinate: {
338+
leave: ({ name, valueName }) => join([name, wrap('::', valueName)]),
339+
},
340+
337341
DirectiveCoordinate: { leave: ({ name }) => join(['@', name]) },
338342

339343
DirectiveArgumentCoordinate: {

src/language/tokenKind.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const TokenKind = {
1313
DOT: '.',
1414
SPREAD: '...' as const,
1515
COLON: ':' as const,
16+
TWO_COLON: '::' as const,
1617
EQUALS: '=' as const,
1718
AT: '@' as const,
1819
BRACKET_L: '[' as const,

src/utilities/__tests__/resolveSchemaCoordinate-test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('resolveSchemaCoordinate', () => {
7171
);
7272

7373
expect(() => resolveSchemaCoordinate(schema, 'String.field')).to.throw(
74-
'Expected "String" to be an object type, interface type, input object type, or enum type.',
74+
'Expected "String" to be an Input Object, Object or Interface type.',
7575
);
7676
});
7777

@@ -101,15 +101,15 @@ describe('resolveSchemaCoordinate', () => {
101101
const type = schema.getType('SearchFilter') as GraphQLEnumType;
102102
const enumValue = type.getValue('OPEN_NOW');
103103
expect(
104-
resolveSchemaCoordinate(schema, 'SearchFilter.OPEN_NOW'),
104+
resolveSchemaCoordinate(schema, 'SearchFilter::OPEN_NOW'),
105105
).to.deep.equal({
106106
kind: 'EnumValue',
107107
type,
108108
enumValue,
109109
});
110110

111111
expect(
112-
resolveSchemaCoordinate(schema, 'SearchFilter.UNKNOWN'),
112+
resolveSchemaCoordinate(schema, 'SearchFilter::UNKNOWN'),
113113
).to.deep.equal(undefined);
114114
});
115115

0 commit comments

Comments
 (0)