@babel-core: parse should parse only (#10914)
* @babel/core: parse methods should parse only * Update Flow types
This commit is contained in:
committed by
Nicolò Ribaudo
parent
875e9619b7
commit
ee5b79d75d
74
packages/babel-core/src/parser/index.js
Normal file
74
packages/babel-core/src/parser/index.js
Normal 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;
|
||||
}
|
||||
}
|
||||
251
packages/babel-core/src/parser/util/missing-plugin-helper.js
Normal file
251
packages/babel-core/src/parser/util/missing-plugin-helper.js
Normal file
@@ -0,0 +1,251 @@
|
||||
// @flow
|
||||
|
||||
const pluginNameMap = {
|
||||
classProperties: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-class-properties",
|
||||
url: "https://git.io/vb4yQ",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-class-properties",
|
||||
url: "https://git.io/vb4SL",
|
||||
},
|
||||
},
|
||||
decorators: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-decorators",
|
||||
url: "https://git.io/vb4y9",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-decorators",
|
||||
url: "https://git.io/vb4ST",
|
||||
},
|
||||
},
|
||||
doExpressions: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-do-expressions",
|
||||
url: "https://git.io/vb4yh",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-do-expressions",
|
||||
url: "https://git.io/vb4S3",
|
||||
},
|
||||
},
|
||||
dynamicImport: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-dynamic-import",
|
||||
url: "https://git.io/vb4Sv",
|
||||
},
|
||||
},
|
||||
exportDefaultFrom: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-export-default-from",
|
||||
url: "https://git.io/vb4SO",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-export-default-from",
|
||||
url: "https://git.io/vb4yH",
|
||||
},
|
||||
},
|
||||
exportNamespaceFrom: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-export-namespace-from",
|
||||
url: "https://git.io/vb4Sf",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-export-namespace-from",
|
||||
url: "https://git.io/vb4SG",
|
||||
},
|
||||
},
|
||||
flow: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-flow",
|
||||
url: "https://git.io/vb4yb",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-transform-flow-strip-types",
|
||||
url: "https://git.io/vb49g",
|
||||
},
|
||||
},
|
||||
functionBind: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-function-bind",
|
||||
url: "https://git.io/vb4y7",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-function-bind",
|
||||
url: "https://git.io/vb4St",
|
||||
},
|
||||
},
|
||||
functionSent: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-function-sent",
|
||||
url: "https://git.io/vb4yN",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-function-sent",
|
||||
url: "https://git.io/vb4SZ",
|
||||
},
|
||||
},
|
||||
importMeta: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-import-meta",
|
||||
url: "https://git.io/vbKK6",
|
||||
},
|
||||
},
|
||||
jsx: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-jsx",
|
||||
url: "https://git.io/vb4yA",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-transform-react-jsx",
|
||||
url: "https://git.io/vb4yd",
|
||||
},
|
||||
},
|
||||
logicalAssignment: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-logical-assignment-operators",
|
||||
url: "https://git.io/vAlBp",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-logical-assignment-operators",
|
||||
url: "https://git.io/vAlRe",
|
||||
},
|
||||
},
|
||||
nullishCoalescingOperator: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-nullish-coalescing-operator",
|
||||
url: "https://git.io/vb4yx",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
url: "https://git.io/vb4Se",
|
||||
},
|
||||
},
|
||||
numericSeparator: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-numeric-separator",
|
||||
url: "https://git.io/vb4Sq",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-numeric-separator",
|
||||
url: "https://git.io/vb4yS",
|
||||
},
|
||||
},
|
||||
optionalChaining: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-optional-chaining",
|
||||
url: "https://git.io/vb4Sc",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-optional-chaining",
|
||||
url: "https://git.io/vb4Sk",
|
||||
},
|
||||
},
|
||||
pipelineOperator: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-pipeline-operator",
|
||||
url: "https://git.io/vb4yj",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-pipeline-operator",
|
||||
url: "https://git.io/vb4SU",
|
||||
},
|
||||
},
|
||||
throwExpressions: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-throw-expressions",
|
||||
url: "https://git.io/vb4SJ",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-throw-expressions",
|
||||
url: "https://git.io/vb4yF",
|
||||
},
|
||||
},
|
||||
typescript: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-typescript",
|
||||
url: "https://git.io/vb4SC",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-transform-typescript",
|
||||
url: "https://git.io/vb4Sm",
|
||||
},
|
||||
},
|
||||
|
||||
// TODO: This plugins are now supported by default by @babel/parser: they can
|
||||
// be removed from this list. Although removing them isn't a breaking change,
|
||||
// it's better to keep a nice error message for users using older versions of
|
||||
// the parser. They can be removed in Babel 8.
|
||||
asyncGenerators: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-async-generators",
|
||||
url: "https://git.io/vb4SY",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-async-generator-functions",
|
||||
url: "https://git.io/vb4yp",
|
||||
},
|
||||
},
|
||||
objectRestSpread: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-object-rest-spread",
|
||||
url: "https://git.io/vb4y5",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-object-rest-spread",
|
||||
url: "https://git.io/vb4Ss",
|
||||
},
|
||||
},
|
||||
optionalCatchBinding: {
|
||||
syntax: {
|
||||
name: "@babel/plugin-syntax-optional-catch-binding",
|
||||
url: "https://git.io/vb4Sn",
|
||||
},
|
||||
transform: {
|
||||
name: "@babel/plugin-proposal-optional-catch-binding",
|
||||
url: "https://git.io/vb4SI",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const getNameURLCombination = ({ name, url }) => `${name} (${url})`;
|
||||
|
||||
/*
|
||||
Returns a string of the format:
|
||||
Support for the experimental syntax [@babel/parser plugin name] isn't currently enabled ([loc]):
|
||||
|
||||
[code frame]
|
||||
|
||||
Add [npm package name] ([url]) to the 'plugins' section of your Babel config
|
||||
to enable [parsing|transformation].
|
||||
*/
|
||||
export default function generateMissingPluginMessage(
|
||||
missingPluginName: string,
|
||||
loc: { line: number, column: number },
|
||||
codeFrame: string,
|
||||
): string {
|
||||
let helpMessage =
|
||||
`Support for the experimental syntax '${missingPluginName}' isn't currently enabled ` +
|
||||
`(${loc.line}:${loc.column + 1}):\n\n` +
|
||||
codeFrame;
|
||||
const pluginInfo = pluginNameMap[missingPluginName];
|
||||
if (pluginInfo) {
|
||||
const { syntax: syntaxPlugin, transform: transformPlugin } = pluginInfo;
|
||||
if (syntaxPlugin) {
|
||||
if (transformPlugin) {
|
||||
const transformPluginInfo = getNameURLCombination(transformPlugin);
|
||||
helpMessage +=
|
||||
`\n\nAdd ${transformPluginInfo} to the 'plugins' section of your Babel config ` +
|
||||
`to enable transformation.`;
|
||||
} else {
|
||||
const syntaxPluginInfo = getNameURLCombination(syntaxPlugin);
|
||||
helpMessage +=
|
||||
`\n\nAdd ${syntaxPluginInfo} to the 'plugins' section of your Babel config ` +
|
||||
`to enable parsing.`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return helpMessage;
|
||||
}
|
||||
Reference in New Issue
Block a user