[eslint] Don't crash on multiple @babel/parser copies (#13274)

This commit is contained in:
Nicolò Ribaudo 2021-05-06 23:31:19 +02:00 committed by GitHub
parent 68bc4dfd31
commit 1879491af7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 112 additions and 60 deletions

View File

@ -1,4 +1,10 @@
import { tokTypes as tt } from "@babel/core"; import { tokTypes } from "@babel/core";
const tl = (process.env.BABEL_8_BREAKING
? Object.fromEntries
: p => p.reduce((o, [k, v]) => ({ ...o, [k]: v }), {}))(
Object.keys(tokTypes).map(key => [key, tokTypes[key].label]),
);
function convertTemplateType(tokens) { function convertTemplateType(tokens) {
let curlyBrace = null; let curlyBrace = null;
@ -12,7 +18,7 @@ function convertTemplateType(tokens) {
const value = templateTokens.reduce((result, token) => { const value = templateTokens.reduce((result, token) => {
if (token.value) { if (token.value) {
result += token.value; result += token.value;
} else if (token.type !== tt.template) { } else if (token.type.label !== tl.template) {
result += token.type.label; result += token.type.label;
} }
@ -34,8 +40,8 @@ function convertTemplateType(tokens) {
} }
tokens.forEach(token => { tokens.forEach(token => {
switch (token.type) { switch (token.type.label) {
case tt.backQuote: case tl.backQuote:
if (curlyBrace) { if (curlyBrace) {
result.push(curlyBrace); result.push(curlyBrace);
curlyBrace = null; curlyBrace = null;
@ -49,12 +55,12 @@ function convertTemplateType(tokens) {
break; break;
case tt.dollarBraceL: case tl.dollarBraceL:
templateTokens.push(token); templateTokens.push(token);
addTemplateType(); addTemplateType();
break; break;
case tt.braceR: case tl.braceR:
if (curlyBrace) { if (curlyBrace) {
result.push(curlyBrace); result.push(curlyBrace);
} }
@ -62,7 +68,7 @@ function convertTemplateType(tokens) {
curlyBrace = token; curlyBrace = token;
break; break;
case tt.template: case tl.template:
if (curlyBrace) { if (curlyBrace) {
templateTokens.push(curlyBrace); templateTokens.push(curlyBrace);
curlyBrace = null; curlyBrace = null;
@ -71,7 +77,7 @@ function convertTemplateType(tokens) {
templateTokens.push(token); templateTokens.push(token);
break; break;
case tt.eof: case tl.eof:
if (curlyBrace) { if (curlyBrace) {
result.push(curlyBrace); result.push(curlyBrace);
} }
@ -92,63 +98,64 @@ function convertTemplateType(tokens) {
} }
function convertToken(token, source) { function convertToken(token, source) {
const type = token.type; const { type } = token;
const { label } = type;
token.range = [token.start, token.end]; token.range = [token.start, token.end];
if (type === tt.name) { if (label === tl.name) {
token.type = "Identifier"; token.type = "Identifier";
} else if ( } else if (
type === tt.semi || label === tl.semi ||
type === tt.comma || label === tl.comma ||
type === tt.parenL || label === tl.parenL ||
type === tt.parenR || label === tl.parenR ||
type === tt.braceL || label === tl.braceL ||
type === tt.braceR || label === tl.braceR ||
type === tt.slash || label === tl.slash ||
type === tt.dot || label === tl.dot ||
type === tt.bracketL || label === tl.bracketL ||
type === tt.bracketR || label === tl.bracketR ||
type === tt.ellipsis || label === tl.ellipsis ||
type === tt.arrow || label === tl.arrow ||
type === tt.pipeline || label === tl.pipeline ||
type === tt.star || label === tl.star ||
type === tt.incDec || label === tl.incDec ||
type === tt.colon || label === tl.colon ||
type === tt.question || label === tl.question ||
type === tt.template || label === tl.template ||
type === tt.backQuote || label === tl.backQuote ||
type === tt.dollarBraceL || label === tl.dollarBraceL ||
type === tt.at || label === tl.at ||
type === tt.logicalOR || label === tl.logicalOR ||
type === tt.logicalAND || label === tl.logicalAND ||
type === tt.nullishCoalescing || label === tl.nullishCoalescing ||
type === tt.bitwiseOR || label === tl.bitwiseOR ||
type === tt.bitwiseXOR || label === tl.bitwiseXOR ||
type === tt.bitwiseAND || label === tl.bitwiseAND ||
type === tt.equality || label === tl.equality ||
type === tt.relational || label === tl.relational ||
type === tt.bitShift || label === tl.bitShift ||
type === tt.plusMin || label === tl.plusMin ||
type === tt.modulo || label === tl.modulo ||
type === tt.exponent || label === tl.exponent ||
type === tt.bang || label === tl.bang ||
type === tt.tilde || label === tl.tilde ||
type === tt.doubleColon || label === tl.doubleColon ||
type === tt.hash || label === tl.hash ||
type === tt.questionDot || label === tl.questionDot ||
type.isAssign type.isAssign
) { ) {
token.type = "Punctuator"; token.type = "Punctuator";
if (!token.value) token.value = type.label; token.value ??= label;
} else if (type === tt.jsxTagStart) { } else if (label === tl.jsxTagStart) {
token.type = "Punctuator"; token.type = "Punctuator";
token.value = "<"; token.value = "<";
} else if (type === tt.jsxTagEnd) { } else if (label === tl.jsxTagEnd) {
token.type = "Punctuator"; token.type = "Punctuator";
token.value = ">"; token.value = ">";
} else if (type === tt.jsxName) { } else if (label === tl.jsxName) {
token.type = "JSXIdentifier"; token.type = "JSXIdentifier";
} else if (type === tt.jsxText) { } else if (label === tl.jsxText) {
token.type = "JSXText"; token.type = "JSXText";
} else if (type.keyword === "null") { } else if (type.keyword === "null") {
token.type = "Null"; token.type = "Null";
@ -156,13 +163,13 @@ function convertToken(token, source) {
token.type = "Boolean"; token.type = "Boolean";
} else if (type.keyword) { } else if (type.keyword) {
token.type = "Keyword"; token.type = "Keyword";
} else if (type === tt.num) { } else if (label === tl.num) {
token.type = "Numeric"; token.type = "Numeric";
token.value = source.slice(token.start, token.end); token.value = source.slice(token.start, token.end);
} else if (type === tt.string) { } else if (label === tl.string) {
token.type = "String"; token.type = "String";
token.value = source.slice(token.start, token.end); token.value = source.slice(token.start, token.end);
} else if (type === tt.regexp) { } else if (label === tl.regexp) {
token.type = "RegularExpression"; token.type = "RegularExpression";
const value = token.value; const value = token.value;
token.regex = { token.regex = {
@ -170,12 +177,13 @@ function convertToken(token, source) {
flags: value.flags, flags: value.flags,
}; };
token.value = `/${value.pattern}/${value.flags}`; token.value = `/${value.pattern}/${value.flags}`;
} else if (type === tt.bigint) { } else if (label === tl.bigint) {
token.type = "Numeric"; token.type = "Numeric";
token.value = `${token.value}n`; token.value = `${token.value}n`;
} else if (type === tt.privateName) { } else if (label === tl.privateName) {
token.type = "PrivateIdentifier"; token.type = "PrivateIdentifier";
} }
if (typeof token.type !== "string") { if (typeof token.type !== "string") {
// Acorn does not have rightAssociative // Acorn does not have rightAssociative
delete token.type.rightAssociative; delete token.type.rightAssociative;

View File

@ -8,6 +8,7 @@
"@babel/eslint-parser": "workspace:^7.12.1", "@babel/eslint-parser": "workspace:^7.12.1",
"dedent": "^0.7.0", "dedent": "^0.7.0",
"eslint": "^7.5.0", "eslint": "^7.5.0",
"eslint-plugin-import": "^2.22.0" "eslint-plugin-import": "^2.22.0",
"npm-babel-parser": "npm:@babel/parser@^7.14.0"
} }
} }

View File

@ -0,0 +1,13 @@
module.exports = {
root: true,
parser: "@babel/eslint-parser",
parserOptions: {
babelOptions: {
configFile: __dirname + "/babel.config.js",
sourceType: "module",
},
},
rules: {
"template-curly-spacing": "error",
},
};

View File

@ -0,0 +1,5 @@
import { func1 } from "./iodex.js";
export function five() {
return { five: `number(${5})` };
}

View File

@ -0,0 +1,7 @@
module.exports = {
plugins: [
() => ({
parserOverride: require("npm-babel-parser").parse,
}),
],
};

View File

@ -0,0 +1,17 @@
import eslint from "eslint";
import path from "path";
import { fileURLToPath } from "url";
describe("https://github.com/babel/babel/issues/12985", () => {
it("works with different copies of @babel/parser", () => {
const engine = new eslint.CLIEngine({ ignore: false });
expect(() =>
engine.executeOnFiles([
path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
`../fixtures/duplicated-babel-parser/a.js`,
),
]),
).not.toThrow();
});
});

View File

@ -5,7 +5,7 @@ __metadata:
version: 4 version: 4
cacheKey: 7 cacheKey: 7
"@babel-baseline/parser@npm:@babel/parser@^7.14.0, @babel/parser@npm:^7.0.0, @babel/parser@npm:^7.12.13, @babel/parser@npm:^7.12.7, @babel/parser@npm:^7.14.0": "@babel-baseline/parser@npm:@babel/parser@^7.14.0, @babel/parser@npm:^7.0.0, @babel/parser@npm:^7.12.13, @babel/parser@npm:^7.12.7, @babel/parser@npm:^7.14.0, npm-babel-parser@npm:@babel/parser@^7.14.0":
version: 7.14.0 version: 7.14.0
resolution: "@babel/parser@npm:7.14.0" resolution: "@babel/parser@npm:7.14.0"
bin: bin:
@ -314,6 +314,7 @@ __metadata:
dedent: ^0.7.0 dedent: ^0.7.0
eslint: ^7.5.0 eslint: ^7.5.0
eslint-plugin-import: ^2.22.0 eslint-plugin-import: ^2.22.0
npm-babel-parser: "npm:@babel/parser@^7.14.0"
languageName: unknown languageName: unknown
linkType: soft linkType: soft