Skip to content

Commit

Permalink
feat: use context.languageOptions.ecmaVersion in core rules (#16458)
Browse files Browse the repository at this point in the history
Updates core rules to use `context.languageOptions.ecmaVersion`
instead of `context.parserOptions.ecmaVersion`

Fixes #16442
  • Loading branch information
mdjermanovic committed Oct 31, 2022
1 parent 8a15968 commit 319f0a5
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 17 deletions.
4 changes: 2 additions & 2 deletions lib/rules/comma-dangle.js
Expand Up @@ -50,7 +50,7 @@ function normalizeOptions(optionValue, ecmaVersion) {
objects: optionValue,
imports: optionValue,
exports: optionValue,
functions: (!ecmaVersion || ecmaVersion < 8) ? "ignore" : optionValue
functions: ecmaVersion < 2017 ? "ignore" : optionValue
};
}
if (typeof optionValue === "object" && optionValue !== null) {
Expand Down Expand Up @@ -134,7 +134,7 @@ module.exports = {
},

create(context) {
const options = normalizeOptions(context.options[0], context.parserOptions.ecmaVersion);
const options = normalizeOptions(context.options[0], context.languageOptions.ecmaVersion);

const sourceCode = context.getSourceCode();

Expand Down
4 changes: 2 additions & 2 deletions lib/rules/func-name-matching.js
Expand Up @@ -44,7 +44,7 @@ function isModuleExports(pattern) {
* @returns {boolean} True if the string is a valid identifier
*/
function isIdentifier(name, ecmaVersion) {
if (ecmaVersion >= 6) {
if (ecmaVersion >= 2015) {
return esutils.keyword.isIdentifierES6(name);
}
return esutils.keyword.isIdentifierES5(name);
Expand Down Expand Up @@ -104,7 +104,7 @@ module.exports = {
const nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always";
const considerPropertyDescriptor = options.considerPropertyDescriptor;
const includeModuleExports = options.includeCommonJSModuleExports;
const ecmaVersion = context.parserOptions && context.parserOptions.ecmaVersion ? context.parserOptions.ecmaVersion : 5;
const ecmaVersion = context.languageOptions.ecmaVersion;

/**
* Check whether node is a certain CallExpression.
Expand Down
8 changes: 4 additions & 4 deletions lib/rules/no-misleading-character-class.js
Expand Up @@ -193,15 +193,15 @@ module.exports = {
* ecmaVersion doesn't support the `u` flag.
*/
function isValidWithUnicodeFlag(pattern) {
const { ecmaVersion } = context.parserOptions;
const { ecmaVersion } = context.languageOptions;

// ecmaVersion is unknown or it doesn't support the 'u' flag
if (typeof ecmaVersion !== "number" || ecmaVersion <= 5) {
// ecmaVersion <= 5 doesn't support the 'u' flag
if (ecmaVersion <= 5) {
return false;
}

const validator = new RegExpValidator({
ecmaVersion: Math.min(ecmaVersion + 2009, REGEXPP_LATEST_ECMA_VERSION)
ecmaVersion: Math.min(ecmaVersion, REGEXPP_LATEST_ECMA_VERSION)
});

try {
Expand Down
8 changes: 4 additions & 4 deletions lib/rules/prefer-regex-literals.js
Expand Up @@ -248,14 +248,14 @@ module.exports = {

/**
* Returns a ecmaVersion compatible for regexpp.
* @param {any} ecmaVersion The ecmaVersion to convert.
* @param {number} ecmaVersion The ecmaVersion to convert.
* @returns {import("regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp.
*/
function getRegexppEcmaVersion(ecmaVersion) {
if (typeof ecmaVersion !== "number" || ecmaVersion <= 5) {
if (ecmaVersion <= 5) {
return 5;
}
return Math.min(ecmaVersion + 2009, REGEXPP_LATEST_ECMA_VERSION);
return Math.min(ecmaVersion, REGEXPP_LATEST_ECMA_VERSION);
}

/**
Expand Down Expand Up @@ -320,7 +320,7 @@ module.exports = {
flags = getStringValue(node.arguments[1]);
}

const regexppEcmaVersion = getRegexppEcmaVersion(context.parserOptions.ecmaVersion);
const regexppEcmaVersion = getRegexppEcmaVersion(context.languageOptions.ecmaVersion);
const RegExpValidatorInstance = new RegExpValidator({ ecmaVersion: regexppEcmaVersion });

try {
Expand Down
118 changes: 117 additions & 1 deletion tests/lib/rules/comma-dangle.js
Expand Up @@ -12,7 +12,8 @@
const path = require("path"),
{ unIndent } = require("../../_utils"),
rule = require("../../../lib/rules/comma-dangle"),
{ RuleTester } = require("../../../lib/rule-tester");
{ RuleTester } = require("../../../lib/rule-tester"),
FlatRuleTester = require("../../../lib/rule-tester/flat-rule-tester");

//------------------------------------------------------------------------------
// Helpers
Expand Down Expand Up @@ -279,6 +280,14 @@ ruleTester.run("comma-dangle", rule, {
code: "function foo(a,\nb) {}",
options: ["always-multiline"]
},
{
code: "foo(a,\nb\n)",
options: ["always-multiline"]
},
{
code: "function foo(a,\nb\n) {}",
options: ["always-multiline"]
},
{
code: "foo(a,\nb)",
options: ["always-multiline"]
Expand Down Expand Up @@ -321,6 +330,16 @@ ruleTester.run("comma-dangle", rule, {
options: ["always-multiline"],
parserOptions: { ecmaVersion: 7 }
},
{
code: "function foo(a,\nb\n) {}",
options: ["always-multiline"],
parserOptions: { ecmaVersion: 7 }
},
{
code: "foo(a,\nb\n)",
options: ["always-multiline"],
parserOptions: { ecmaVersion: 7 }
},
{
code: "function foo(a,\nb) {}",
options: ["only-multiline"],
Expand Down Expand Up @@ -1853,3 +1872,100 @@ let d = 0;export {d,};
}
]
});

const flatRuleTester = new FlatRuleTester();

// https://github.com/eslint/eslint/issues/16442
flatRuleTester.run("comma-dangle", rule, {
valid: [
{
code: "function f(\n a,\n b\n) {}",
options: ["always-multiline"],
languageOptions: {
ecmaVersion: 5,
sourceType: "script"
}
},
{
code: "f(\n a,\n b\n);",
options: ["always-multiline"],
languageOptions: {
ecmaVersion: 5,
sourceType: "script"
}
},
{
code: "function f(\n a,\n b\n) {}",
options: ["always-multiline"],
languageOptions: {
ecmaVersion: 2016
}
},
{
code: "f(\n a,\n b\n);",
options: ["always-multiline"],
languageOptions: {
ecmaVersion: 2016
}
}
],

invalid: [
{
code: "function f(\n a,\n b\n) {}",
output: "function f(\n a,\n b,\n) {}",
options: ["always-multiline"],
languageOptions: {
ecmaVersion: 2017
},
errors: [{
messageId: "missing",
type: "Identifier",
line: 3,
column: 3
}]
},
{
code: "f(\n a,\n b\n);",
output: "f(\n a,\n b,\n);",
options: ["always-multiline"],
languageOptions: {
ecmaVersion: 2017
},
errors: [{
messageId: "missing",
type: "Identifier",
line: 3,
column: 3
}]
},
{
code: "function f(\n a,\n b\n) {}",
output: "function f(\n a,\n b,\n) {}",
options: ["always-multiline"],
languageOptions: {
ecmaVersion: "latest"
},
errors: [{
messageId: "missing",
type: "Identifier",
line: 3,
column: 3
}]
},
{
code: "f(\n a,\n b\n);",
output: "f(\n a,\n b,\n);",
options: ["always-multiline"],
languageOptions: {
ecmaVersion: "latest"
},
errors: [{
messageId: "missing",
type: "Identifier",
line: 3,
column: 3
}]
}
]
});
39 changes: 37 additions & 2 deletions tests/lib/rules/func-name-matching.js
Expand Up @@ -10,7 +10,8 @@
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/func-name-matching"),
{ RuleTester } = require("../../../lib/rule-tester");
{ RuleTester } = require("../../../lib/rule-tester"),
FlatRuleTester = require("../../../lib/rule-tester/flat-rule-tester");

//------------------------------------------------------------------------------
// Tests
Expand Down Expand Up @@ -504,7 +505,8 @@ ruleTester.run("func-name-matching", rule, {
code: "class C { #x; foo() { a.b.#x = function y() {}; } }",
options: ["never"],
parserOptions: { ecmaVersion: 2022 }
}
},
"var obj = { '\\u1885': function foo() {} };" // not a valid identifier in es5
],
invalid: [
{
Expand Down Expand Up @@ -878,6 +880,39 @@ ruleTester.run("func-name-matching", rule, {
errors: [
{ messageId: "notMatchProperty", data: { funcName: "x", name: "x" } }
]
},
{
code: "var obj = { '\\u1885': function foo() {} };", // valid identifier in es2015
parserOptions: { ecmaVersion: 6 },
errors: [
{ messageId: "matchProperty", data: { funcName: "foo", name: "\u1885" } }
]
}
]
});

const flatRuleTester = new FlatRuleTester();

flatRuleTester.run("func-name-matching", rule, {
valid: [
{
code: "var obj = { '\\u1885': function foo() {} };", // not a valid identifier in es5
languageOptions: {
ecmaVersion: 5,
sourceType: "script"
}
}
],

invalid: [
{
code: "var obj = { '\\u1885': function foo() {} };", // valid identifier in es2015
languageOptions: {
ecmaVersion: 2015
},
errors: [
{ messageId: "matchProperty", data: { funcName: "foo", name: "\u1885" } }
]
}
]
});
33 changes: 32 additions & 1 deletion tests/lib/rules/no-misleading-character-class.js
Expand Up @@ -9,7 +9,8 @@
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/no-misleading-character-class"),
{ RuleTester } = require("../../../lib/rule-tester");
{ RuleTester } = require("../../../lib/rule-tester"),
FlatRuleTester = require("../../../lib/rule-tester/flat-rule-tester");

//------------------------------------------------------------------------------
// Tests
Expand Down Expand Up @@ -622,3 +623,33 @@ ruleTester.run("no-misleading-character-class", rule, {
}
]
});

const flatRuleTester = new FlatRuleTester();

flatRuleTester.run("no-misleading-character-class", rule, {
valid: [],

invalid: [
{
code: "var r = /[👍]/",
languageOptions: {
ecmaVersion: 5,
sourceType: "script"
},
errors: [{
messageId: "surrogatePairWithoutUFlag",
suggestions: null // ecmaVersion doesn't support the 'u' flag
}]
},
{
code: "var r = /[👍]/",
languageOptions: {
ecmaVersion: 2015
},
errors: [{
messageId: "surrogatePairWithoutUFlag",
suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /[👍]/u" }]
}]
}
]
});
27 changes: 26 additions & 1 deletion tests/lib/rules/prefer-regex-literals.js
Expand Up @@ -10,7 +10,8 @@
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/prefer-regex-literals");
const { RuleTester } = require("../../../lib/rule-tester");
const { RuleTester } = require("../../../lib/rule-tester"),
FlatRuleTester = require("../../../lib/rule-tester/flat-rule-tester");

//------------------------------------------------------------------------------
// Tests
Expand Down Expand Up @@ -2474,3 +2475,27 @@ ruleTester.run("prefer-regex-literals", rule, {
}
]
});

const flatRuleTester = new FlatRuleTester();

flatRuleTester.run("prefer-regex-literals", rule, {
valid: [],

invalid: [
{
code: "var regex = new RegExp('foo', 'u');",
languageOptions: {
ecmaVersion: 2015
},
errors: [{
messageId: "unexpectedRegExp",
suggestions: [
{
messageId: "replaceWithLiteral",
output: "var regex = /foo/u;"
}
]
}]
}
]
});

0 comments on commit 319f0a5

Please sign in to comment.