Skip to content

Commit 3da9a6a

Browse files
committed
Merge branch 'master' of https://github.com/nveenjain/graphql-js into feature/addCommentInAST
Signed-off-by: Naveen Jain <[email protected]>
2 parents 5a5825c + 688f93c commit 3da9a6a

20 files changed

+523
-388
lines changed

.eslintrc.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ overrides:
433433
flowtype/require-valid-file-annotation: off
434434

435435
##########################################################################
436-
# `@typescript-eslint/eslint-plugin` rule list based on `v2.17.x`
436+
# `@typescript-eslint/eslint-plugin` rule list based on `v2.21.x`
437437
##########################################################################
438438

439439
# Supported Rules

.flowconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)?)\\)
4040
suppress_comment=\\(.\\|\n\\)*\\$DisableFlowOnNegativeTest
4141

4242
[version]
43-
^0.118.0
43+
^0.119.0

package.json

+11-11
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,23 @@
4444
},
4545
"dependencies": {},
4646
"devDependencies": {
47-
"@babel/core": "7.8.4",
47+
"@babel/core": "7.8.6",
4848
"@babel/plugin-transform-flow-strip-types": "7.8.3",
49-
"@babel/preset-env": "7.8.4",
50-
"@babel/register": "7.8.3",
51-
"@typescript-eslint/eslint-plugin": "2.19.2",
52-
"@typescript-eslint/parser": "2.19.2",
53-
"babel-eslint": "10.0.3",
49+
"@babel/preset-env": "7.8.6",
50+
"@babel/register": "7.8.6",
51+
"@typescript-eslint/eslint-plugin": "2.21.0",
52+
"@typescript-eslint/parser": "2.21.0",
53+
"babel-eslint": "10.1.0",
5454
"chai": "4.2.0",
55-
"cspell": "4.0.46",
56-
"dtslint": "2.0.6",
55+
"cspell": "4.0.55",
56+
"dtslint": "3.2.0",
5757
"eslint": "6.8.0",
5858
"eslint-plugin-flowtype": "4.6.0",
5959
"eslint-plugin-import": "2.20.1",
60-
"flow-bin": "0.118.0",
61-
"mocha": "7.0.1",
60+
"flow-bin": "0.119.1",
61+
"mocha": "7.1.0",
6262
"nyc": "15.0.0",
6363
"prettier": "1.19.1",
64-
"typescript": "^3.7.5"
64+
"typescript": "^3.8.3"
6565
}
6666
}

src/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Each sub directory within is a sub-module of graphql-js:
1717
fulfilling a GraphQL result.
1818
- [`graphql/execution`](execution/README.md): The Execution phase of fulfilling
1919
a GraphQL request.
20-
- [`graphql/error`](error/README.md): Creating and formating GraphQL errors.
20+
- [`graphql/error`](error/README.md): Creating and formatting GraphQL errors.
2121
- [`graphql/utilities`](utilities/README.md): Common useful computations upon
2222
the GraphQL language and type objects.
2323
- [`graphql/subscription`](subscription/README.md): Subscribe to data updates.

src/__tests__/graphql-test.js

-18
This file was deleted.

src/execution/__tests__/sync-test.js

+11
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ describe('Execute: synchronously when possible', () => {
9393
});
9494

