Navigation Menu

Skip to content

Commit

Permalink
feat: Flat config support in Linter (refs #13481) (#15185)
Browse files Browse the repository at this point in the history
* Update: Flat config support in Linter (refs #13481)

* Update lib/linter/linter.js

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>

* Update lib/linter/linter.js

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>

* Clean up FlatConfigArray detection

* Add back FlatConfigArray import

* More flat config tests passing; originals failing

* Finish languageOptions features

* Make sure to recognize RuleTester-wrapped Espree

* Move globals into local file

* Normalize ecmaVersion to year on context.languageOptions

* Clean up ecmaVersion normalization

* Revert parserOptions.ecmaVersion behavior to original

* Add more tests

* Update defaults for flat config (refs #14588)

* More tests passing

* Fix wrong ecmaVersion conversion

* Duplicated all tests for FlatConfig

* Finish languageOptions tests

* Settings tests working

* Rule context tests working

* Options tests working

* Directives tests working

* reportUnusedDisableDirectives tests working

* All original tests passing

* Add test to verify lazy loading of rules (fixes #14862)

* Fix failing tests

* Fix failing browser test

* Fix ecmaVersion edge cases

* Switch globalReturn to false if sourceType is module

* Update Espree and eslint-scope to support sourceType:commonjs

* Update lib/linter/linter.js

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>

* Update lib/linter/linter.js

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>

* Fix processors functionality

* Update lib/shared/types.js

Co-authored-by: Brandon Mills <btmills@users.noreply.github.com>

* Update tests/lib/linter/linter.js

Co-authored-by: Brandon Mills <btmills@users.noreply.github.com>

* Update tests/lib/linter/linter.js

Co-authored-by: Brandon Mills <btmills@users.noreply.github.com>

* Update lib/linter/linter.js

Co-authored-by: Brandon Mills <btmills@users.noreply.github.com>

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
Co-authored-by: Brandon Mills <btmills@users.noreply.github.com>
  • Loading branch information
3 people committed Dec 4, 2021
1 parent 54deec5 commit 32ac37a
Show file tree
Hide file tree
Showing 14 changed files with 8,125 additions and 103 deletions.
144 changes: 144 additions & 0 deletions conf/globals.js
@@ -0,0 +1,144 @@
/**
* @fileoverview Globals for ecmaVersion/sourceType
* @author Nicholas C. Zakas
*/

"use strict";

//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------

const commonjs = {
exports: true,
global: false,
module: false,
require: false
};

const es3 = {
Array: false,
Boolean: false,
constructor: false,
Date: false,
decodeURI: false,
decodeURIComponent: false,
encodeURI: false,
encodeURIComponent: false,
Error: false,
escape: false,
eval: false,
EvalError: false,
Function: false,
hasOwnProperty: false,
Infinity: false,
isFinite: false,
isNaN: false,
isPrototypeOf: false,
Math: false,
NaN: false,
Number: false,
Object: false,
parseFloat: false,
parseInt: false,
propertyIsEnumerable: false,
RangeError: false,
ReferenceError: false,
RegExp: false,
String: false,
SyntaxError: false,
toLocaleString: false,
toString: false,
TypeError: false,
undefined: false,
unescape: false,
URIError: false,
valueOf: false
};

const es5 = {
...es3,
JSON: false
};

const es2015 = {
...es5,
ArrayBuffer: false,
DataView: false,
Float32Array: false,
Float64Array: false,
Int16Array: false,
Int32Array: false,
Int8Array: false,
Map: false,
Promise: false,
Proxy: false,
Reflect: false,
Set: false,
Symbol: false,
Uint16Array: false,
Uint32Array: false,
Uint8Array: false,
Uint8ClampedArray: false,
WeakMap: false,
WeakSet: false
};

// no new globals in ES2016
const es2016 = {
...es2015
};

const es2017 = {
...es2016,
Atomics: false,
SharedArrayBuffer: false
};

// no new globals in ES2018
const es2018 = {
...es2017
};

// no new globals in ES2019
const es2019 = {
...es2018
};

const es2020 = {
...es2019,
BigInt: false,
BigInt64Array: false,
BigUint64Array: false,
globalThis: false
};

const es2021 = {
...es2020,
AggregateError: false,
FinalizationRegistry: false,
WeakRef: false
};

const es2022 = {
...es2021
};


//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

module.exports = {
commonjs,
es3,
es5,
es2015,
es2016,
es2017,
es2018,
es2019,
es2020,
es2021,
es2022
};
9 changes: 9 additions & 0 deletions karma.conf.js
Expand Up @@ -16,6 +16,15 @@ module.exports = function(config) {
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: "",

// next three sections allow console.log to work
client: {
captureConsole: true
},

browserConsoleLogOptions: {
terminal: true,
level: "log"
},

/*
* frameworks to use
Expand Down
13 changes: 11 additions & 2 deletions lib/config/default-config.js
Expand Up @@ -26,7 +26,7 @@ exports.defaultConfig = [

/*
* Because we try to delay loading rules until absolutely
* necessary, a proxy allows us to hook into the lazy-loading
* necessary, a proxy allows us to hook into the lazy-loading
* aspect of the rules map while still keeping all of the
* relevant configuration inside of the config array.
*/
Expand All @@ -46,7 +46,16 @@ exports.defaultConfig = [
".git/**"
],
languageOptions: {
parser: "@/espree"
ecmaVersion: "latest",
sourceType: "module",
parser: "@/espree",
parserOptions: {}
}
},
{
files: ["**/*.cjs"],
languageOptions: {
sourceType: "commonjs"
}
}
];
4 changes: 2 additions & 2 deletions lib/config/flat-config-array.js
Expand Up @@ -52,13 +52,13 @@ class FlatConfigArray extends ConfigArray {
* @param {{basePath: string, baseConfig: FlatConfig}} options The options
* to use for the config array instance.
*/
constructor(configs, { basePath, baseConfig = defaultConfig }) {
constructor(configs, { basePath, baseConfig = defaultConfig } = {}) {
super(configs, {
basePath,
schema: flatConfigSchema
});

this.unshift(baseConfig);
this.unshift(...baseConfig);
}

/* eslint-disable class-methods-use-this -- Desired as instance method */
Expand Down
67 changes: 67 additions & 0 deletions lib/config/flat-config-helpers.js
@@ -0,0 +1,67 @@
/**
* @fileoverview Shared functions to work with configs.
* @author Nicholas C. Zakas
*/

"use strict";

//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------

/**
* Parses a ruleId into its plugin and rule parts.
* @param {string} ruleId The rule ID to parse.
* @returns {{pluginName:string,ruleName:string}} The plugin and rule
* parts of the ruleId;
*/
function parseRuleId(ruleId) {
let pluginName, ruleName;

// distinguish between core rules and plugin rules
if (ruleId.includes("/")) {
pluginName = ruleId.slice(0, ruleId.lastIndexOf("/"));
ruleName = ruleId.slice(pluginName.length + 1);
} else {
pluginName = "@";
ruleName = ruleId;
}

return {
pluginName,
ruleName
};
}

/**
* Retrieves a rule instance from a given config based on the ruleId.
* @param {string} ruleId The rule ID to look for.
* @param {FlatConfig} config The config to search.
* @returns {import("../shared/types").Rule|undefined} The rule if found
* or undefined if not.
*/
function getRuleFromConfig(ruleId, config) {

const { pluginName, ruleName } = parseRuleId(ruleId);

const plugin = config.plugins && config.plugins[pluginName];
let rule = plugin && plugin.rules && plugin.rules[ruleName];

// normalize function rules into objects
if (rule && typeof rule === "function") {
rule = {
create: rule
};
}

return rule;
}

//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

module.exports = {
parseRuleId,
getRuleFromConfig
};
21 changes: 13 additions & 8 deletions lib/config/flat-config-schema.js
Expand Up @@ -195,13 +195,6 @@ function assertIsObjectOrString(value) {
// Low-Level Schemas
//-----------------------------------------------------------------------------


/** @type {ObjectPropertySchema} */
const numberSchema = {
merge: "replace",
validate: "number"
};

/** @type {ObjectPropertySchema} */
const booleanSchema = {
merge: "replace",
Expand Down Expand Up @@ -415,6 +408,18 @@ const rulesSchema = {
}
};

/** @type {ObjectPropertySchema} */
const ecmaVersionSchema = {
merge: "replace",
validate(value) {
if (typeof value === "number" || value === "latest") {
return;
}

throw new TypeError("Expected a number or \"latest\".");
}
};

/** @type {ObjectPropertySchema} */
const sourceTypeSchema = {
merge: "replace",
Expand All @@ -439,7 +444,7 @@ exports.flatConfigSchema = {
},
languageOptions: {
schema: {
ecmaVersion: numberSchema,
ecmaVersion: ecmaVersionSchema,
sourceType: sourceTypeSchema,
globals: globalsSchema,
parser: parserSchema,
Expand Down

0 comments on commit 32ac37a

Please sign in to comment.