From a1c3759adfd087c8b5c3c892b92885b7dded4224 Mon Sep 17 00:00:00 2001 From: Teddy Katz Date: Fri, 23 Feb 2018 20:30:47 -0500 Subject: [PATCH] Chore: refactor populating configs with defaults in linter (#10006) --- conf/default-config-options.js | 29 ----------- lib/linter.js | 49 +++++++++---------- .../config-file/js/.eslintrc.parser3.js | 4 +- 3 files changed, 23 insertions(+), 59 deletions(-) delete mode 100644 conf/default-config-options.js diff --git a/conf/default-config-options.js b/conf/default-config-options.js deleted file mode 100644 index 96fe25ce6f1..00000000000 --- a/conf/default-config-options.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @fileoverview Default config options - * @author Teddy Katz - */ - -"use strict"; - -/** - * Freezes an object and all its nested properties - * @param {Object} obj The object to deeply freeze - * @returns {Object} `obj` after freezing it - */ -function deepFreeze(obj) { - if (obj === null || typeof obj !== "object") { - return obj; - } - - Object.keys(obj).map(key => obj[key]).forEach(deepFreeze); - return Object.freeze(obj); -} - -module.exports = deepFreeze({ - env: {}, - globals: {}, - rules: {}, - settings: {}, - parser: "espree", - parserOptions: {} -}); diff --git a/lib/linter.js b/lib/linter.js index 8e95c3a7111..207e2cad081 100755 --- a/lib/linter.js +++ b/lib/linter.js @@ -14,7 +14,6 @@ const eslintScope = require("eslint-scope"), levn = require("levn"), lodash = require("lodash"), blankScriptAST = require("../conf/blank-script.json"), - defaultConfig = require("../conf/default-config-options.js"), CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"), ConfigOps = require("./config/config-ops"), validator = require("./config/config-validator"), @@ -33,6 +32,7 @@ const eslintScope = require("eslint-scope"), const debug = require("debug")("eslint:linter"); const MAX_AUTOFIX_PASSES = 10; +const DEFAULT_PARSER_NAME = "espree"; //------------------------------------------------------------------------------ // Typedefs @@ -415,16 +415,13 @@ function normalizeEcmaVersion(ecmaVersion, isModule) { } /** - * Process initial config to make it safe to extend by file comment config + * Populates a config file with the default values, and merges any parserOptions stored in an env into + * the parserOptions of the populated config. * @param {Object} config Initial config * @param {Environments} envContext Env context - * @returns {Object} Processed config + * @returns {Object} Processed config */ -function prepareConfig(config, envContext) { - config.globals = config.globals || {}; - const copiedRules = {}; - let parserOptions = {}; - +function populateConfig(config, envContext) { if (typeof config.rules === "object") { Object.keys(config.rules).forEach(k => { const rule = config.rules[k]; @@ -432,32 +429,30 @@ function prepareConfig(config, envContext) { if (rule === null) { throw new Error(`Invalid config for rule '${k}'.`); } - if (Array.isArray(rule)) { - copiedRules[k] = rule.slice(); - } else { - copiedRules[k] = rule; - } }); } // merge in environment parserOptions - if (typeof config.env === "object") { - Object.keys(config.env).forEach(envName => { + const envNamesEnabledInConfig = typeof config.env === "object" + ? Object.keys(config.env).filter(envName => config.env[envName]) + : []; + + const parserOptionsFromEnv = envNamesEnabledInConfig + .reduce((parserOptions, envName) => { const env = envContext.get(envName); - if (config.env[envName] && env && env.parserOptions) { - parserOptions = ConfigOps.merge(parserOptions, env.parserOptions); - } - }); - } + return env && env.parserOptions + ? ConfigOps.merge(parserOptions, env.parserOptions) + : parserOptions; + }, {}); const preparedConfig = { - rules: copiedRules, - parser: config.parser || defaultConfig.parser, - globals: ConfigOps.merge(defaultConfig.globals, config.globals), - env: ConfigOps.merge(defaultConfig.env, config.env || {}), - settings: ConfigOps.merge(defaultConfig.settings, config.settings || {}), - parserOptions: ConfigOps.merge(parserOptions, config.parserOptions || {}) + rules: config.rules || {}, + parser: config.parser || DEFAULT_PARSER_NAME, + globals: config.globals || {}, + env: config.env || {}, + settings: config.settings || {}, + parserOptions: ConfigOps.merge(parserOptionsFromEnv, config.parserOptions || {}) }; const isModule = preparedConfig.parserOptions.sourceType === "module"; @@ -810,7 +805,7 @@ module.exports = class Linter { } // process initial config to make it safe to extend - config = prepareConfig(config, this.environments); + config = populateConfig(config, this.environments); if (!lastSourceCodes.get(this)) { diff --git a/tests/fixtures/config-file/js/.eslintrc.parser3.js b/tests/fixtures/config-file/js/.eslintrc.parser3.js index fd5f04ff12e..9324e00652a 100644 --- a/tests/fixtures/config-file/js/.eslintrc.parser3.js +++ b/tests/fixtures/config-file/js/.eslintrc.parser3.js @@ -1,7 +1,5 @@ -var defaultOptions = require("../../../../conf/default-config-options"); - module.exports = { - parser: defaultOptions.parser, + parser: "espree", rules: { semi: [2, "always"] }