9595
describe('graphqlSync', () => {
96+
it('report errors raised during schema validation', () => {
97+
const badSchema = new GraphQLSchema({});
98+
const result = graphqlSync({
99+
schema: badSchema,
100+
source: '{ __typename }',
101+
});
102+
expect(result).to.deep.equal({
103+
errors: [{ message: 'Query root type must be provided.' }],
104+
});
105+
});
106+
96107
it('does not return a Promise for syntax errors', () => {
97108
const doc = 'fragment Example on Query { { { syncField }';
98109
const result = graphqlSync({

src/language/__tests__/lexer-test.js

+14-18
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,7 @@ describe('Lexer', () => {
128128
'{ kind: "Name", value: "foo", line: 1, column: 1 }',
129129
);
130130
});
131-
132-
it('skips whitespace and comments', () => {
131+
it('skips whitespace and commas', () => {
133132
expect(
134133
lexOne(`
135134
@@ -144,18 +143,6 @@ describe('Lexer', () => {
144143
value: 'foo',
145144
});
146145

147-
expect(
148-
lexOne(`
149-
#comment
150-
foo#comment
151-
`),
152-
).to.contain({
153-
kind: TokenKind.NAME,
154-
start: 18,
155-
end: 21,
156-
value: 'foo',
157-
});
158-
159146
expect(lexOne(',,,foo,,,')).to.contain({
160147
kind: TokenKind.NAME,
161148
start: 3,
@@ -181,7 +168,6 @@ describe('Lexer', () => {
181168
4 |
182169
`);
183170
});
184-
185171
it('updates line numbers in error for file context', () => {
186172
let caughtError;
187173
try {
@@ -218,6 +204,19 @@ describe('Lexer', () => {
218204
| ^
219205
`);
220206
});
207+
it('lexes comments', () => {
208+
expect(
209+
lexOne(
210+
dedent`#this is a comment
211+
a{}`,
212+
),
213+
).to.contain({
214+
kind: TokenKind.COMMENT,
215+
start: 0,
216+
end: 18,
217+
value: 'this is a comment',
218+
});
219+
});
221220

222221
it('lexes strings', () => {
223222
expect(lexOne('""')).to.contain({
@@ -877,9 +876,6 @@ describe('Lexer', () => {
877876
let endToken;
878877
do {
879878
endToken = lexer.advance();
880-
// Lexer advances over ignored comment tokens to make writing parsers
881-
// easier, but will include them in the linked list result.
882-
expect(endToken.kind).to.not.equal(TokenKind.COMMENT);
883879
} while (endToken.kind !== TokenKind.EOF);
884880

885881
expect(startToken.prev).to.equal(null);

src/language/__tests__/parser-test.js

+61-17
Original file line numberDiff line numberDiff line change
@@ -147,37 +147,81 @@ describe('Parser', () => {
147147
);
148148
});
149149

150-
it('Add comments from type in AST', () => {
151-
const ast = parse(`
150+
it('Add single comments in AST', () => {
151+
const ast = parse(dedent`
152152
#This comment has a \u0A0A multi-byte character.
153153
type alpha{ field(arg: string):string }
154154
`);
155155

156-
expect(ast).to.have.nested.property(
157-
'comments[0].value',
158-
'This comment has a \u0A0A multi-byte character.',
159-
);
160-
expect(ast.comments).to.have.length(1);
156+
expect(toJSONDeep(ast.comments)).to.deep.equal([
157+
{
158+
kind: 'Comment',
159+
loc: { start: 0, end: 43 },
160+
value: 'This comment has a ਊ multi-byte character.',
161+
},
162+
]);
163+
});
164+
165+
it('Ignore comments that comes when we peek for a token in AST', () => {
166+
const ast = parse(dedent`
167+
type #This is a comment that gets ignored
168+
alpha{ field(arg: string):string }
169+
`);
170+
171+
expect(toJSONDeep(ast.comments)).to.deep.equal([
172+
{
173+
kind: 'Comment',
174+
loc: {
175+
end: 41,
176+
start: 5,
177+
},
178+
value: 'This is a comment that gets ignored',
179+
},
180+
]);
181+
});
182+
183+
it('Add empty comments from in AST', () => {
184+
const ast = parse(dedent`
185+
#
186+
type alpha{ field(arg: string):string }
187+
`);
188+
189+
expect(toJSONDeep(ast.comments)).to.deep.equal([
190+
{
191+
kind: 'Comment',
192+
loc: { start: 0, end: 1 },
193+
value: '',
194+
},
195+
]);
161196
});
162197

163198
it('Add multiple comments in AST', () => {
164-
const ast = parse(`
199+
const ast = parse(dedent`
200+
#This is top comment
165201
type alpha{
166202
#This comment is demo comment.
167203
field(arg: string):string
168204
#This is another demo comment having # inside
169205
}
170206
`);
171207

172-
expect(ast).to.have.nested.property(
173-
'comments[0].value',
174-
'This comment is demo comment.',
175-
);
176-
expect(ast).to.have.nested.property(
177-
'comments[1].value',
178-
'This is another demo comment having # inside',
179-
);
180-
expect(ast.comments).to.have.length(2);
208+
expect(toJSONDeep(ast.comments)).to.deep.equal([
209+
{
210+
kind: 'Comment',
211+
loc: { start: 0, end: 20 },
212+
value: 'This is top comment',
213+
},
214+
{
215+
kind: 'Comment',
216+
loc: { start: 35, end: 65 },
217+
value: 'This comment is demo comment.',
218+
},
219+
{
220+
kind: 'Comment',
221+
loc: { start: 97, end: 142 },
222+
value: 'This is another demo comment having # inside',
223+
},
224+
]);
181225
});
182226

183227
it('parses kitchen sink', () => {

src/language/__tests__/visitor-test.js

+64
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { expect } from 'chai';
44
import { describe, it } from 'mocha';
55

66
import invariant from '../../jsutils/invariant';
7+
import dedent from '../../jsutils/dedent';
78

89
import { Kind } from '../kinds';
910
import { parse } from '../parser';
@@ -115,6 +116,69 @@ describe('Visitor', () => {
115116
});
116117
});
117118

119+
it('allows visiting single comments', () => {
120+
const ast = parse(
121+
dedent`
122+
#This is a comment
123+
{ a }
124+
`,
125+
{ noLocation: true },
126+
);
127+
const visited = [];
128+
129+
visit(ast, {
130+
enter: {
131+
Comment(node) {
132+
visited.push(['enter', node.kind]);
133+
},
134+
},
135+
leave: {
136+
Comment(node) {
137+
visited.push(['leave', node.kind]);
138+
},
139+
},
140+
});
141+
142+
expect(visited).to.deep.equal([
143+
['enter', 'Comment'],
144+
['leave', 'Comment'],
145+
]);
146+
});
147+
148+
it('allows visiting multiple comments including comments in definitions', () => {
149+
const ast = parse(
150+
dedent`
151+
#This is a comment
152+
{
153+
#a is a field
154+
a
155+
}
156+
`,
157+
{ noLocation: true },
158+
);
159+
const visited = [];
160+
161+
visit(ast, {
162+
enter: {
163+
Comment(node) {
164+
visited.push(['enter', node.kind]);
165+
},
166+
},
167+
leave: {
168+
Comment(node) {
169+
visited.push(['leave', node.kind]);
170+
},
171+
},
172+
});
173+
174+
expect(visited).to.deep.equal([
175+
['enter', 'Comment'],
176+
['leave', 'Comment'],
177+
['enter', 'Comment'],
178+
['leave', 'Comment'],
179+
]);
180+
});
181+
118182
it('allows visiting only specified nodes', () => {
119183
const ast = parse('{ a }', { noLocation: true });
120184
const visited = [];

src/language/ast.d.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export function isNode(maybeNode: any): maybeNode is ASTNode;
9999
export type ASTNode =
100100
| NameNode
101101
| DocumentNode
102+
| CommentNode
102103
| OperationDefinitionNode
103104
| VariableDefinitionNode
104105
| VariableNode
@@ -147,6 +148,7 @@ export type ASTNode =
147148
export interface ASTKindToNode {
148149
Name: NameNode;
149150
Document: DocumentNode;
151+
Comment: CommentNode;
150152
OperationDefinition: OperationDefinitionNode;
151153
VariableDefinition: VariableDefinitionNode;
152154
Variable: VariableNode;
@@ -204,16 +206,13 @@ export interface DocumentNode {
204206
readonly kind: 'Document';
205207
readonly loc?: Location;
206208
readonly definitions: ReadonlyArray<DefinitionNode>;
207-
readonly comments: ReadonlyArray<CommentNode>;
209+
readonly comments?: ReadonlyArray<CommentNode>;
208210
}
209211

210212
export interface CommentNode {
211213
readonly kind: 'Comment';
212-
readonly start: number;
213-
readonly end: number;
214-
readonly column: number;
215-
readonly line: number;
216-
readonly value: string | void;
214+
readonly loc?: Location;
215+
readonly value: string;
217216
}
218217

219218
export type DefinitionNode =

0 commit comments

Comments
 (0)