95 lines
2.2 KiB
JavaScript
95 lines
2.2 KiB
JavaScript
"use strict";
|
|
|
|
const createError = require("../common/parser-create-error");
|
|
const { hasPragma } = require("./pragma");
|
|
|
|
function parseComments(ast) {
|
|
const comments = [];
|
|
const startToken = ast.loc.startToken;
|
|
let next = startToken.next;
|
|
while (next.kind !== "<EOF>") {
|
|
if (next.kind === "Comment") {
|
|
Object.assign(next, {
|
|
// The Comment token's column starts _after_ the `#`,
|
|
// but we need to make sure the node captures the `#`
|
|
column: next.column - 1
|
|
});
|
|
comments.push(next);
|
|
}
|
|
next = next.next;
|
|
}
|
|
|
|
return comments;
|
|
}
|
|
|
|
function removeTokens(node) {
|
|
if (node && typeof node === "object") {
|
|
delete node.startToken;
|
|
delete node.endToken;
|
|
delete node.prev;
|
|
delete node.next;
|
|
for (const key in node) {
|
|
removeTokens(node[key]);
|
|
}
|
|
}
|
|
return node;
|
|
}
|
|
|
|
function fallbackParser(parse, source) {
|
|
const parserOptions = {
|
|
allowLegacySDLImplementsInterfaces: false,
|
|
experimentalFragmentVariables: true
|
|
};
|
|
try {
|
|
return parse(source, parserOptions);
|
|
} catch (_) {
|
|
parserOptions.allowLegacySDLImplementsInterfaces = true;
|
|
return parse(source, parserOptions);
|
|
}
|
|
}
|
|
|
|
function parse(text /*, parsers, opts*/) {
|
|
// Inline the require to avoid loading all the JS if we don't use it
|
|
const parser = require("graphql/language");
|
|
try {
|
|
const ast = fallbackParser(parser.parse, text);
|
|
ast.comments = parseComments(ast);
|
|
removeTokens(ast);
|
|
return ast;
|
|
} catch (error) {
|
|
const GraphQLError = require("graphql/error").GraphQLError;
|
|
if (error instanceof GraphQLError) {
|
|
throw createError(error.message, {
|
|
start: {
|
|
line: error.locations[0].line,
|
|
column: error.locations[0].column
|
|
}
|
|
});
|
|
} else {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
parsers: {
|
|
graphql: {
|
|
parse,
|
|
astFormat: "graphql",
|
|
hasPragma,
|
|
locStart(node) {
|
|
if (typeof node.start === "number") {
|
|
return node.start;
|
|
}
|
|
return node.loc && node.loc.start;
|
|
},
|
|
locEnd(node) {
|
|
if (typeof node.end === "number") {
|
|
return node.end;
|
|
}
|
|
return node.loc && node.loc.end;
|
|
}
|
|
}
|
|
}
|
|
};
|