Skip to content

Commit

Permalink
feat(linter): support read env from eslintrc
Browse files Browse the repository at this point in the history
  • Loading branch information
fi3ework committed Jan 24, 2024
1 parent 3d184d5 commit 26f275e
Show file tree
Hide file tree
Showing 22 changed files with 4,180 additions and 94 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"env": {
"browser": true
},
"rules": {
"no-undef": "error"
}
}
5 changes: 5 additions & 0 deletions crates/oxc_cli/fixtures/eslintrc_env/eslintrc_no_env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"no-undef": "error"
}
}
1 change: 1 addition & 0 deletions crates/oxc_cli/fixtures/eslintrc_env/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('')
23 changes: 23 additions & 0 deletions crates/oxc_cli/src/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,29 @@ mod test {
assert_eq!(result.number_of_errors, 0);
}

#[test]
fn eslintrc_no_env() {
let args =
&["-c", "fixtures/eslintrc_env/eslintrc_no_env.json", "fixtures/eslintrc_env/test.js"];
let result = test(args);
assert_eq!(result.number_of_files, 1);
assert_eq!(result.number_of_warnings, 1);
assert_eq!(result.number_of_errors, 0);
}

#[test]
fn eslintrc_with_env() {
let args = &[
"-c",
"fixtures/eslintrc_env/eslintrc_env_browser.json",
"fixtures/eslintrc_env/test.js",
];
let result = test(args);
assert_eq!(result.number_of_files, 1);
assert_eq!(result.number_of_warnings, 0);
assert_eq!(result.number_of_errors, 0);
}

#[test]
fn no_empty_allow_empty_catch() {
let args = &[
Expand Down
32 changes: 28 additions & 4 deletions crates/oxc_linter/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use oxc_diagnostics::{Error, FailedToOpenFileError, Report};
use rustc_hash::{FxHashMap, FxHashSet};
use serde_json::Value;

use crate::{rules::RuleEnum, settings::Nextjs, AllowWarnDeny, JsxA11y, LintSettings};
use crate::{rules::RuleEnum, settings::Nextjs, AllowWarnDeny, Env, JsxA11y, LintSettings};

use self::errors::{
FailedToParseConfigError, FailedToParseConfigJsonError, FailedToParseJsonc,
Expand All @@ -15,6 +15,7 @@ use self::errors::{
pub struct ESLintConfig {
rules: Vec<ESLintRuleConfig>,
settings: LintSettings,
env: Env,
}

#[derive(Debug)]
Expand All @@ -30,11 +31,12 @@ impl ESLintConfig {
let json = Self::read_json(path)?;
let rules = parse_rules(&json)?;
let settings = parse_settings_from_root(&json);
Ok(Self { rules, settings })
let env = parse_env_from_root(&json);
Ok(Self { rules, settings, env })
}

pub fn settings(self) -> LintSettings {
self.settings
pub fn properties(self) -> (LintSettings, Env) {
(self.settings, self.env)
}

fn read_json(path: &Path) -> Result<serde_json::Value, Error> {
Expand Down Expand Up @@ -201,6 +203,28 @@ pub fn parse_settings(setting_value: &Value) -> LintSettings {
LintSettings::default()
}

fn parse_env_from_root(root_json: &Value) -> Env {
let Value::Object(root_object) = root_json else { return Env::default() };

let Some(env_value) = root_object.get("env") else { return Env::default() };

let env_object = match env_value {
Value::Object(env_object) => env_object,
_ => return Env::default(),
};

let mut result = vec![];
for (k, v) in env_object {
if let Value::Bool(v) = v {
if *v {
result.push(String::from(k));
}
}
}

Env::new(result)
}

fn parse_rule_name(name: &str) -> (&str, &str) {
if let Some((category, name)) = name.split_once('/') {
let category = category.trim_start_matches('@');
Expand Down
27 changes: 26 additions & 1 deletion crates/oxc_linter/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use oxc_span::SourceType;

use crate::{
disable_directives::{DisableDirectives, DisableDirectivesBuilder},
environments::ENVIRONMENTS,
fixer::{Fix, Message},
AstNode, LintSettings,
AstNode, Env, LintSettings,
};

pub struct LintContext<'a> {
Expand All @@ -26,6 +27,8 @@ pub struct LintContext<'a> {
file_path: Box<Path>,

settings: Arc<LintSettings>,

env: Arc<Env>,
}

impl<'a> LintContext<'a> {
Expand All @@ -40,6 +43,7 @@ impl<'a> LintContext<'a> {
current_rule_name: "",
file_path,
settings: Arc::new(LintSettings::default()),
env: Arc::new(Env::default()),
}
}

Expand All @@ -55,6 +59,12 @@ impl<'a> LintContext<'a> {
self
}

#[must_use]
pub fn with_env(mut self, env: &Arc<Env>) -> Self {
self.env = Arc::clone(env);
self
}

pub fn semantic(&self) -> &Rc<Semantic<'a>> {
&self.semantic
}
Expand All @@ -79,6 +89,21 @@ impl<'a> LintContext<'a> {
&self.file_path
}

pub fn envs(&self) -> &Env {
&self.env
}

pub fn env_contains_var(&self, var: &str) -> bool {
for env in self.env.iter() {
let env = ENVIRONMENTS.get(env).unwrap_or(&ENVIRONMENTS["builtin"]);
if env.get(var).is_some() {
return true;
}
}

false
}

#[inline]
pub fn with_rule_name(&mut self, name: &'static str) {
self.current_rule_name = name;
Expand Down
25 changes: 25 additions & 0 deletions crates/oxc_linter/src/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use std::{self, ops::Deref};

#[derive(Debug, Clone)]
pub struct Env(Vec<String>);

impl Env {
pub fn new(env: Vec<String>) -> Self {
Self(env)
}
}

/// The `env` field from ESLint config
impl Default for Env {
fn default() -> Self {
Self(vec!["builtin".to_string()])
}
}

impl Deref for Env {
type Target = Vec<String>;

fn deref(&self) -> &Self::Target {
&self.0
}
}
Loading

0 comments on commit 26f275e

Please sign in to comment.