@babel-core: parse should parse only (#10914)

* @babel/core: parse methods should parse only

* Update Flow types
This commit is contained in:
Kai Cataldo 2019-12-24 12:28:57 -05:00 committed by Nicolò Ribaudo
parent 875e9619b7
commit ee5b79d75d
4 changed files with 80 additions and 81 deletions

View File

@ -1,14 +1,11 @@
// @flow // @flow
import loadConfig, { type InputOptions } from "./config"; import loadConfig, { type InputOptions } from "./config";
import normalizeFile from "./transformation/normalize-file"; import parser from "./parser";
import type { ParseResult } from "./parser";
import normalizeOptions from "./transformation/normalize-opts"; import normalizeOptions from "./transformation/normalize-opts";
type AstRoot = BabelNodeFile | BabelNodeProgram; type FileParseCallback = {
export type ParseResult = AstRoot;
export type FileParseCallback = {
(Error, null): any, (Error, null): any,
(null, ParseResult | null): any, (null, ParseResult | null): any,
}; };
@ -49,7 +46,7 @@ export const parse: Parse = (function parse(code, opts, callback) {
const cfg = loadConfig(opts); const cfg = loadConfig(opts);
if (cfg === null) return cb(null, null); if (cfg === null) return cb(null, null);
ast = normalizeFile(cfg.passes, normalizeOptions(cfg), code).ast; ast = parser(cfg.passes, normalizeOptions(cfg), code);
} catch (err) { } catch (err) {
return cb(err); return cb(err);
} }
@ -68,7 +65,7 @@ export function parseSync(
return null; return null;
} }
return normalizeFile(config.passes, normalizeOptions(config), code).ast; return parser(config.passes, normalizeOptions(config), code);
} }
export function parseAsync( export function parseAsync(

View File

@ -0,0 +1,74 @@
import { parse } from "@babel/parser";
import { codeFrameColumns } from "@babel/code-frame";
import generateMissingPluginMessage from "./util/missing-plugin-helper";
type AstRoot = BabelNodeFile | BabelNodeProgram;
export type ParseResult = AstRoot;
export default function parser(
pluginPasses: PluginPasses,
{ parserOpts, highlightCode = true, filename = "unknown" }: Object,
code: string,
): ParseResult {
try {
const results = [];
for (const plugins of pluginPasses) {
for (const plugin of plugins) {
const { parserOverride } = plugin;
if (parserOverride) {
const ast = parserOverride(code, parserOpts, parse);
if (ast !== undefined) results.push(ast);
}
}
}
if (results.length === 0) {
return parse(code, parserOpts);
} else if (results.length === 1) {
if (typeof results[0].then === "function") {
throw new Error(
`You appear to be using an async parser plugin, ` +
`which your current version of Babel does not support. ` +
`If you're using a published plugin, you may need to upgrade ` +
`your @babel/core version.`,
);
}
return results[0];
}
throw new Error("More than one plugin attempted to override parsing.");
} catch (err) {
if (err.code === "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED") {
err.message +=
"\nConsider renaming the file to '.mjs', or setting sourceType:module " +
"or sourceType:unambiguous in your Babel config for this file.";
// err.code will be changed to BABEL_PARSE_ERROR later.
}
const { loc, missingPlugin } = err;
if (loc) {
const codeFrame = codeFrameColumns(
code,
{
start: {
line: loc.line,
column: loc.column + 1,
},
},
{
highlightCode,
},
);
if (missingPlugin) {
err.message =
`${filename}: ` +
generateMissingPluginMessage(missingPlugin[0], loc, codeFrame);
} else {
err.message = `${filename}: ${err.message}\n\n` + codeFrame;
}
err.code = "BABEL_PARSE_ERROR";
}
throw err;
}
}

View File

@ -7,10 +7,8 @@ import cloneDeep from "lodash/cloneDeep";
import * as t from "@babel/types"; import * as t from "@babel/types";
import type { PluginPasses } from "../config"; import type { PluginPasses } from "../config";
import convertSourceMap, { typeof Converter } from "convert-source-map"; import convertSourceMap, { typeof Converter } from "convert-source-map";
import { parse } from "@babel/parser";
import { codeFrameColumns } from "@babel/code-frame";
import File from "./file/file"; import File from "./file/file";
import generateMissingPluginMessage from "./util/missing-plugin-helper"; import parser from "../parser";
const debug = buildDebug("babel:transform:file"); const debug = buildDebug("babel:transform:file");
const LARGE_INPUT_SOURCEMAP_THRESHOLD = 1_000_000; const LARGE_INPUT_SOURCEMAP_THRESHOLD = 1_000_000;
@ -37,9 +35,6 @@ export default function normalizeFile(
} }
ast = cloneDeep(ast); ast = cloneDeep(ast);
} else { } else {
// The parser's AST types aren't fully compatible with the types generated
// by the logic in babel-types.
// $FlowFixMe
ast = parser(pluginPasses, options, code); ast = parser(pluginPasses, options, code);
} }
@ -94,73 +89,6 @@ export default function normalizeFile(
}); });
} }
function parser(
pluginPasses: PluginPasses,
{ parserOpts, highlightCode = true, filename = "unknown" }: Object,
code: string,
) {
try {
const results = [];
for (const plugins of pluginPasses) {
for (const plugin of plugins) {
const { parserOverride } = plugin;
if (parserOverride) {
const ast = parserOverride(code, parserOpts, parse);
if (ast !== undefined) results.push(ast);
}
}
}
if (results.length === 0) {
return parse(code, parserOpts);
} else if (results.length === 1) {
if (typeof results[0].then === "function") {
throw new Error(
`You appear to be using an async parser plugin, ` +
`which your current version of Babel does not support. ` +
`If you're using a published plugin, you may need to upgrade ` +
`your @babel/core version.`,
);
}
return results[0];
}
throw new Error("More than one plugin attempted to override parsing.");
} catch (err) {
if (err.code === "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED") {
err.message +=
"\nConsider renaming the file to '.mjs', or setting sourceType:module " +
"or sourceType:unambiguous in your Babel config for this file.";
// err.code will be changed to BABEL_PARSE_ERROR later.
}
const { loc, missingPlugin } = err;
if (loc) {
const codeFrame = codeFrameColumns(
code,
{
start: {
line: loc.line,
column: loc.column + 1,
},
},
{
highlightCode,
},
);
if (missingPlugin) {
err.message =
`${filename}: ` +
generateMissingPluginMessage(missingPlugin[0], loc, codeFrame);
} else {
err.message = `${filename}: ${err.message}\n\n` + codeFrame;
}
err.code = "BABEL_PARSE_ERROR";
}
throw err;
}
}
// These regexps are copied from the convert-source-map package, // These regexps are copied from the convert-source-map package,
// but without // or /* at the beginning of the comment. // but without // or /* at the beginning of the comment.