Skip to content

Commit

Permalink
parser tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
twof committed Oct 30, 2024
1 parent eb9b6c8 commit 3a900a9
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 34 deletions.
77 changes: 61 additions & 16 deletions src/language/__tests__/parser-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Kind } from '../kinds';
import { parse, parseConstValue, parseType, parseValue } from '../parser';
import { Source } from '../source';
import { TokenKind } from '../tokenKind';

Check failure on line 13 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

There should be at least one empty line between import groups

Check failure on line 13 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

There should be at least one empty line between import groups

Check failure on line 13 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

There should be at least one empty line between import groups

Check failure on line 13 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

There should be at least one empty line between import groups

Check failure on line 13 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

There should be at least one empty line between import groups
import { Console } from 'console';

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Do not import Node.js builtin module "console"

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unexpected use of 'require("console")'. Use the global variable 'console' instead

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

`console` import should occur before import of `chai`

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'Console' is defined but never used. Allowed unused vars must match /^_T/u

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Do not import Node.js builtin module "console"

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unexpected use of 'require("console")'. Use the global variable 'console' instead

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

`console` import should occur before import of `chai`

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'Console' is defined but never used. Allowed unused vars must match /^_T/u

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Do not import Node.js builtin module "console"

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unexpected use of 'require("console")'. Use the global variable 'console' instead

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

`console` import should occur before import of `chai`

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'Console' is defined but never used. Allowed unused vars must match /^_T/u

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Do not import Node.js builtin module "console"

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unexpected use of 'require("console")'. Use the global variable 'console' instead

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

`console` import should occur before import of `chai`

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'Console' is defined but never used. Allowed unused vars must match /^_T/u

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Do not import Node.js builtin module "console"

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Unexpected use of 'require("console")'. Use the global variable 'console' instead

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

`console` import should occur before import of `chai`

Check failure on line 14 in src/language/__tests__/parser-test.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'Console' is defined but never used. Allowed unused vars must match /^_T/u

function expectSyntaxError(text: string) {
return expectToThrowJSON(() => parse(text));
Expand Down Expand Up @@ -631,11 +632,46 @@ describe('Parser', () => {
});
});

it('parses nested types', () => {
const result = parseType('[MyType!]');
expectJSON(result).toDeepEqual({
kind: Kind.LIST_TYPE,
loc: { start: 0, end: 9 },
type: {
kind: Kind.NON_NULL_TYPE,
loc: { start: 1, end: 8 },
type: {
kind: Kind.NAMED_TYPE,
loc: { start: 1, end: 7 },
name: {
kind: Kind.NAME,
loc: { start: 1, end: 7 },
value: 'MyType',
},
},
},
});
});
});

