prettier/src/language-graphql/parser-graphql.js

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;
}
}
}
};