Add ESLint 8 support to @babel/eslint-parser (#13782)
* Add ESLint 8 support to `@babel/eslint-parser` * Only read eslint version dynamically during dev * Fix tests * Update ESLint * Use ESLint 8 stable * Review * Check * Fix babel config
This commit is contained in:
parent
ad59a2c618
commit
381277ae35
@ -58,6 +58,7 @@ module.exports = function (api) {
|
|||||||
let ignoreLib = true;
|
let ignoreLib = true;
|
||||||
let includeRegeneratorRuntime = false;
|
let includeRegeneratorRuntime = false;
|
||||||
let needsPolyfillsForOldNode = false;
|
let needsPolyfillsForOldNode = false;
|
||||||
|
let dynamicESLintVersionCheck = false;
|
||||||
|
|
||||||
let transformRuntimeOptions;
|
let transformRuntimeOptions;
|
||||||
|
|
||||||
@ -99,6 +100,8 @@ module.exports = function (api) {
|
|||||||
needsPolyfillsForOldNode = true;
|
needsPolyfillsForOldNode = true;
|
||||||
break;
|
break;
|
||||||
case "test-legacy": // In test-legacy environment, we build babel on latest node but test on minimum supported legacy versions
|
case "test-legacy": // In test-legacy environment, we build babel on latest node but test on minimum supported legacy versions
|
||||||
|
dynamicESLintVersionCheck = true;
|
||||||
|
// fall through
|
||||||
case "production":
|
case "production":
|
||||||
// Config during builds before publish.
|
// Config during builds before publish.
|
||||||
targets = { node: nodeVersion };
|
targets = { node: nodeVersion };
|
||||||
@ -107,10 +110,12 @@ module.exports = function (api) {
|
|||||||
case "test":
|
case "test":
|
||||||
targets = { node: "current" };
|
targets = { node: "current" };
|
||||||
needsPolyfillsForOldNode = true;
|
needsPolyfillsForOldNode = true;
|
||||||
|
dynamicESLintVersionCheck = true;
|
||||||
break;
|
break;
|
||||||
case "development":
|
case "development":
|
||||||
envOpts.debug = true;
|
envOpts.debug = true;
|
||||||
targets = { node: "current" };
|
targets = { node: "current" };
|
||||||
|
dynamicESLintVersionCheck = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,6 +223,10 @@ module.exports = function (api) {
|
|||||||
exclude: /regenerator-runtime/,
|
exclude: /regenerator-runtime/,
|
||||||
plugins: [["@babel/transform-runtime", transformRuntimeOptions]],
|
plugins: [["@babel/transform-runtime", transformRuntimeOptions]],
|
||||||
},
|
},
|
||||||
|
dynamicESLintVersionCheck && {
|
||||||
|
test: ["./eslint/*/src"].map(normalize),
|
||||||
|
plugins: [pluginDynamicESLintVersionCheck],
|
||||||
|
},
|
||||||
].filter(Boolean),
|
].filter(Boolean),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -654,3 +663,30 @@ function pluginBabelParserTokenType({
|
|||||||
tokenTypesMapping.set(tokenTypesDefinition[i].key.name, i);
|
tokenTypesMapping.set(tokenTypesDefinition[i].key.name, i);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// Transforms
|
||||||
|
// ESLINT_VERSION
|
||||||
|
// to
|
||||||
|
// process.env.ESLINT_VERSION_FOR_BABEL
|
||||||
|
// ? parseInt(process.env.ESLINT_VERSION_FOR_BABEL, 10)
|
||||||
|
// : ESLINT_VERSION
|
||||||
|
function pluginDynamicESLintVersionCheck({ template }) {
|
||||||
|
const transformed = new WeakSet();
|
||||||
|
|
||||||
|
return {
|
||||||
|
visitor: {
|
||||||
|
ReferencedIdentifier(path) {
|
||||||
|
if (path.node.name !== "ESLINT_VERSION") return;
|
||||||
|
|
||||||
|
if (transformed.has(path.node)) return;
|
||||||
|
transformed.add(path.node);
|
||||||
|
|
||||||
|
path.replaceWith(template.expression.ast`
|
||||||
|
process.env.ESLINT_VERSION_FOR_BABEL
|
||||||
|
? parseInt(process.env.ESLINT_VERSION_FOR_BABEL, 10)
|
||||||
|
: ${path.node}
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babel/core": ">=7.11.0",
|
"@babel/core": ">=7.11.0",
|
||||||
"eslint": ">=7.5.0"
|
"eslint": "^7.5.0 || ^8.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eslint-scope": "^5.1.1",
|
"eslint-scope": "^5.1.1",
|
||||||
@ -38,6 +38,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "workspace:^",
|
"@babel/core": "workspace:^",
|
||||||
"dedent": "^0.7.0",
|
"dedent": "^0.7.0",
|
||||||
"eslint": "^7.27.0"
|
"eslint": "^7.27.0",
|
||||||
|
"eslint-8": "npm:eslint@^8.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
const ESLINT_VERSION = require("../utils/eslint-version.cjs");
|
||||||
|
|
||||||
function* it(children) {
|
function* it(children) {
|
||||||
if (Array.isArray(children)) yield* children;
|
if (Array.isArray(children)) yield* children;
|
||||||
else yield children;
|
else yield children;
|
||||||
@ -40,7 +42,7 @@ const convertNodesVisitor = {
|
|||||||
delete node.extra;
|
delete node.extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node?.loc.identifierName) {
|
if (node.loc.identifierName) {
|
||||||
delete node.loc.identifierName;
|
delete node.loc.identifierName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +91,15 @@ const convertNodesVisitor = {
|
|||||||
} else {
|
} else {
|
||||||
q.loc.end.column += 2;
|
q.loc.end.column += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ESLINT_VERSION >= 8) {
|
||||||
|
q.start -= 1;
|
||||||
|
if (q.tail) {
|
||||||
|
q.end += 1;
|
||||||
|
} else {
|
||||||
|
q.end += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -117,6 +128,10 @@ function convertProgramNode(ast) {
|
|||||||
ast.range[1] = lastToken.end;
|
ast.range[1] = lastToken.end;
|
||||||
ast.loc.end.line = lastToken.loc.end.line;
|
ast.loc.end.line = lastToken.loc.end.line;
|
||||||
ast.loc.end.column = lastToken.loc.end.column;
|
ast.loc.end.column = lastToken.loc.end.column;
|
||||||
|
|
||||||
|
if (ESLINT_VERSION >= 8) {
|
||||||
|
ast.end = lastToken.end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -129,6 +144,10 @@ function convertProgramNode(ast) {
|
|||||||
if (ast.body && ast.body.length > 0) {
|
if (ast.body && ast.body.length > 0) {
|
||||||
ast.loc.start.line = ast.body[0].loc.start.line;
|
ast.loc.start.line = ast.body[0].loc.start.line;
|
||||||
ast.range[0] = ast.body[0].start;
|
ast.range[0] = ast.body[0].start;
|
||||||
|
|
||||||
|
if (ESLINT_VERSION >= 8) {
|
||||||
|
ast.start = ast.body[0].start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
const ESLINT_VERSION = require("../utils/eslint-version.cjs");
|
||||||
|
|
||||||
function convertTemplateType(tokens, tl) {
|
function convertTemplateType(tokens, tl) {
|
||||||
let curlyBrace = null;
|
let curlyBrace = null;
|
||||||
let templateTokens = [];
|
let templateTokens = [];
|
||||||
@ -190,12 +192,45 @@ function convertToken(token, source, tl) {
|
|||||||
// Acorn does not have rightAssociative
|
// Acorn does not have rightAssociative
|
||||||
delete token.type.rightAssociative;
|
delete token.type.rightAssociative;
|
||||||
}
|
}
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function convertTokens(tokens, code, tl) {
|
module.exports = function convertTokens(tokens, code, tl) {
|
||||||
return convertTemplateType(tokens, tl)
|
const result = [];
|
||||||
.filter(t => t.type !== "CommentLine" && t.type !== "CommentBlock")
|
|
||||||
.map(t => convertToken(t, code, tl));
|
const withoutComments = convertTemplateType(tokens, tl).filter(
|
||||||
|
t => t.type !== "CommentLine" && t.type !== "CommentBlock",
|
||||||
|
);
|
||||||
|
for (let i = 0, { length } = withoutComments; i < length; i++) {
|
||||||
|
const token = withoutComments[i];
|
||||||
|
|
||||||
|
if (!process.env.BABEL_8_BREAKING) {
|
||||||
|
// Babel 8 already produces a single token
|
||||||
|
|
||||||
|
if (
|
||||||
|
ESLINT_VERSION >= 8 &&
|
||||||
|
i + 1 < length &&
|
||||||
|
token.type.label === tl.hash
|
||||||
|
) {
|
||||||
|
const nextToken = withoutComments[i + 1];
|
||||||
|
|
||||||
|
// We must disambiguate private identifier from the hack pipes topic token
|
||||||
|
if (nextToken.type.label === tl.name && token.end === nextToken.start) {
|
||||||
|
i++;
|
||||||
|
|
||||||
|
nextToken.type = "PrivateIdentifier";
|
||||||
|
nextToken.start -= 1;
|
||||||
|
nextToken.loc.start.column -= 1;
|
||||||
|
nextToken.range = [nextToken.start, nextToken.end];
|
||||||
|
|
||||||
|
result.push(nextToken);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
convertToken(token, code, tl);
|
||||||
|
result.push(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|||||||
1
eslint/babel-eslint-parser/src/utils/eslint-version.cjs
Normal file
1
eslint/babel-eslint-parser/src/utils/eslint-version.cjs
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = parseInt(require("eslint/package.json").version, 10);
|
||||||
@ -1,4 +1,5 @@
|
|||||||
const babel = require("./babel-core.cjs");
|
const babel = require("./babel-core.cjs");
|
||||||
|
const ESLINT_VERSION = require("../utils/eslint-version.cjs");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge user supplied estree plugin options to default estree plugin options
|
* Merge user supplied estree plugin options to default estree plugin options
|
||||||
@ -8,8 +9,7 @@ const babel = require("./babel-core.cjs");
|
|||||||
*/
|
*/
|
||||||
function getParserPlugins(babelOptions) {
|
function getParserPlugins(babelOptions) {
|
||||||
const babelParserPlugins = babelOptions.parserOpts?.plugins ?? [];
|
const babelParserPlugins = babelOptions.parserOpts?.plugins ?? [];
|
||||||
// todo: enable classFeatures when it is supported by ESLint
|
const estreeOptions = { classFeatures: ESLINT_VERSION >= 8 };
|
||||||
const estreeOptions = { classFeatures: false };
|
|
||||||
for (const plugin of babelParserPlugins) {
|
for (const plugin of babelParserPlugins) {
|
||||||
if (Array.isArray(plugin) && plugin[0] === "estree") {
|
if (Array.isArray(plugin) && plugin[0] === "estree") {
|
||||||
Object.assign(estreeOptions, plugin[1]);
|
Object.assign(estreeOptions, plugin[1]);
|
||||||
|
|||||||
@ -5,6 +5,16 @@ import { fileURLToPath } from "url";
|
|||||||
import { createRequire } from "module";
|
import { createRequire } from "module";
|
||||||
import { parseForESLint } from "../lib/index.cjs";
|
import { parseForESLint } from "../lib/index.cjs";
|
||||||
|
|
||||||
|
function parseForESLint8(code, options) {
|
||||||
|
const { ESLINT_VERSION_FOR_BABEL } = process.env;
|
||||||
|
process.env.ESLINT_VERSION_FOR_BABEL = "8";
|
||||||
|
try {
|
||||||
|
return parseForESLint(code, options);
|
||||||
|
} finally {
|
||||||
|
process.env.ESLINT_VERSION_FOR_BABEL = ESLINT_VERSION_FOR_BABEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
const BABEL_OPTIONS = {
|
const BABEL_OPTIONS = {
|
||||||
@ -18,6 +28,8 @@ const PROPS_TO_REMOVE = [
|
|||||||
"exportKind",
|
"exportKind",
|
||||||
"variance",
|
"variance",
|
||||||
"typeArguments",
|
"typeArguments",
|
||||||
|
"filename",
|
||||||
|
"identifierName",
|
||||||
];
|
];
|
||||||
|
|
||||||
function deeplyRemoveProperties(obj, props) {
|
function deeplyRemoveProperties(obj, props) {
|
||||||
@ -46,35 +58,61 @@ function deeplyRemoveProperties(obj, props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("Babel and Espree", () => {
|
describe("Babel and Espree", () => {
|
||||||
let espree;
|
let espree7, espree8;
|
||||||
|
|
||||||
function parseAndAssertSame(code) {
|
const espreeOptions = {
|
||||||
|
ecmaFeatures: {
|
||||||
|
// enable JSX parsing
|
||||||
|
jsx: true,
|
||||||
|
// enable return in global scope
|
||||||
|
globalReturn: true,
|
||||||
|
// enable implied strict mode (if ecmaVersion >= 5)
|
||||||
|
impliedStrict: true,
|
||||||
|
// allow experimental object rest/spread
|
||||||
|
experimentalObjectRestSpread: true,
|
||||||
|
},
|
||||||
|
tokens: true,
|
||||||
|
loc: true,
|
||||||
|
range: true,
|
||||||
|
comment: true,
|
||||||
|
sourceType: "module",
|
||||||
|
};
|
||||||
|
|
||||||
|
function parseAndAssertSame(code, /* optional */ eslintVersion) {
|
||||||
code = unpad(code);
|
code = unpad(code);
|
||||||
const espreeAST = espree.parse(code, {
|
|
||||||
ecmaFeatures: {
|
if (eslintVersion !== 8) {
|
||||||
// enable JSX parsing
|
// ESLint 7
|
||||||
jsx: true,
|
const espreeAST = espree7.parse(code, {
|
||||||
// enable return in global scope
|
...espreeOptions,
|
||||||
globalReturn: true,
|
ecmaVersion: 2021,
|
||||||
// enable implied strict mode (if ecmaVersion >= 5)
|
});
|
||||||
impliedStrict: true,
|
const babelAST = parseForESLint(code, {
|
||||||
// allow experimental object rest/spread
|
eslintVisitorKeys: true,
|
||||||
experimentalObjectRestSpread: true,
|
eslintScopeManager: true,
|
||||||
},
|
babelOptions: BABEL_OPTIONS,
|
||||||
tokens: true,
|
}).ast;
|
||||||
loc: true,
|
|
||||||
range: true,
|
deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE);
|
||||||
comment: true,
|
expect(babelAST).toEqual(espreeAST);
|
||||||
ecmaVersion: 2021,
|
}
|
||||||
sourceType: "module",
|
|
||||||
});
|
if (eslintVersion !== 7) {
|
||||||
const babelAST = parseForESLint(code, {
|
// ESLint 8
|
||||||
eslintVisitorKeys: true,
|
const espreeAST = espree8.parse(code, {
|
||||||
eslintScopeManager: true,
|
...espreeOptions,
|
||||||
babelOptions: BABEL_OPTIONS,
|
ecmaVersion: 2022,
|
||||||
}).ast;
|
});
|
||||||
deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE);
|
|
||||||
expect(babelAST).toEqual(espreeAST);
|
const babelAST = parseForESLint8(code, {
|
||||||
|
eslintVisitorKeys: true,
|
||||||
|
eslintScopeManager: true,
|
||||||
|
babelOptions: BABEL_OPTIONS,
|
||||||
|
}).ast;
|
||||||
|
|
||||||
|
deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE);
|
||||||
|
expect(babelAST).toEqual(espreeAST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
@ -82,11 +120,28 @@ describe("Babel and Espree", () => {
|
|||||||
|
|
||||||
// Use the version of Espree that is a dependency of
|
// Use the version of Espree that is a dependency of
|
||||||
// the version of ESLint we are testing against.
|
// the version of ESLint we are testing against.
|
||||||
const espreePath = require.resolve("espree", {
|
const espree7Path = require.resolve("espree", {
|
||||||
paths: [path.dirname(require.resolve("eslint"))],
|
paths: [path.dirname(require.resolve("eslint"))],
|
||||||
});
|
});
|
||||||
|
const espree8Path = require.resolve("espree", {
|
||||||
|
paths: [path.dirname(require.resolve("eslint-8"))],
|
||||||
|
});
|
||||||
|
|
||||||
espree = require(espreePath);
|
espree7 = require(espree7Path);
|
||||||
|
espree8 = require(espree8Path);
|
||||||
|
|
||||||
|
const espree7pkg = require(require.resolve("espree/package.json", {
|
||||||
|
paths: [path.dirname(require.resolve("eslint"))],
|
||||||
|
}));
|
||||||
|
const espree8pkg = require(require.resolve("espree/package.json", {
|
||||||
|
paths: [path.dirname(require.resolve("eslint-8"))],
|
||||||
|
}));
|
||||||
|
if (!espree7pkg.version.startsWith("7.")) {
|
||||||
|
throw new Error(`Expected espree 7, but found ${espree7pkg.version}`);
|
||||||
|
}
|
||||||
|
if (!espree8pkg.version.startsWith("9.")) {
|
||||||
|
throw new Error(`Expected espree 9, but found ${espree8pkg.version}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("compatibility", () => {
|
describe("compatibility", () => {
|
||||||
@ -381,7 +436,7 @@ describe("Babel and Espree", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (process.env.BABEL_8_BREAKING) {
|
if (process.env.BABEL_8_BREAKING) {
|
||||||
it("hash (token)", () => {
|
it("private identifier (token) - ESLint 7", () => {
|
||||||
const code = "class A { #x }";
|
const code = "class A { #x }";
|
||||||
const babylonAST = parseForESLint(code, {
|
const babylonAST = parseForESLint(code, {
|
||||||
eslintVisitorKeys: true,
|
eslintVisitorKeys: true,
|
||||||
@ -392,8 +447,7 @@ describe("Babel and Espree", () => {
|
|||||||
expect(babylonAST.tokens[3].value).toEqual("x");
|
expect(babylonAST.tokens[3].value).toEqual("x");
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Espree doesn't support private fields yet
|
it("hash (token) - ESLint 7", () => {
|
||||||
it("hash (token)", () => {
|
|
||||||
const code = "class A { #x }";
|
const code = "class A { #x }";
|
||||||
const babylonAST = parseForESLint(code, {
|
const babylonAST = parseForESLint(code, {
|
||||||
eslintVisitorKeys: true,
|
eslintVisitorKeys: true,
|
||||||
@ -405,6 +459,18 @@ describe("Babel and Espree", () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it("private identifier (token) - ESLint 8", () => {
|
||||||
|
const code = "class A { #x }";
|
||||||
|
const babylonAST = parseForESLint8(code, {
|
||||||
|
eslintVisitorKeys: true,
|
||||||
|
eslintScopeManager: true,
|
||||||
|
babelOptions: BABEL_OPTIONS,
|
||||||
|
}).ast;
|
||||||
|
|
||||||
|
expect(babylonAST.tokens[3].type).toEqual("PrivateIdentifier");
|
||||||
|
expect(babylonAST.tokens[3].value).toEqual("x");
|
||||||
|
});
|
||||||
|
|
||||||
it("static (token)", () => {
|
it("static (token)", () => {
|
||||||
const code = `
|
const code = `
|
||||||
import { static as foo } from "foo";
|
import { static as foo } from "foo";
|
||||||
@ -450,6 +516,170 @@ describe("Babel and Espree", () => {
|
|||||||
expect(classDeclaration.body.body[0].type).toEqual("PropertyDefinition");
|
expect(classDeclaration.body.body[0].type).toEqual("PropertyDefinition");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("class fields with ESLint 8", () => {
|
||||||
|
parseAndAssertSame(
|
||||||
|
`
|
||||||
|
class A {
|
||||||
|
x = 2;
|
||||||
|
static #y = 3;
|
||||||
|
asi
|
||||||
|
#m() {}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
8,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("static (token) - ESLint 7", () => {
|
||||||
|
const code = `
|
||||||
|
class A {
|
||||||
|
static m() {}
|
||||||
|
static() {}
|
||||||
|
static x;
|
||||||
|
static #y;
|
||||||
|
static;
|
||||||
|
static = 2;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const babylonAST = parseForESLint(code, {
|
||||||
|
eslintVisitorKeys: true,
|
||||||
|
eslintScopeManager: true,
|
||||||
|
babelOptions: BABEL_OPTIONS,
|
||||||
|
}).ast;
|
||||||
|
|
||||||
|
const staticKw = { type: "Keyword", value: "static" };
|
||||||
|
|
||||||
|
expect(babylonAST.tokens[3]).toMatchObject(staticKw);
|
||||||
|
expect(babylonAST.tokens[9]).toMatchObject(staticKw);
|
||||||
|
expect(babylonAST.tokens[14]).toMatchObject(staticKw);
|
||||||
|
expect(babylonAST.tokens[17]).toMatchObject(staticKw);
|
||||||
|
expect(
|
||||||
|
babylonAST.tokens[process.env.BABEL_8_BREAKING ? 20 : 21],
|
||||||
|
).toMatchObject(staticKw);
|
||||||
|
expect(
|
||||||
|
babylonAST.tokens[process.env.BABEL_8_BREAKING ? 22 : 23],
|
||||||
|
).toMatchObject(staticKw);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("static (token) - ESLint 8", () => {
|
||||||
|
const code = `
|
||||||
|
class A {
|
||||||
|
static m() {}
|
||||||
|
static() {}
|
||||||
|
static x;
|
||||||
|
static #y;
|
||||||
|
static;
|
||||||
|
static = 2;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const babylonAST = parseForESLint8(code, {
|
||||||
|
eslintVisitorKeys: true,
|
||||||
|
eslintScopeManager: true,
|
||||||
|
babelOptions: BABEL_OPTIONS,
|
||||||
|
}).ast;
|
||||||
|
|
||||||
|
const staticKw = { type: "Keyword", value: "static" };
|
||||||
|
|
||||||
|
expect(babylonAST.tokens[3]).toMatchObject(staticKw);
|
||||||
|
expect(babylonAST.tokens[9]).toMatchObject(staticKw);
|
||||||
|
expect(babylonAST.tokens[14]).toMatchObject(staticKw);
|
||||||
|
expect(babylonAST.tokens[17]).toMatchObject(staticKw);
|
||||||
|
expect(babylonAST.tokens[20]).toMatchObject(staticKw);
|
||||||
|
expect(babylonAST.tokens[22]).toMatchObject(staticKw);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (process.env.BABEL_8_BREAKING) {
|
||||||
|
it("pipeline # topic token - ESLint 7", () => {
|
||||||
|
const code = `
|
||||||
|
x |> #
|
||||||
|
y |> #[0]
|
||||||
|
class A {
|
||||||
|
#x = y |>
|
||||||
|
#
|
||||||
|
z
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const babylonAST = parseForESLint(code, {
|
||||||
|
eslintVisitorKeys: true,
|
||||||
|
eslintScopeManager: true,
|
||||||
|
babelOptions: {
|
||||||
|
filename: "test.js",
|
||||||
|
parserOpts: {
|
||||||
|
plugins: [
|
||||||
|
["pipelineOperator", { proposal: "hack", topicToken: "#" }],
|
||||||
|
],
|
||||||
|
tokens: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).ast;
|
||||||
|
|
||||||
|
const topicToken = { type: "Punctuator", value: "#" };
|
||||||
|
expect(babylonAST.tokens[2]).toMatchObject(topicToken);
|
||||||
|
expect(babylonAST.tokens[5]).toMatchObject(topicToken);
|
||||||
|
expect(babylonAST.tokens[16]).toMatchObject(topicToken);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
it("pipeline # topic token - ESLint 7", () => {
|
||||||
|
const code = `
|
||||||
|
x |> #
|
||||||
|
y |> #[0]
|
||||||
|
class A {
|
||||||
|
#x = y |>
|
||||||
|
#
|
||||||
|
z
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const babylonAST = parseForESLint(code, {
|
||||||
|
eslintVisitorKeys: true,
|
||||||
|
eslintScopeManager: true,
|
||||||
|
babelOptions: {
|
||||||
|
filename: "test.js",
|
||||||
|
parserOpts: {
|
||||||
|
plugins: [
|
||||||
|
["pipelineOperator", { proposal: "hack", topicToken: "#" }],
|
||||||
|
],
|
||||||
|
tokens: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).ast;
|
||||||
|
|
||||||
|
const topicToken = { type: "Punctuator", value: "#" };
|
||||||
|
expect(babylonAST.tokens[2]).toMatchObject(topicToken);
|
||||||
|
expect(babylonAST.tokens[5]).toMatchObject(topicToken);
|
||||||
|
expect(babylonAST.tokens[17]).toMatchObject(topicToken);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it("pipeline # topic token - ESLint 8", () => {
|
||||||
|
const code = `
|
||||||
|
x |> #
|
||||||
|
y |> #[0]
|
||||||
|
class A {
|
||||||
|
#x = y |>
|
||||||
|
#
|
||||||
|
z
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const babylonAST = parseForESLint8(code, {
|
||||||
|
eslintVisitorKeys: true,
|
||||||
|
eslintScopeManager: true,
|
||||||
|
babelOptions: {
|
||||||
|
filename: "test.js",
|
||||||
|
parserOpts: {
|
||||||
|
plugins: [
|
||||||
|
["pipelineOperator", { proposal: "hack", topicToken: "#" }],
|
||||||
|
],
|
||||||
|
tokens: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).ast;
|
||||||
|
|
||||||
|
const topicToken = { type: "Punctuator", value: "#" };
|
||||||
|
expect(babylonAST.tokens[2]).toMatchObject(topicToken);
|
||||||
|
expect(babylonAST.tokens[5]).toMatchObject(topicToken);
|
||||||
|
expect(babylonAST.tokens[16]).toMatchObject(topicToken);
|
||||||
|
});
|
||||||
|
|
||||||
it("empty program with line comment", () => {
|
it("empty program with line comment", () => {
|
||||||
parseAndAssertSame("// single comment");
|
parseAndAssertSame("// single comment");
|
||||||
});
|
});
|
||||||
|
|||||||
167
yarn.lock
167
yarn.lock
@ -324,12 +324,13 @@ __metadata:
|
|||||||
"@babel/core": "workspace:^"
|
"@babel/core": "workspace:^"
|
||||||
dedent: ^0.7.0
|
dedent: ^0.7.0
|
||||||
eslint: ^7.27.0
|
eslint: ^7.27.0
|
||||||
|
eslint-8: "npm:eslint@^8.0.0"
|
||||||
eslint-scope: ^5.1.1
|
eslint-scope: ^5.1.1
|
||||||
eslint-visitor-keys: ^2.1.0
|
eslint-visitor-keys: ^2.1.0
|
||||||
semver: "condition:BABEL_8_BREAKING ? ^7.3.4 : ^6.3.0"
|
semver: "condition:BABEL_8_BREAKING ? ^7.3.4 : ^6.3.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
"@babel/core": ">=7.11.0"
|
"@babel/core": ">=7.11.0"
|
||||||
eslint: ">=7.5.0"
|
eslint: ^7.5.0 || ^8.0.0
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@ -3656,6 +3657,41 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@eslint/eslintrc@npm:^1.0.2":
|
||||||
|
version: 1.0.2
|
||||||
|
resolution: "@eslint/eslintrc@npm:1.0.2"
|
||||||
|
dependencies:
|
||||||
|
ajv: ^6.12.4
|
||||||
|
debug: ^4.3.2
|
||||||
|
espree: ^9.0.0
|
||||||
|
globals: ^13.9.0
|
||||||
|
ignore: ^4.0.6
|
||||||
|
import-fresh: ^3.2.1
|
||||||
|
js-yaml: ^3.13.1
|
||||||
|
minimatch: ^3.0.4
|
||||||
|
strip-json-comments: ^3.1.1
|
||||||
|
checksum: bc57f1cfb8809552072e8dedf219753972f804c4d3efffbb365946fc1e09218b5e032da91afffee23739f21ecb761e151d72d5058245b5064183735c7a20fffb
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@humanwhocodes/config-array@npm:^0.6.0":
|
||||||
|
version: 0.6.0
|
||||||
|
resolution: "@humanwhocodes/config-array@npm:0.6.0"
|
||||||
|
dependencies:
|
||||||
|
"@humanwhocodes/object-schema": ^1.2.0
|
||||||
|
debug: ^4.1.1
|
||||||
|
minimatch: ^3.0.4
|
||||||
|
checksum: 1025b07514b7bfd10a05e8b6cb5e6520878e9c8836b3dd0569fc07df29a09e428c2df1e0760b1d461da8ed6f81ca83ecb02e24198f80b0a177a2acbf532e267c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@humanwhocodes/object-schema@npm:^1.2.0":
|
||||||
|
version: 1.2.0
|
||||||
|
resolution: "@humanwhocodes/object-schema@npm:1.2.0"
|
||||||
|
checksum: 40b75480376de8104d65f7c44a7dd76d30fb57823ca8ba3a3239b2b568323be894d93440578a72fd8e5e2cc3df3577ce0d2f0fe308b990dd51cf35392bf3c9a2
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@istanbuljs/load-nyc-config@npm:^1.0.0":
|
"@istanbuljs/load-nyc-config@npm:^1.0.0":
|
||||||
version: 1.1.0
|
version: 1.1.0
|
||||||
resolution: "@istanbuljs/load-nyc-config@npm:1.1.0"
|
resolution: "@istanbuljs/load-nyc-config@npm:1.1.0"
|
||||||
@ -5016,12 +5052,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"acorn@npm:^8.0.4, acorn@npm:^8.2.4":
|
"acorn@npm:^8.0.4, acorn@npm:^8.2.4, acorn@npm:^8.5.0":
|
||||||
version: 8.2.4
|
version: 8.5.0
|
||||||
resolution: "acorn@npm:8.2.4"
|
resolution: "acorn@npm:8.5.0"
|
||||||
bin:
|
bin:
|
||||||
acorn: bin/acorn
|
acorn: bin/acorn
|
||||||
checksum: cb4ffa2746bebd8ea808e98e139e2e497eaa254de45877abea6a2bad4e65a824fc37e23f6d163562b1e4ee12fcc8fa03948986c0a353b314bff78a0327168cb2
|
checksum: 2e4c1dbed3da327684863debf31d341bf8882c6893c506653872c00977eee45675feb9129255d6c74c88424d2b20d889ca6de5b39776e5e3cccfc756b3ca1da8
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -5286,6 +5322,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"argparse@npm:^2.0.1":
|
||||||
|
version: 2.0.1
|
||||||
|
resolution: "argparse@npm:2.0.1"
|
||||||
|
checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"arr-diff@npm:^1.0.1":
|
"arr-diff@npm:^1.0.1":
|
||||||
version: 1.1.0
|
version: 1.1.0
|
||||||
resolution: "arr-diff@npm:1.1.0"
|
resolution: "arr-diff@npm:1.1.0"
|
||||||
@ -7039,7 +7082,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1":
|
"debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2":
|
||||||
version: 4.3.2
|
version: 4.3.2
|
||||||
resolution: "debug@npm:4.3.2"
|
resolution: "debug@npm:4.3.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -7680,6 +7723,54 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"eslint-8@npm:eslint@^8.0.0":
|
||||||
|
version: 8.0.0
|
||||||
|
resolution: "eslint@npm:8.0.0"
|
||||||
|
dependencies:
|
||||||
|
"@eslint/eslintrc": ^1.0.2
|
||||||
|
"@humanwhocodes/config-array": ^0.6.0
|
||||||
|
ajv: ^6.10.0
|
||||||
|
chalk: ^4.0.0
|
||||||
|
cross-spawn: ^7.0.2
|
||||||
|
debug: ^4.3.2
|
||||||
|
doctrine: ^3.0.0
|
||||||
|
enquirer: ^2.3.5
|
||||||
|
escape-string-regexp: ^4.0.0
|
||||||
|
eslint-scope: ^6.0.0
|
||||||
|
eslint-utils: ^3.0.0
|
||||||
|
eslint-visitor-keys: ^3.0.0
|
||||||
|
espree: ^9.0.0
|
||||||
|
esquery: ^1.4.0
|
||||||
|
esutils: ^2.0.2
|
||||||
|
fast-deep-equal: ^3.1.3
|
||||||
|
file-entry-cache: ^6.0.1
|
||||||
|
functional-red-black-tree: ^1.0.1
|
||||||
|
glob-parent: ^6.0.1
|
||||||
|
globals: ^13.6.0
|
||||||
|
ignore: ^4.0.6
|
||||||
|
import-fresh: ^3.0.0
|
||||||
|
imurmurhash: ^0.1.4
|
||||||
|
is-glob: ^4.0.0
|
||||||
|
js-yaml: ^4.1.0
|
||||||
|
json-stable-stringify-without-jsonify: ^1.0.1
|
||||||
|
levn: ^0.4.1
|
||||||
|
lodash.merge: ^4.6.2
|
||||||
|
minimatch: ^3.0.4
|
||||||
|
natural-compare: ^1.4.0
|
||||||
|
optionator: ^0.9.1
|
||||||
|
progress: ^2.0.0
|
||||||
|
regexpp: ^3.2.0
|
||||||
|
semver: ^7.2.1
|
||||||
|
strip-ansi: ^6.0.0
|
||||||
|
strip-json-comments: ^3.1.0
|
||||||
|
text-table: ^0.2.0
|
||||||
|
v8-compile-cache: ^2.0.3
|
||||||
|
bin:
|
||||||
|
eslint: bin/eslint.js
|
||||||
|
checksum: 68ba2838862782d9cbf6100218cbf0d69873b6d5d1de5860627b5424f067e2145d334810168142452fb93692666aa1cbeb4d0a94eea089a7d54d3ae32e99942c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"eslint-import-resolver-node@npm:^0.3.4":
|
"eslint-import-resolver-node@npm:^0.3.4":
|
||||||
version: 0.3.4
|
version: 0.3.4
|
||||||
resolution: "eslint-import-resolver-node@npm:0.3.4"
|
resolution: "eslint-import-resolver-node@npm:0.3.4"
|
||||||
@ -7794,6 +7885,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"eslint-scope@npm:^6.0.0":
|
||||||
|
version: 6.0.0
|
||||||
|
resolution: "eslint-scope@npm:6.0.0"
|
||||||
|
dependencies:
|
||||||
|
esrecurse: ^4.3.0
|
||||||
|
estraverse: ^5.2.0
|
||||||
|
checksum: 3f1b3578f288c3820f68ad2aae102300e546be8a98a958f515405dc20cc2fe64fda583d364977628bb14fe3d4f96f37de5e9bc5d6eb26bc310da33ba2a677dc3
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0":
|
"eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0":
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
resolution: "eslint-utils@npm:2.1.0"
|
resolution: "eslint-utils@npm:2.1.0"
|
||||||
@ -7828,6 +7929,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"eslint-visitor-keys@npm:^3.0.0":
|
||||||
|
version: 3.0.0
|
||||||
|
resolution: "eslint-visitor-keys@npm:3.0.0"
|
||||||
|
checksum: 352607f367a2e0e2f9f234e40d6d9b34c39399345b8a9f204e1343749ddfae505d8343909cba6c4abc2ca03add4cdc0530af5e98f870ad7183fc2a89458669e5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"eslint@npm:^7.27.0":
|
"eslint@npm:^7.27.0":
|
||||||
version: 7.27.0
|
version: 7.27.0
|
||||||
resolution: "eslint@npm:7.27.0"
|
resolution: "eslint@npm:7.27.0"
|
||||||
@ -7888,6 +7996,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"espree@npm:^9.0.0":
|
||||||
|
version: 9.0.0
|
||||||
|
resolution: "espree@npm:9.0.0"
|
||||||
|
dependencies:
|
||||||
|
acorn: ^8.5.0
|
||||||
|
acorn-jsx: ^5.3.1
|
||||||
|
eslint-visitor-keys: ^3.0.0
|
||||||
|
checksum: f313c642e35587ce62a419f57ceea47937a719b084c7b31f649d2ca15ed92bc2dde58e2ac4fc381a74364b0db0b97d9cdb2a5d1ca0ccd7483bde9b4b04fe23e8
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"esprima@npm:^4.0.0, esprima@npm:^4.0.1":
|
"esprima@npm:^4.0.0, esprima@npm:^4.0.1":
|
||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
resolution: "esprima@npm:4.0.1"
|
resolution: "esprima@npm:4.0.1"
|
||||||
@ -8788,6 +8907,15 @@ fsevents@^1.2.7:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"glob-parent@npm:^6.0.1":
|
||||||
|
version: 6.0.1
|
||||||
|
resolution: "glob-parent@npm:6.0.1"
|
||||||
|
dependencies:
|
||||||
|
is-glob: ^4.0.1
|
||||||
|
checksum: 0468cf300b8c7a483dbd8c031704fa1003331cbc65ded095f768328ed35eec78dd199c224c7436db997569863c0cbc0b7fd7c3cb45508e6134c502be9e691dc5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"glob-stream@npm:^6.1.0":
|
"glob-stream@npm:^6.1.0":
|
||||||
version: 6.1.0
|
version: 6.1.0
|
||||||
resolution: "glob-stream@npm:6.1.0"
|
resolution: "glob-stream@npm:6.1.0"
|
||||||
@ -8901,12 +9029,12 @@ fsevents@^1.2.7:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"globals@npm:^13.6.0":
|
"globals@npm:^13.6.0, globals@npm:^13.9.0":
|
||||||
version: 13.8.0
|
version: 13.11.0
|
||||||
resolution: "globals@npm:13.8.0"
|
resolution: "globals@npm:13.11.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
type-fest: ^0.20.2
|
type-fest: ^0.20.2
|
||||||
checksum: acbfcad2b8aeff34d977a2df62bda863d7537e19f5b30cc3452493ce636b5193be9f68da46a53f41875f49052ddd7d550cd2568ecc818ddde3603e30def1fef3
|
checksum: e9e5624154261a3e5344d2105a94886c5f2ca48028fa8258cd7b9119c5f00cf2909392817bb2d162c9a1a31b55d9b2c14e8f2271c45a22f77806f5b9322541cf
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -10565,6 +10693,17 @@ fsevents@^1.2.7:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"js-yaml@npm:^4.1.0":
|
||||||
|
version: 4.1.0
|
||||||
|
resolution: "js-yaml@npm:4.1.0"
|
||||||
|
dependencies:
|
||||||
|
argparse: ^2.0.1
|
||||||
|
bin:
|
||||||
|
js-yaml: bin/js-yaml.js
|
||||||
|
checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"jsbn@npm:~0.1.0":
|
"jsbn@npm:~0.1.0":
|
||||||
version: 0.1.1
|
version: 0.1.1
|
||||||
resolution: "jsbn@npm:0.1.1"
|
resolution: "jsbn@npm:0.1.1"
|
||||||
@ -13056,10 +13195,10 @@ fsevents@^1.2.7:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"regexpp@npm:^3.0.0, regexpp@npm:^3.1.0":
|
"regexpp@npm:^3.0.0, regexpp@npm:^3.1.0, regexpp@npm:^3.2.0":
|
||||||
version: 3.1.0
|
version: 3.2.0
|
||||||
resolution: "regexpp@npm:3.1.0"
|
resolution: "regexpp@npm:3.2.0"
|
||||||
checksum: 63bcb2c98d63274774c79bef256e03f716d25f1fa8427267d0302d1436a83fa0d905f4e8a172fdfa99fb4d84833df2fb3bf7da2a1a868f156e913174c32b1139
|
checksum: a78dc5c7158ad9ddcfe01aa9144f46e192ddbfa7b263895a70a5c6c73edd9ce85faf7c0430e59ac38839e1734e275b9c3de5c57ee3ab6edc0e0b1bdebefccef8
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user