describe('parseDocumentDirective', () => {
it('doesnt throw on document-level directive', () => {
parse(dedent`
@SemanticNullability
type Query {
hello: String
world: String?
foo: String!
}
`);
});

it('parses semantic-non-null types', () => {
const result = parseType('MyType*');
const result = parseType('MyType', { useSemanticNullability: true });
expectJSON(result).toDeepEqual({
kind: Kind.SEMANTIC_NON_NULL_TYPE,
loc: { start: 0, end: 7 },
loc: { start: 0, end: 6 },
type: {
kind: Kind.NAMED_TYPE,
loc: { start: 0, end: 6 },
Expand All @@ -648,22 +684,31 @@ describe('Parser', () => {
});
});

it('parses nested types', () => {
const result = parseType('[MyType!]');
it('parses nullable types', () => {
const result = parseType('MyType?', { useSemanticNullability: true });
expectJSON(result).toDeepEqual({
kind: Kind.LIST_TYPE,
loc: { start: 0, end: 9 },
kind: Kind.NAMED_TYPE,
loc: { start: 0, end: 6 },
name: {
kind: Kind.NAME,
loc: { start: 0, end: 6 },
value: 'MyType',
},
});
});

it('parses non-nullable types', () => {
const result = parseType('MyType!', { useSemanticNullability: true });
expectJSON(result).toDeepEqual({
kind: Kind.NON_NULL_TYPE,
loc: { start: 0, end: 7 },
type: {
kind: Kind.NON_NULL_TYPE,
loc: { start: 1, end: 8 },
type: {
kind: Kind.NAMED_TYPE,
loc: { start: 1, end: 7 },
name: {
kind: Kind.NAME,
loc: { start: 1, end: 7 },
value: 'MyType',
},
kind: Kind.NAMED_TYPE,
loc: { start: 0, end: 6 },
name: {
kind: Kind.NAME,
loc: { start: 0, end: 6 },
value: 'MyType',
},
},
});
Expand Down
8 changes: 4 additions & 4 deletions src/language/lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class Lexer {
export function isPunctuatorTokenKind(kind: TokenKind): boolean {
return (
kind === TokenKind.BANG ||
kind === TokenKind.ASTERISK ||
kind === TokenKind.QUESTION_MARK ||
kind === TokenKind.DOLLAR ||
kind === TokenKind.AMP ||
kind === TokenKind.PAREN_L ||
Expand Down Expand Up @@ -247,7 +247,7 @@ function readNextToken(lexer: Lexer, start: number): Token {
// - FloatValue
// - StringValue
//
// Punctuator :: one of ! $ & ( ) * ... : = @ [ ] { | }
// Punctuator :: one of ! $ & ( ) ? ... : = @ [ ] { | }
case 0x0021: // !
return createToken(lexer, TokenKind.BANG, position, position + 1);
case 0x0024: // $
Expand All @@ -258,8 +258,8 @@ function readNextToken(lexer: Lexer, start: number): Token {
return createToken(lexer, TokenKind.PAREN_L, position, position + 1);
case 0x0029: // )
return createToken(lexer, TokenKind.PAREN_R, position, position + 1);
case 0x002a: // *
return createToken(lexer, TokenKind.ASTERISK, position, position + 1);
case 0x003f: // ?
return createToken(lexer, TokenKind.QUESTION_MARK, position, position + 1);
case 0x002e: // .
if (
body.charCodeAt(position + 1) === 0x002e &&
Expand Down
46 changes: 33 additions & 13 deletions src/language/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export interface ParseOptions {
* ```
*/
allowLegacyFragmentVariables?: boolean;

useSemanticNullability?: boolean;
}

/**
Expand Down Expand Up @@ -250,6 +252,14 @@ export class Parser {
* - InputObjectTypeDefinition
*/
parseDefinition(): DefinitionNode {
// TODO: I don't know what isConst represents. Every other callsite has it false
let directives = this.parseDirectives(false);

Check failure on line 256 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directives' is never reassigned. Use 'const' instead

Check failure on line 256 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directives' is never reassigned. Use 'const' instead

Check failure on line 256 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directives' is never reassigned. Use 'const' instead

Check failure on line 256 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directives' is never reassigned. Use 'const' instead

Check failure on line 256 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directives' is never reassigned. Use 'const' instead
for (let directive of directives) {

Check failure on line 257 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directive' is never reassigned. Use 'const' instead

Check failure on line 257 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directive' is never reassigned. Use 'const' instead

Check failure on line 257 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directive' is never reassigned. Use 'const' instead

Check failure on line 257 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directive' is never reassigned. Use 'const' instead

Check failure on line 257 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

'directive' is never reassigned. Use 'const' instead
if (directive.name.value == "SemanticNullability") {

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected '===' and instead saw '=='

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Strings must use singlequote

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected '===' and instead saw '=='

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Strings must use singlequote

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected '===' and instead saw '=='

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Strings must use singlequote

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected '===' and instead saw '=='

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Strings must use singlequote

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Expected '===' and instead saw '=='

Check failure on line 258 in src/language/parser.ts

View workflow job for this annotation

GitHub Actions / ci / Lint source files

Strings must use singlequote
this._options.useSemanticNullability = true;
}
}

if (this.peek(TokenKind.BRACE_L)) {
return this.parseOperationDefinition();
}
Expand Down Expand Up @@ -757,20 +767,30 @@ export class Parser {
type = this.parseNamedType();
}

if (this.expectOptionalToken(TokenKind.BANG)) {
return this.node<NonNullTypeNode>(start, {
kind: Kind.NON_NULL_TYPE,
type,
});
}
if (this.expectOptionalToken(TokenKind.ASTERISK)) {
return this.node<SemanticNonNullTypeNode>(start, {
kind: Kind.SEMANTIC_NON_NULL_TYPE,
type,
});
}
if (this._options.useSemanticNullability) {
if (this.expectOptionalToken(TokenKind.BANG)) {
return this.node<NonNullTypeNode>(start, {
kind: Kind.NON_NULL_TYPE,
type,
});
} else if (this.expectOptionalToken(TokenKind.QUESTION_MARK)) {
return type;
} else {
return this.node<SemanticNonNullTypeNode>(start, {
kind: Kind.SEMANTIC_NON_NULL_TYPE,
type,
});
}
} else {
if (this.expectOptionalToken(TokenKind.BANG)) {
return this.node<NonNullTypeNode>(start, {
kind: Kind.NON_NULL_TYPE,
type,
});
}

return type;
return type;
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/language/tokenKind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ enum TokenKind {
SOF = '<SOF>',
EOF = '<EOF>',
BANG = '!',
ASTERISK = '*',
QUESTION_MARK = '?',
DOLLAR = '$',
AMP = '&',
PAREN_L = '(',
Expand Down

0 comments on commit 3a900a9

Please sign in to comment.