Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions crates/oxc_linter/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,29 @@ impl<'a> LintContext<'a> {
/// Checks if a given variable named is defined as a global variable in the current environment.
///
/// Example:
/// - `env_contains_var("Date")` returns `true` because it is a global builtin in all environments.
/// - `env_contains_var("HTMLElement")` returns `true` only if the `browser` environment is enabled.
/// - `env_contains_var("globalThis")` returns `true` only if the `es2020` environment or higher is enabled.
pub fn env_contains_var(&self, var: &str) -> bool {
/// - `is_global_defined("Date")` returns `true` because it is a global builtin in all environments.
/// - `is_global_defined("HTMLElement")` returns `true` only if the `browser` environment is enabled.
/// - `is_global_defined("globalThis")` returns `true` only if the `es2020` environment or higher is enabled.
/// - `is_global_defined("myGlobalVar")` returns `true` only if it is defined in the `globals` section as a non "off" value.
pub fn is_global_defined(&self, var: &str) -> bool {
if !self.scoping().root_unresolved_references().contains_key(var) {
return false;
}
if self.globals().is_enabled(var) {
return true;
}
self.env_contains_var(var)
}

pub fn is_ecma_script_global(&self, var: &str) -> bool {
if !self.scoping().root_unresolved_references().contains_key(var) {
return false;
}

GLOBALS["es2026"].contains_key(var) || GLOBALS["builtin"].contains_key(var)
}

fn env_contains_var(&self, var: &str) -> bool {
if GLOBALS["builtin"].contains_key(var) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,7 @@ impl NoConstantBinaryExpression {
| Expression::RegExpLiteral(_) => true,
Expression::NewExpression(call_expr) => {
if let Expression::Identifier(ident) = &call_expr.callee {
return ctx.env_contains_var(ident.name.as_str())
&& ctx.scoping().root_unresolved_references().contains_key(&ident.name);
return ctx.is_ecma_script_global(&ident.name);
}
false
}
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_linter/src/rules/eslint/no_extend_native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl Rule for NoExtendNative {
let reference = symbols.get_reference(reference_id);
let name = ctx.semantic().reference_name(reference);
// If the referenced name does not appear to be a global object, skip it.
if !ctx.env_contains_var(name) {
if !ctx.is_ecma_script_global(name) {
continue;
}
// If the referenced name is explicitly allowed, skip it.
Expand Down
13 changes: 8 additions & 5 deletions crates/oxc_linter/src/rules/eslint/no_undef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,7 @@ impl Rule for NoUndef {

let name = ctx.semantic().reference_name(reference);

if ctx.env_contains_var(name) {
continue;
}

if ctx.globals().is_enabled(name) {
if ctx.is_global_defined(name) {
continue;
}

Expand Down Expand Up @@ -152,6 +148,13 @@ fn test() {
("var a; ({b: a} = {});", None, None),
("var obj; [obj.a, obj.b] = [0, 1];", None, None),
("URLSearchParams;", None, Some(serde_json::json!({"env": { "browser": true }}))),
(
"URLSearchParams;",
None,
Some(
serde_json::json!({"env": { "browser": false }, "globals": { "URLSearchParams": "readonly" }}),
),
),
("Intl;", None, Some(serde_json::json!({"env": { "browser": true }}))),
("IntersectionObserver;", None, Some(serde_json::json!({"env": { "browser": true }}))),
("Credential;", None, Some(serde_json::json!({"env": { "browser": true }}))),
Expand Down
Loading