* Add error recovery support to @babel/parser * Update @babel/parser tests to always recover from errors * Update this.raise usage in @babel/parser: - expression.js - lval.js - statement.js - estree.js - flow.js - jsx/index.js - tokenizer/index.js * Update @babel/parser fixtures with recovered errors * Fix tests out of @babel/parser * Do not use try/catch for control flow * Update invalid fixtures * Do not report invalid lhs in toAssignable * Do not validate function id multiple times * Dedupe reserved await errors * Remove duplicate errors about strict reserved bindings * Remove duplicated error about yield/await inside params * Don't error twice for methods in object patterns * Don't report invalid super() twice * Remove dup error about reserved param for expr arrows * Remove double escapes in migrated tests * Dedupe errors about invalid escapes in identifiers * Remove duplicated error about decorated constructor * Remove duplicated error about spread in flow class * Don't throw for invalid super usage * Don't fail for object decorators with stage 2 * Fix flow inexact type errors * Fix flow * Fix errors about escapes in keywords (ref: #10455) * Update after rebase * Fix todo * Remove duplicated error when using += for defaults * Remove unnecessary throw * Nit: use ??
57 lines
1.7 KiB
JavaScript
57 lines
1.7 KiB
JavaScript
// @flow
|
|
|
|
import type { Options } from "../options";
|
|
import type { File, JSXOpeningElement } from "../types";
|
|
import type { PluginList } from "../plugin-utils";
|
|
import { getOptions } from "../options";
|
|
import StatementParser from "./statement";
|
|
import { SCOPE_PROGRAM } from "../util/scopeflags";
|
|
import ScopeHandler from "../util/scope";
|
|
|
|
export type PluginsMap = Map<string, { [string]: any }>;
|
|
|
|
export default class Parser extends StatementParser {
|
|
// Forward-declaration so typescript plugin can override jsx plugin
|
|
+jsxParseOpeningElementAfterName: (
|
|
node: JSXOpeningElement,
|
|
) => JSXOpeningElement;
|
|
|
|
constructor(options: ?Options, input: string) {
|
|
options = getOptions(options);
|
|
super(options, input);
|
|
|
|
const ScopeHandler = this.getScopeHandler();
|
|
|
|
this.options = options;
|
|
this.inModule = this.options.sourceType === "module";
|
|
this.scope = new ScopeHandler(this.raise.bind(this), this.inModule);
|
|
this.plugins = pluginsMap(this.options.plugins);
|
|
this.filename = options.sourceFilename;
|
|
}
|
|
|
|
// This can be overwritten, for example, by the TypeScript plugin.
|
|
getScopeHandler(): Class<ScopeHandler<*>> {
|
|
return ScopeHandler;
|
|
}
|
|
|
|
parse(): File {
|
|
this.scope.enter(SCOPE_PROGRAM);
|
|
const file = this.startNode();
|
|
const program = this.startNode();
|
|
this.nextToken();
|
|
file.errors = null;
|
|
this.parseTopLevel(file, program);
|
|
file.errors = this.state.errors;
|
|
return file;
|
|
}
|
|
}
|
|
|
|
function pluginsMap(plugins: PluginList): PluginsMap {
|
|
const pluginMap: PluginsMap = new Map();
|
|
for (const plugin of plugins) {
|
|
const [name, options] = Array.isArray(plugin) ? plugin : [plugin, {}];
|
|
if (!pluginMap.has(name)) pluginMap.set(name, options || {});
|
|
}
|
|
return pluginMap;
|
|
}
|