diff --git a/Cargo.lock b/Cargo.lock index a3e2fd323..b9974cefd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -915,6 +915,16 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "javascript_globals" +version = "0.0.0" +dependencies = [ + "handlebars", + "lazy_static", + "oxc_tasks_common", + "serde", +] + [[package]] name = "jemalloc-sys" version = "0.5.4+5.3.0-patched" diff --git a/crates/oxc_cli/fixtures/eslintrc_env/eslintrc_env_browser.json b/crates/oxc_cli/fixtures/eslintrc_env/eslintrc_env_browser.json new file mode 100644 index 000000000..5c23b263d --- /dev/null +++ b/crates/oxc_cli/fixtures/eslintrc_env/eslintrc_env_browser.json @@ -0,0 +1,8 @@ +{ + "env": { + "browser": true + }, + "rules": { + "no-undef": "error" + } +} diff --git a/crates/oxc_cli/fixtures/eslintrc_env/eslintrc_no_env.json b/crates/oxc_cli/fixtures/eslintrc_env/eslintrc_no_env.json new file mode 100644 index 000000000..2b372cf36 --- /dev/null +++ b/crates/oxc_cli/fixtures/eslintrc_env/eslintrc_no_env.json @@ -0,0 +1,5 @@ +{ + "rules": { + "no-undef": "error" + } +} diff --git a/crates/oxc_cli/fixtures/eslintrc_env/test.js b/crates/oxc_cli/fixtures/eslintrc_env/test.js new file mode 100644 index 000000000..4e750168a --- /dev/null +++ b/crates/oxc_cli/fixtures/eslintrc_env/test.js @@ -0,0 +1 @@ +console.log('') diff --git a/crates/oxc_cli/src/lint/mod.rs b/crates/oxc_cli/src/lint/mod.rs index 2f9a8319e..b448c15b4 100644 --- a/crates/oxc_cli/src/lint/mod.rs +++ b/crates/oxc_cli/src/lint/mod.rs @@ -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 = &[ diff --git a/crates/oxc_linter/src/config/mod.rs b/crates/oxc_linter/src/config/mod.rs index e44ad36ea..418edc9a5 100644 --- a/crates/oxc_linter/src/config/mod.rs +++ b/crates/oxc_linter/src/config/mod.rs @@ -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, @@ -15,6 +15,7 @@ use self::errors::{ pub struct ESLintConfig { rules: Vec, settings: LintSettings, + env: Env, } #[derive(Debug)] @@ -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 { @@ -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('@'); diff --git a/crates/oxc_linter/src/context.rs b/crates/oxc_linter/src/context.rs index 269d93426..6f27f520e 100644 --- a/crates/oxc_linter/src/context.rs +++ b/crates/oxc_linter/src/context.rs @@ -8,7 +8,8 @@ use oxc_span::SourceType; use crate::{ disable_directives::{DisableDirectives, DisableDirectivesBuilder}, fixer::{Fix, Message}, - AstNode, LintSettings, + javascript_globals::GLOBALS, + AstNode, Env, LintSettings, }; pub struct LintContext<'a> { @@ -26,6 +27,8 @@ pub struct LintContext<'a> { file_path: Box, settings: Arc, + + env: Arc, } impl<'a> LintContext<'a> { @@ -40,6 +43,7 @@ impl<'a> LintContext<'a> { current_rule_name: "", file_path, settings: Arc::new(LintSettings::default()), + env: Arc::new(Env::default()), } } @@ -55,6 +59,12 @@ impl<'a> LintContext<'a> { self } + #[must_use] + pub fn with_env(mut self, env: &Arc) -> Self { + self.env = Arc::clone(env); + self + } + pub fn semantic(&self) -> &Rc> { &self.semantic } @@ -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 = GLOBALS.get(env).unwrap_or(&GLOBALS["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; diff --git a/crates/oxc_linter/src/env.rs b/crates/oxc_linter/src/env.rs new file mode 100644 index 000000000..9dae87713 --- /dev/null +++ b/crates/oxc_linter/src/env.rs @@ -0,0 +1,25 @@ +use std::{self, ops::Deref}; + +#[derive(Debug, Clone)] +pub struct Env(Vec); + +impl Env { + pub fn new(env: Vec) -> 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; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/crates/oxc_linter/src/globals.rs b/crates/oxc_linter/src/globals.rs index 9ea1744e1..6deae467b 100644 --- a/crates/oxc_linter/src/globals.rs +++ b/crates/oxc_linter/src/globals.rs @@ -1,79 +1,5 @@ -//! [Globals](https://github.com/sindresorhus/globals/blob/main/globals.json) -//! Each global is given a value of true or false. -//! A value of true indicates that the variable may be overwritten. -//! A value of false indicates that the variable should be considered read-only. - use phf::{phf_map, phf_set, Map}; -pub const BUILTINS: Map<&'static str, bool> = phf_map! { - "AggregateError" => false, - "Array" => false, - "ArrayBuffer" => false, - "Atomics" => false, - "BigInt" => false, - "BigInt64Array" => false, - "BigUint64Array" => false, - "Boolean" => false, - "constructor" => false, - "DataView" => false, - "Date" => false, - "decodeURI" => false, - "decodeURIComponent" => false, - "encodeURI" => false, - "encodeURIComponent" => false, - "Error" => false, - "escape" => false, - "eval" => false, - "EvalError" => false, - "FinalizationRegistry" => false, - "Float32Array" => false, - "Float64Array" => false, - "Function" => false, - "globalThis" => false, - "hasOwnProperty" => false, - "Infinity" => false, - "Int16Array" => false, - "Int32Array" => false, - "Int8Array" => false, - "isFinite" => false, - "isNaN" => false, - "isPrototypeOf" => false, - "JSON" => false, - "Map" => false, - "Math" => false, - "NaN" => false, - "Number" => false, - "Object" => false, - "parseFloat" => false, - "parseInt" => false, - "Promise" => false, - "propertyIsEnumerable" => false, - "Proxy" => false, - "RangeError" => false, - "ReferenceError" => false, - "Reflect" => false, - "RegExp" => false, - "Set" => false, - "SharedArrayBuffer" => false, - "String" => false, - "Symbol" => false, - "Diagnostic" => false, - "toLocaleString" => false, - "toString" => false, - "TypeError" => false, - "Uint16Array" => false, - "Uint32Array" => false, - "Uint8Array" => false, - "Uint8ClampedArray" => false, - "undefined" => false, - "unescape" => false, - "URIError" => false, - "valueOf" => false, - "WeakMap" => false, - "WeakRef" => false, - "WeakSet" => false -}; - pub const PRE_DEFINE_VAR: Map<&'static str, bool> = phf_map! { "undefined" => false, "Infinity" => false, diff --git a/crates/oxc_linter/src/javascript_globals.rs b/crates/oxc_linter/src/javascript_globals.rs new file mode 100644 index 000000000..33440433f --- /dev/null +++ b/crates/oxc_linter/src/javascript_globals.rs @@ -0,0 +1,1832 @@ +use phf::{phf_map, Map}; + +pub static GLOBALS: Map<&'static str, Map<&'static str, bool>> = phf_map! { + "builtin" => phf_map! { + "AggregateError" => false, + "Array" => false, + "ArrayBuffer" => false, + "Atomics" => false, + "BigInt" => false, + "BigInt64Array" => false, + "BigUint64Array" => false, + "Boolean" => false, + "DataView" => false, + "Date" => false, + "Error" => false, + "EvalError" => false, + "FinalizationRegistry" => false, + "Float32Array" => false, + "Float64Array" => false, + "Function" => false, + "Infinity" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "JSON" => false, + "Map" => false, + "Math" => false, + "NaN" => false, + "Number" => false, + "Object" => false, + "Promise" => false, + "Proxy" => false, + "RangeError" => false, + "ReferenceError" => false, + "Reflect" => false, + "RegExp" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "String" => false, + "Symbol" => false, + "SyntaxError" => false, + "TypeError" => false, + "URIError" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakRef" => false, + "WeakSet" => false, + "constructor" => false, + "decodeURI" => false, + "decodeURIComponent" => false, + "encodeURI" => false, + "encodeURIComponent" => false, + "escape" => false, + "eval" => false, + "globalThis" => false, + "hasOwnProperty" => false, + "isFinite" => false, + "isNaN" => false, + "isPrototypeOf" => false, + "parseFloat" => false, + "parseInt" => false, + "propertyIsEnumerable" => false, + "toLocaleString" => false, + "toString" => false, + "undefined" => false, + "unescape" => false, + "valueOf" => false, + }, + "es6" => phf_map! { + "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, + }, + "es2015" => phf_map! { + "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, + }, + "es2016" => phf_map! { + "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, + }, + "es2017" => phf_map! { + "ArrayBuffer" => false, + "Atomics" => false, + "DataView" => false, + "Float32Array" => false, + "Float64Array" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "Map" => false, + "Promise" => false, + "Proxy" => false, + "Reflect" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "Symbol" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakSet" => false, + }, + "es2018" => phf_map! { + "ArrayBuffer" => false, + "Atomics" => false, + "DataView" => false, + "Float32Array" => false, + "Float64Array" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "Map" => false, + "Promise" => false, + "Proxy" => false, + "Reflect" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "Symbol" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakSet" => false, + }, + "es2019" => phf_map! { + "ArrayBuffer" => false, + "Atomics" => false, + "DataView" => false, + "Float32Array" => false, + "Float64Array" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "Map" => false, + "Promise" => false, + "Proxy" => false, + "Reflect" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "Symbol" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakSet" => false, + }, + "es2020" => phf_map! { + "ArrayBuffer" => false, + "Atomics" => false, + "BigInt" => false, + "BigInt64Array" => false, + "BigUint64Array" => false, + "DataView" => false, + "Float32Array" => false, + "Float64Array" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "Map" => false, + "Promise" => false, + "Proxy" => false, + "Reflect" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "Symbol" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakSet" => false, + "globalThis" => false, + }, + "es2021" => phf_map! { + "AggregateError" => false, + "ArrayBuffer" => false, + "Atomics" => false, + "BigInt" => false, + "BigInt64Array" => false, + "BigUint64Array" => false, + "DataView" => false, + "FinalizationRegistry" => false, + "Float32Array" => false, + "Float64Array" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "Map" => false, + "Promise" => false, + "Proxy" => false, + "Reflect" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "Symbol" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakRef" => false, + "WeakSet" => false, + "globalThis" => false, + }, + "es2022" => phf_map! { + "AggregateError" => false, + "ArrayBuffer" => false, + "Atomics" => false, + "BigInt" => false, + "BigInt64Array" => false, + "BigUint64Array" => false, + "DataView" => false, + "FinalizationRegistry" => false, + "Float32Array" => false, + "Float64Array" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "Map" => false, + "Promise" => false, + "Proxy" => false, + "Reflect" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "Symbol" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakRef" => false, + "WeakSet" => false, + "globalThis" => false, + }, + "es2023" => phf_map! { + "AggregateError" => false, + "ArrayBuffer" => false, + "Atomics" => false, + "BigInt" => false, + "BigInt64Array" => false, + "BigUint64Array" => false, + "DataView" => false, + "FinalizationRegistry" => false, + "Float32Array" => false, + "Float64Array" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "Map" => false, + "Promise" => false, + "Proxy" => false, + "Reflect" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "Symbol" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakRef" => false, + "WeakSet" => false, + "globalThis" => false, + }, + "es2024" => phf_map! { + "AggregateError" => false, + "ArrayBuffer" => false, + "Atomics" => false, + "BigInt" => false, + "BigInt64Array" => false, + "BigUint64Array" => false, + "DataView" => false, + "FinalizationRegistry" => false, + "Float32Array" => false, + "Float64Array" => false, + "Int16Array" => false, + "Int32Array" => false, + "Int8Array" => false, + "Map" => false, + "Promise" => false, + "Proxy" => false, + "Reflect" => false, + "Set" => false, + "SharedArrayBuffer" => false, + "Symbol" => false, + "Uint16Array" => false, + "Uint32Array" => false, + "Uint8Array" => false, + "Uint8ClampedArray" => false, + "WeakMap" => false, + "WeakRef" => false, + "WeakSet" => false, + "globalThis" => false, + }, + "browser" => phf_map! { + "AbortController" => false, + "AbortSignal" => false, + "AnalyserNode" => false, + "Animation" => false, + "AnimationEffectReadOnly" => false, + "AnimationEffectTiming" => false, + "AnimationEffectTimingReadOnly" => false, + "AnimationEvent" => false, + "AnimationPlaybackEvent" => false, + "AnimationTimeline" => false, + "ApplicationCache" => false, + "ApplicationCacheErrorEvent" => false, + "Attr" => false, + "Audio" => false, + "AudioBuffer" => false, + "AudioBufferSourceNode" => false, + "AudioContext" => false, + "AudioDestinationNode" => false, + "AudioListener" => false, + "AudioNode" => false, + "AudioParam" => false, + "AudioProcessingEvent" => false, + "AudioScheduledSourceNode" => false, + "AudioWorkletGlobalScope" => false, + "AudioWorkletNode" => false, + "AudioWorkletProcessor" => false, + "BarProp" => false, + "BaseAudioContext" => false, + "BatteryManager" => false, + "BeforeUnloadEvent" => false, + "BiquadFilterNode" => false, + "Blob" => false, + "BlobEvent" => false, + "BroadcastChannel" => false, + "BudgetService" => false, + "ByteLengthQueuingStrategy" => false, + "CSS" => false, + "CSSConditionRule" => false, + "CSSFontFaceRule" => false, + "CSSGroupingRule" => false, + "CSSImportRule" => false, + "CSSKeyframeRule" => false, + "CSSKeyframesRule" => false, + "CSSMatrixComponent" => false, + "CSSMediaRule" => false, + "CSSNamespaceRule" => false, + "CSSPageRule" => false, + "CSSPerspective" => false, + "CSSRotate" => false, + "CSSRule" => false, + "CSSRuleList" => false, + "CSSScale" => false, + "CSSSkew" => false, + "CSSSkewX" => false, + "CSSSkewY" => false, + "CSSStyleDeclaration" => false, + "CSSStyleRule" => false, + "CSSStyleSheet" => false, + "CSSSupportsRule" => false, + "CSSTransformValue" => false, + "CSSTranslate" => false, + "Cache" => false, + "CacheStorage" => false, + "CanvasCaptureMediaStreamTrack" => false, + "CanvasGradient" => false, + "CanvasPattern" => false, + "CanvasRenderingContext2D" => false, + "ChannelMergerNode" => false, + "ChannelSplitterNode" => false, + "CharacterData" => false, + "ClipboardEvent" => false, + "ClipboardItem" => false, + "CloseEvent" => false, + "Comment" => false, + "CompositionEvent" => false, + "CompressionStream" => false, + "ConstantSourceNode" => false, + "ConvolverNode" => false, + "CountQueuingStrategy" => false, + "Credential" => false, + "CredentialsContainer" => false, + "Crypto" => false, + "CryptoKey" => false, + "CustomElementRegistry" => false, + "CustomEvent" => false, + "DOMError" => false, + "DOMException" => false, + "DOMImplementation" => false, + "DOMMatrix" => false, + "DOMMatrixReadOnly" => false, + "DOMParser" => false, + "DOMPoint" => false, + "DOMPointReadOnly" => false, + "DOMQuad" => false, + "DOMRect" => false, + "DOMRectList" => false, + "DOMRectReadOnly" => false, + "DOMStringList" => false, + "DOMStringMap" => false, + "DOMTokenList" => false, + "DataTransfer" => false, + "DataTransferItem" => false, + "DataTransferItemList" => false, + "DecompressionStream" => false, + "DelayNode" => false, + "DeviceMotionEvent" => false, + "DeviceOrientationEvent" => false, + "Document" => false, + "DocumentFragment" => false, + "DocumentType" => false, + "DragEvent" => false, + "DynamicsCompressorNode" => false, + "Element" => false, + "ErrorEvent" => false, + "Event" => false, + "EventSource" => false, + "EventTarget" => false, + "File" => false, + "FileList" => false, + "FileReader" => false, + "FocusEvent" => false, + "FontFace" => false, + "FontFaceSetLoadEvent" => false, + "FormData" => false, + "FormDataEvent" => false, + "GainNode" => false, + "Gamepad" => false, + "GamepadButton" => false, + "GamepadEvent" => false, + "HTMLAllCollection" => false, + "HTMLAnchorElement" => false, + "HTMLAreaElement" => false, + "HTMLAudioElement" => false, + "HTMLBRElement" => false, + "HTMLBaseElement" => false, + "HTMLBodyElement" => false, + "HTMLButtonElement" => false, + "HTMLCanvasElement" => false, + "HTMLCollection" => false, + "HTMLContentElement" => false, + "HTMLDListElement" => false, + "HTMLDataElement" => false, + "HTMLDataListElement" => false, + "HTMLDetailsElement" => false, + "HTMLDialogElement" => false, + "HTMLDirectoryElement" => false, + "HTMLDivElement" => false, + "HTMLDocument" => false, + "HTMLElement" => false, + "HTMLEmbedElement" => false, + "HTMLFieldSetElement" => false, + "HTMLFontElement" => false, + "HTMLFormControlsCollection" => false, + "HTMLFormElement" => false, + "HTMLFrameElement" => false, + "HTMLFrameSetElement" => false, + "HTMLHRElement" => false, + "HTMLHeadElement" => false, + "HTMLHeadingElement" => false, + "HTMLHtmlElement" => false, + "HTMLIFrameElement" => false, + "HTMLImageElement" => false, + "HTMLInputElement" => false, + "HTMLLIElement" => false, + "HTMLLabelElement" => false, + "HTMLLegendElement" => false, + "HTMLLinkElement" => false, + "HTMLMapElement" => false, + "HTMLMarqueeElement" => false, + "HTMLMediaElement" => false, + "HTMLMenuElement" => false, + "HTMLMetaElement" => false, + "HTMLMeterElement" => false, + "HTMLModElement" => false, + "HTMLOListElement" => false, + "HTMLObjectElement" => false, + "HTMLOptGroupElement" => false, + "HTMLOptionElement" => false, + "HTMLOptionsCollection" => false, + "HTMLOutputElement" => false, + "HTMLParagraphElement" => false, + "HTMLParamElement" => false, + "HTMLPictureElement" => false, + "HTMLPreElement" => false, + "HTMLProgressElement" => false, + "HTMLQuoteElement" => false, + "HTMLScriptElement" => false, + "HTMLSelectElement" => false, + "HTMLShadowElement" => false, + "HTMLSlotElement" => false, + "HTMLSourceElement" => false, + "HTMLSpanElement" => false, + "HTMLStyleElement" => false, + "HTMLTableCaptionElement" => false, + "HTMLTableCellElement" => false, + "HTMLTableColElement" => false, + "HTMLTableElement" => false, + "HTMLTableRowElement" => false, + "HTMLTableSectionElement" => false, + "HTMLTemplateElement" => false, + "HTMLTextAreaElement" => false, + "HTMLTimeElement" => false, + "HTMLTitleElement" => false, + "HTMLTrackElement" => false, + "HTMLUListElement" => false, + "HTMLUnknownElement" => false, + "HTMLVideoElement" => false, + "HashChangeEvent" => false, + "Headers" => false, + "History" => false, + "IDBCursor" => false, + "IDBCursorWithValue" => false, + "IDBDatabase" => false, + "IDBFactory" => false, + "IDBIndex" => false, + "IDBKeyRange" => false, + "IDBObjectStore" => false, + "IDBOpenDBRequest" => false, + "IDBRequest" => false, + "IDBTransaction" => false, + "IDBVersionChangeEvent" => false, + "IIRFilterNode" => false, + "IdleDeadline" => false, + "Image" => false, + "ImageBitmap" => false, + "ImageBitmapRenderingContext" => false, + "ImageCapture" => false, + "ImageData" => false, + "InputEvent" => false, + "IntersectionObserver" => false, + "IntersectionObserverEntry" => false, + "Intl" => false, + "KeyboardEvent" => false, + "KeyframeEffect" => false, + "KeyframeEffectReadOnly" => false, + "Location" => false, + "MIDIAccess" => false, + "MIDIConnectionEvent" => false, + "MIDIInput" => false, + "MIDIInputMap" => false, + "MIDIMessageEvent" => false, + "MIDIOutput" => false, + "MIDIOutputMap" => false, + "MIDIPort" => false, + "MediaDeviceInfo" => false, + "MediaDevices" => false, + "MediaElementAudioSourceNode" => false, + "MediaEncryptedEvent" => false, + "MediaError" => false, + "MediaKeyMessageEvent" => false, + "MediaKeySession" => false, + "MediaKeyStatusMap" => false, + "MediaKeySystemAccess" => false, + "MediaList" => false, + "MediaMetadata" => false, + "MediaQueryList" => false, + "MediaQueryListEvent" => false, + "MediaRecorder" => false, + "MediaSettingsRange" => false, + "MediaSource" => false, + "MediaStream" => false, + "MediaStreamAudioDestinationNode" => false, + "MediaStreamAudioSourceNode" => false, + "MediaStreamConstraints" => false, + "MediaStreamEvent" => false, + "MediaStreamTrack" => false, + "MediaStreamTrackEvent" => false, + "MessageChannel" => false, + "MessageEvent" => false, + "MessagePort" => false, + "MimeType" => false, + "MimeTypeArray" => false, + "MouseEvent" => false, + "MutationEvent" => false, + "MutationObserver" => false, + "MutationRecord" => false, + "NamedNodeMap" => false, + "NavigationPreloadManager" => false, + "Navigator" => false, + "NavigatorUAData" => false, + "NetworkInformation" => false, + "Node" => false, + "NodeFilter" => false, + "NodeIterator" => false, + "NodeList" => false, + "Notification" => false, + "OfflineAudioCompletionEvent" => false, + "OfflineAudioContext" => false, + "OffscreenCanvas" => true, + "OffscreenCanvasRenderingContext2D" => false, + "Option" => false, + "OscillatorNode" => false, + "OverconstrainedError" => false, + "PageTransitionEvent" => false, + "PannerNode" => false, + "Path2D" => false, + "PaymentAddress" => false, + "PaymentRequest" => false, + "PaymentRequestUpdateEvent" => false, + "PaymentResponse" => false, + "Performance" => false, + "PerformanceEntry" => false, + "PerformanceLongTaskTiming" => false, + "PerformanceMark" => false, + "PerformanceMeasure" => false, + "PerformanceNavigation" => false, + "PerformanceNavigationTiming" => false, + "PerformanceObserver" => false, + "PerformanceObserverEntryList" => false, + "PerformancePaintTiming" => false, + "PerformanceResourceTiming" => false, + "PerformanceTiming" => false, + "PeriodicWave" => false, + "PermissionStatus" => false, + "Permissions" => false, + "PhotoCapabilities" => false, + "Plugin" => false, + "PluginArray" => false, + "PointerEvent" => false, + "PopStateEvent" => false, + "Presentation" => false, + "PresentationAvailability" => false, + "PresentationConnection" => false, + "PresentationConnectionAvailableEvent" => false, + "PresentationConnectionCloseEvent" => false, + "PresentationConnectionList" => false, + "PresentationReceiver" => false, + "PresentationRequest" => false, + "ProcessingInstruction" => false, + "ProgressEvent" => false, + "PromiseRejectionEvent" => false, + "PushManager" => false, + "PushSubscription" => false, + "PushSubscriptionOptions" => false, + "RTCCertificate" => false, + "RTCDataChannel" => false, + "RTCDataChannelEvent" => false, + "RTCDtlsTransport" => false, + "RTCIceCandidate" => false, + "RTCIceGatherer" => false, + "RTCIceTransport" => false, + "RTCPeerConnection" => false, + "RTCPeerConnectionIceEvent" => false, + "RTCRtpContributingSource" => false, + "RTCRtpReceiver" => false, + "RTCRtpSender" => false, + "RTCSctpTransport" => false, + "RTCSessionDescription" => false, + "RTCStatsReport" => false, + "RTCTrackEvent" => false, + "RadioNodeList" => false, + "Range" => false, + "ReadableByteStreamController" => false, + "ReadableStream" => false, + "ReadableStreamBYOBReader" => false, + "ReadableStreamBYOBRequest" => false, + "ReadableStreamDefaultController" => false, + "ReadableStreamDefaultReader" => false, + "RemotePlayback" => false, + "Request" => false, + "ResizeObserver" => false, + "ResizeObserverEntry" => false, + "Response" => false, + "SVGAElement" => false, + "SVGAngle" => false, + "SVGAnimateElement" => false, + "SVGAnimateMotionElement" => false, + "SVGAnimateTransformElement" => false, + "SVGAnimatedAngle" => false, + "SVGAnimatedBoolean" => false, + "SVGAnimatedEnumeration" => false, + "SVGAnimatedInteger" => false, + "SVGAnimatedLength" => false, + "SVGAnimatedLengthList" => false, + "SVGAnimatedNumber" => false, + "SVGAnimatedNumberList" => false, + "SVGAnimatedPreserveAspectRatio" => false, + "SVGAnimatedRect" => false, + "SVGAnimatedString" => false, + "SVGAnimatedTransformList" => false, + "SVGAnimationElement" => false, + "SVGCircleElement" => false, + "SVGClipPathElement" => false, + "SVGComponentTransferFunctionElement" => false, + "SVGDefsElement" => false, + "SVGDescElement" => false, + "SVGDiscardElement" => false, + "SVGElement" => false, + "SVGEllipseElement" => false, + "SVGFEBlendElement" => false, + "SVGFEColorMatrixElement" => false, + "SVGFEComponentTransferElement" => false, + "SVGFECompositeElement" => false, + "SVGFEConvolveMatrixElement" => false, + "SVGFEDiffuseLightingElement" => false, + "SVGFEDisplacementMapElement" => false, + "SVGFEDistantLightElement" => false, + "SVGFEDropShadowElement" => false, + "SVGFEFloodElement" => false, + "SVGFEFuncAElement" => false, + "SVGFEFuncBElement" => false, + "SVGFEFuncGElement" => false, + "SVGFEFuncRElement" => false, + "SVGFEGaussianBlurElement" => false, + "SVGFEImageElement" => false, + "SVGFEMergeElement" => false, + "SVGFEMergeNodeElement" => false, + "SVGFEMorphologyElement" => false, + "SVGFEOffsetElement" => false, + "SVGFEPointLightElement" => false, + "SVGFESpecularLightingElement" => false, + "SVGFESpotLightElement" => false, + "SVGFETileElement" => false, + "SVGFETurbulenceElement" => false, + "SVGFilterElement" => false, + "SVGForeignObjectElement" => false, + "SVGGElement" => false, + "SVGGeometryElement" => false, + "SVGGradientElement" => false, + "SVGGraphicsElement" => false, + "SVGImageElement" => false, + "SVGLength" => false, + "SVGLengthList" => false, + "SVGLineElement" => false, + "SVGLinearGradientElement" => false, + "SVGMPathElement" => false, + "SVGMarkerElement" => false, + "SVGMaskElement" => false, + "SVGMatrix" => false, + "SVGMetadataElement" => false, + "SVGNumber" => false, + "SVGNumberList" => false, + "SVGPathElement" => false, + "SVGPatternElement" => false, + "SVGPoint" => false, + "SVGPointList" => false, + "SVGPolygonElement" => false, + "SVGPolylineElement" => false, + "SVGPreserveAspectRatio" => false, + "SVGRadialGradientElement" => false, + "SVGRect" => false, + "SVGRectElement" => false, + "SVGSVGElement" => false, + "SVGScriptElement" => false, + "SVGSetElement" => false, + "SVGStopElement" => false, + "SVGStringList" => false, + "SVGStyleElement" => false, + "SVGSwitchElement" => false, + "SVGSymbolElement" => false, + "SVGTSpanElement" => false, + "SVGTextContentElement" => false, + "SVGTextElement" => false, + "SVGTextPathElement" => false, + "SVGTextPositioningElement" => false, + "SVGTitleElement" => false, + "SVGTransform" => false, + "SVGTransformList" => false, + "SVGUnitTypes" => false, + "SVGUseElement" => false, + "SVGViewElement" => false, + "Screen" => false, + "ScreenOrientation" => false, + "ScriptProcessorNode" => false, + "SecurityPolicyViolationEvent" => false, + "Selection" => false, + "ServiceWorker" => false, + "ServiceWorkerContainer" => false, + "ServiceWorkerRegistration" => false, + "ShadowRoot" => false, + "SharedWorker" => false, + "SourceBuffer" => false, + "SourceBufferList" => false, + "SpeechSynthesisEvent" => false, + "SpeechSynthesisUtterance" => false, + "StaticRange" => false, + "StereoPannerNode" => false, + "Storage" => false, + "StorageEvent" => false, + "StorageManager" => false, + "StyleSheet" => false, + "StyleSheetList" => false, + "SubmitEvent" => false, + "SubtleCrypto" => false, + "TaskAttributionTiming" => false, + "Text" => false, + "TextDecoder" => false, + "TextDecoderStream" => false, + "TextEncoder" => false, + "TextEncoderStream" => false, + "TextEvent" => false, + "TextMetrics" => false, + "TextTrack" => false, + "TextTrackCue" => false, + "TextTrackCueList" => false, + "TextTrackList" => false, + "TimeRanges" => false, + "ToggleEvent" => false, + "Touch" => false, + "TouchEvent" => false, + "TouchList" => false, + "TrackEvent" => false, + "TransformStream" => false, + "TransformStreamDefaultController" => false, + "TransitionEvent" => false, + "TreeWalker" => false, + "UIEvent" => false, + "URL" => false, + "URLSearchParams" => false, + "VTTCue" => false, + "ValidityState" => false, + "VisualViewport" => false, + "WaveShaperNode" => false, + "WebAssembly" => false, + "WebGL2RenderingContext" => false, + "WebGLActiveInfo" => false, + "WebGLBuffer" => false, + "WebGLContextEvent" => false, + "WebGLFramebuffer" => false, + "WebGLProgram" => false, + "WebGLQuery" => false, + "WebGLRenderbuffer" => false, + "WebGLRenderingContext" => false, + "WebGLSampler" => false, + "WebGLShader" => false, + "WebGLShaderPrecisionFormat" => false, + "WebGLSync" => false, + "WebGLTexture" => false, + "WebGLTransformFeedback" => false, + "WebGLUniformLocation" => false, + "WebGLVertexArrayObject" => false, + "WebSocket" => false, + "WheelEvent" => false, + "Window" => false, + "Worker" => false, + "WritableStream" => false, + "WritableStreamDefaultController" => false, + "WritableStreamDefaultWriter" => false, + "XMLDocument" => false, + "XMLHttpRequest" => false, + "XMLHttpRequestEventTarget" => false, + "XMLHttpRequestUpload" => false, + "XMLSerializer" => false, + "XPathEvaluator" => false, + "XPathExpression" => false, + "XPathResult" => false, + "XRAnchor" => false, + "XRBoundedReferenceSpace" => false, + "XRCPUDepthInformation" => false, + "XRDepthInformation" => false, + "XRFrame" => false, + "XRInputSource" => false, + "XRInputSourceArray" => false, + "XRInputSourceEvent" => false, + "XRInputSourcesChangeEvent" => false, + "XRPose" => false, + "XRReferenceSpace" => false, + "XRReferenceSpaceEvent" => false, + "XRRenderState" => false, + "XRRigidTransform" => false, + "XRSession" => false, + "XRSessionEvent" => false, + "XRSpace" => false, + "XRSystem" => false, + "XRView" => false, + "XRViewerPose" => false, + "XRViewport" => false, + "XRWebGLBinding" => false, + "XRWebGLDepthInformation" => false, + "XRWebGLLayer" => false, + "XSLTProcessor" => false, + "addEventListener" => false, + "alert" => false, + "applicationCache" => false, + "atob" => false, + "blur" => false, + "btoa" => false, + "caches" => false, + "cancelAnimationFrame" => false, + "cancelIdleCallback" => false, + "clearInterval" => false, + "clearTimeout" => false, + "clientInformation" => false, + "close" => false, + "closed" => false, + "confirm" => false, + "console" => false, + "createImageBitmap" => false, + "crypto" => false, + "customElements" => false, + "defaultStatus" => false, + "defaultstatus" => false, + "devicePixelRatio" => false, + "dispatchEvent" => false, + "document" => false, + "event" => false, + "external" => false, + "fetch" => false, + "find" => false, + "focus" => false, + "frameElement" => false, + "frames" => false, + "getComputedStyle" => false, + "getSelection" => false, + "history" => false, + "indexedDB" => false, + "innerHeight" => false, + "innerWidth" => false, + "isSecureContext" => false, + "length" => false, + "localStorage" => false, + "location" => true, + "locationbar" => false, + "matchMedia" => false, + "menubar" => false, + "moveBy" => false, + "moveTo" => false, + "name" => false, + "navigator" => false, + "offscreenBuffering" => false, + "onabort" => true, + "onafterprint" => true, + "onanimationend" => true, + "onanimationiteration" => true, + "onanimationstart" => true, + "onappinstalled" => true, + "onauxclick" => true, + "onbeforeinstallprompt" => true, + "onbeforeprint" => true, + "onbeforeunload" => true, + "onblur" => true, + "oncancel" => true, + "oncanplay" => true, + "oncanplaythrough" => true, + "onchange" => true, + "onclick" => true, + "onclose" => true, + "oncontextmenu" => true, + "oncuechange" => true, + "ondblclick" => true, + "ondevicemotion" => true, + "ondeviceorientation" => true, + "ondeviceorientationabsolute" => true, + "ondrag" => true, + "ondragend" => true, + "ondragenter" => true, + "ondragleave" => true, + "ondragover" => true, + "ondragstart" => true, + "ondrop" => true, + "ondurationchange" => true, + "onemptied" => true, + "onended" => true, + "onerror" => true, + "onfocus" => true, + "ongotpointercapture" => true, + "onhashchange" => true, + "oninput" => true, + "oninvalid" => true, + "onkeydown" => true, + "onkeypress" => true, + "onkeyup" => true, + "onlanguagechange" => true, + "onload" => true, + "onloadeddata" => true, + "onloadedmetadata" => true, + "onloadstart" => true, + "onlostpointercapture" => true, + "onmessage" => true, + "onmessageerror" => true, + "onmousedown" => true, + "onmouseenter" => true, + "onmouseleave" => true, + "onmousemove" => true, + "onmouseout" => true, + "onmouseover" => true, + "onmouseup" => true, + "onmousewheel" => true, + "onoffline" => true, + "ononline" => true, + "onpagehide" => true, + "onpageshow" => true, + "onpause" => true, + "onplay" => true, + "onplaying" => true, + "onpointercancel" => true, + "onpointerdown" => true, + "onpointerenter" => true, + "onpointerleave" => true, + "onpointermove" => true, + "onpointerout" => true, + "onpointerover" => true, + "onpointerup" => true, + "onpopstate" => true, + "onprogress" => true, + "onratechange" => true, + "onrejectionhandled" => true, + "onreset" => true, + "onresize" => true, + "onscroll" => true, + "onsearch" => true, + "onseeked" => true, + "onseeking" => true, + "onselect" => true, + "onstalled" => true, + "onstorage" => true, + "onsubmit" => true, + "onsuspend" => true, + "ontimeupdate" => true, + "ontoggle" => true, + "ontransitionend" => true, + "onunhandledrejection" => true, + "onunload" => true, + "onvolumechange" => true, + "onwaiting" => true, + "onwheel" => true, + "open" => false, + "openDatabase" => false, + "opener" => false, + "origin" => false, + "outerHeight" => false, + "outerWidth" => false, + "pageXOffset" => false, + "pageYOffset" => false, + "parent" => false, + "performance" => false, + "personalbar" => false, + "postMessage" => false, + "print" => false, + "prompt" => false, + "queueMicrotask" => false, + "registerProcessor" => false, + "removeEventListener" => false, + "reportError" => false, + "requestAnimationFrame" => false, + "requestIdleCallback" => false, + "resizeBy" => false, + "resizeTo" => false, + "screen" => false, + "screenLeft" => false, + "screenTop" => false, + "screenX" => false, + "screenY" => false, + "scroll" => false, + "scrollBy" => false, + "scrollTo" => false, + "scrollX" => false, + "scrollY" => false, + "scrollbars" => false, + "self" => false, + "sessionStorage" => false, + "setInterval" => false, + "setTimeout" => false, + "speechSynthesis" => false, + "status" => false, + "statusbar" => false, + "stop" => false, + "structuredClone" => false, + "styleMedia" => false, + "toolbar" => false, + "top" => false, + "visualViewport" => false, + "window" => false, + }, + "node" => phf_map! { + "AbortController" => false, + "AbortSignal" => false, + "Blob" => false, + "BroadcastChannel" => false, + "Buffer" => false, + "ByteLengthQueuingStrategy" => false, + "CompressionStream" => false, + "CountQueuingStrategy" => false, + "Crypto" => false, + "CryptoKey" => false, + "CustomEvent" => false, + "DOMException" => false, + "DecompressionStream" => false, + "Event" => false, + "EventTarget" => false, + "File" => false, + "FormData" => false, + "Headers" => false, + "Intl" => false, + "MessageChannel" => false, + "MessageEvent" => false, + "MessagePort" => false, + "PerformanceEntry" => false, + "PerformanceMark" => false, + "PerformanceMeasure" => false, + "PerformanceObserver" => false, + "PerformanceObserverEntryList" => false, + "PerformanceResourceTiming" => false, + "ReadableByteStreamController" => false, + "ReadableStream" => false, + "ReadableStreamBYOBReader" => false, + "ReadableStreamBYOBRequest" => false, + "ReadableStreamDefaultController" => false, + "ReadableStreamDefaultReader" => false, + "Request" => false, + "Response" => false, + "SubtleCrypto" => false, + "TextDecoder" => false, + "TextDecoderStream" => false, + "TextEncoder" => false, + "TextEncoderStream" => false, + "TransformStream" => false, + "TransformStreamDefaultController" => false, + "URL" => false, + "URLSearchParams" => false, + "WebAssembly" => false, + "WritableStream" => false, + "WritableStreamDefaultController" => false, + "WritableStreamDefaultWriter" => false, + "__dirname" => false, + "__filename" => false, + "atob" => false, + "btoa" => false, + "clearImmediate" => false, + "clearInterval" => false, + "clearTimeout" => false, + "console" => false, + "crypto" => false, + "exports" => true, + "fetch" => false, + "global" => false, + "module" => false, + "performance" => false, + "process" => false, + "queueMicrotask" => false, + "require" => false, + "setImmediate" => false, + "setInterval" => false, + "setTimeout" => false, + "structuredClone" => false, + }, + "shared-node-browser" => phf_map! { + "AbortController" => false, + "AbortSignal" => false, + "Blob" => false, + "BroadcastChannel" => false, + "ByteLengthQueuingStrategy" => false, + "CompressionStream" => false, + "CountQueuingStrategy" => false, + "Crypto" => false, + "CryptoKey" => false, + "CustomEvent" => false, + "DOMException" => false, + "DecompressionStream" => false, + "Event" => false, + "EventTarget" => false, + "File" => false, + "FormData" => false, + "Headers" => false, + "Intl" => false, + "MessageChannel" => false, + "MessageEvent" => false, + "MessagePort" => false, + "PerformanceEntry" => false, + "PerformanceMark" => false, + "PerformanceMeasure" => false, + "PerformanceObserver" => false, + "PerformanceObserverEntryList" => false, + "PerformanceResourceTiming" => false, + "ReadableByteStreamController" => false, + "ReadableStream" => false, + "ReadableStreamBYOBReader" => false, + "ReadableStreamBYOBRequest" => false, + "ReadableStreamDefaultController" => false, + "ReadableStreamDefaultReader" => false, + "Request" => false, + "Response" => false, + "SubtleCrypto" => false, + "TextDecoder" => false, + "TextDecoderStream" => false, + "TextEncoder" => false, + "TextEncoderStream" => false, + "TransformStream" => false, + "TransformStreamDefaultController" => false, + "URL" => false, + "URLSearchParams" => false, + "WebAssembly" => false, + "WritableStream" => false, + "WritableStreamDefaultController" => false, + "WritableStreamDefaultWriter" => false, + "atob" => false, + "btoa" => false, + "clearInterval" => false, + "clearTimeout" => false, + "console" => false, + "crypto" => false, + "fetch" => false, + "performance" => false, + "queueMicrotask" => false, + "setInterval" => false, + "setTimeout" => false, + "structuredClone" => false, + }, + "worker" => phf_map! { + "Blob" => false, + "BroadcastChannel" => false, + "ByteLengthQueuingStrategy" => false, + "Cache" => false, + "CompressionStream" => false, + "CountQueuingStrategy" => false, + "Crypto" => false, + "CryptoKey" => false, + "CustomEvent" => false, + "DecompressionStream" => false, + "ErrorEvent" => false, + "Event" => false, + "File" => false, + "FileReaderSync" => false, + "FormData" => false, + "Headers" => false, + "IDBCursor" => false, + "IDBCursorWithValue" => false, + "IDBDatabase" => false, + "IDBFactory" => false, + "IDBIndex" => false, + "IDBKeyRange" => false, + "IDBObjectStore" => false, + "IDBOpenDBRequest" => false, + "IDBRequest" => false, + "IDBTransaction" => false, + "IDBVersionChangeEvent" => false, + "ImageData" => false, + "MessageChannel" => false, + "MessageEvent" => false, + "MessagePort" => false, + "Notification" => false, + "Performance" => false, + "PerformanceEntry" => false, + "PerformanceMark" => false, + "PerformanceMeasure" => false, + "PerformanceNavigation" => false, + "PerformanceObserver" => false, + "PerformanceObserverEntryList" => false, + "PerformanceResourceTiming" => false, + "PerformanceTiming" => false, + "Promise" => false, + "ReadableByteStreamController" => false, + "ReadableStream" => false, + "ReadableStreamBYOBReader" => false, + "ReadableStreamBYOBRequest" => false, + "ReadableStreamDefaultController" => false, + "ReadableStreamDefaultReader" => false, + "Request" => false, + "Response" => false, + "ServiceWorkerRegistration" => false, + "SubtleCrypto" => false, + "TextDecoder" => false, + "TextDecoderStream" => false, + "TextEncoder" => false, + "TextEncoderStream" => false, + "TransformStream" => false, + "TransformStreamDefaultController" => false, + "URL" => false, + "URLSearchParams" => false, + "WebAssembly" => false, + "WebSocket" => false, + "Worker" => false, + "WorkerGlobalScope" => false, + "WritableStream" => false, + "WritableStreamDefaultController" => false, + "WritableStreamDefaultWriter" => false, + "XMLHttpRequest" => false, + "addEventListener" => false, + "applicationCache" => false, + "atob" => false, + "btoa" => false, + "caches" => false, + "clearInterval" => false, + "clearTimeout" => false, + "close" => true, + "console" => false, + "crypto" => false, + "fetch" => false, + "importScripts" => true, + "indexedDB" => false, + "location" => false, + "name" => false, + "navigator" => false, + "onclose" => true, + "onconnect" => true, + "onerror" => true, + "onlanguagechange" => true, + "onmessage" => true, + "onoffline" => true, + "ononline" => true, + "onrejectionhandled" => true, + "onunhandledrejection" => true, + "performance" => false, + "postMessage" => true, + "queueMicrotask" => false, + "removeEventListener" => false, + "reportError" => false, + "self" => true, + "setInterval" => false, + "setTimeout" => false, + }, + "serviceworker" => phf_map! { + "Blob" => false, + "BroadcastChannel" => false, + "ByteLengthQueuingStrategy" => false, + "Cache" => false, + "CacheStorage" => false, + "Client" => false, + "Clients" => false, + "CompressionStream" => false, + "CountQueuingStrategy" => false, + "Crypto" => false, + "CryptoKey" => false, + "CustomEvent" => false, + "DecompressionStream" => false, + "ErrorEvent" => false, + "Event" => false, + "ExtendableEvent" => false, + "ExtendableMessageEvent" => false, + "FetchEvent" => false, + "File" => false, + "FileReaderSync" => false, + "FormData" => false, + "Headers" => false, + "IDBCursor" => false, + "IDBCursorWithValue" => false, + "IDBDatabase" => false, + "IDBFactory" => false, + "IDBIndex" => false, + "IDBKeyRange" => false, + "IDBObjectStore" => false, + "IDBOpenDBRequest" => false, + "IDBRequest" => false, + "IDBTransaction" => false, + "IDBVersionChangeEvent" => false, + "ImageData" => false, + "MessageChannel" => false, + "MessageEvent" => false, + "MessagePort" => false, + "Notification" => false, + "Performance" => false, + "PerformanceEntry" => false, + "PerformanceMark" => false, + "PerformanceMeasure" => false, + "PerformanceNavigation" => false, + "PerformanceObserver" => false, + "PerformanceObserverEntryList" => false, + "PerformanceResourceTiming" => false, + "PerformanceTiming" => false, + "Promise" => false, + "ReadableByteStreamController" => false, + "ReadableStream" => false, + "ReadableStreamBYOBReader" => false, + "ReadableStreamBYOBRequest" => false, + "ReadableStreamDefaultController" => false, + "ReadableStreamDefaultReader" => false, + "Request" => false, + "Response" => false, + "ServiceWorker" => false, + "ServiceWorkerContainer" => false, + "ServiceWorkerGlobalScope" => false, + "ServiceWorkerMessageEvent" => false, + "ServiceWorkerRegistration" => false, + "SubtleCrypto" => false, + "TextDecoder" => false, + "TextDecoderStream" => false, + "TextEncoder" => false, + "TextEncoderStream" => false, + "TransformStream" => false, + "TransformStreamDefaultController" => false, + "URL" => false, + "URLSearchParams" => false, + "WebAssembly" => false, + "WebSocket" => false, + "WindowClient" => false, + "Worker" => false, + "WorkerGlobalScope" => false, + "WritableStream" => false, + "WritableStreamDefaultController" => false, + "WritableStreamDefaultWriter" => false, + "XMLHttpRequest" => false, + "addEventListener" => false, + "applicationCache" => false, + "atob" => false, + "btoa" => false, + "caches" => false, + "clearInterval" => false, + "clearTimeout" => false, + "clients" => false, + "close" => true, + "console" => false, + "crypto" => false, + "fetch" => false, + "importScripts" => false, + "indexedDB" => false, + "location" => false, + "name" => false, + "navigator" => false, + "onclose" => true, + "onconnect" => true, + "onerror" => true, + "onfetch" => true, + "oninstall" => true, + "onlanguagechange" => true, + "onmessage" => true, + "onmessageerror" => true, + "onnotificationclick" => true, + "onnotificationclose" => true, + "onoffline" => true, + "ononline" => true, + "onpush" => true, + "onpushsubscriptionchange" => true, + "onrejectionhandled" => true, + "onsync" => true, + "onunhandledrejection" => true, + "performance" => false, + "postMessage" => true, + "queueMicrotask" => false, + "registration" => false, + "removeEventListener" => false, + "self" => false, + "setInterval" => false, + "setTimeout" => false, + "skipWaiting" => false, + }, + "commonjs" => phf_map! { + "exports" => true, + "global" => false, + "module" => false, + "require" => false, + }, + "amd" => phf_map! { + "define" => false, + "require" => false, + }, + "mocha" => phf_map! { + "after" => false, + "afterEach" => false, + "before" => false, + "beforeEach" => false, + "context" => false, + "describe" => false, + "it" => false, + "mocha" => false, + "run" => false, + "setup" => false, + "specify" => false, + "suite" => false, + "suiteSetup" => false, + "suiteTeardown" => false, + "teardown" => false, + "test" => false, + "xcontext" => false, + "xdescribe" => false, + "xit" => false, + "xspecify" => false, + }, + "jasmine" => phf_map! { + "afterAll" => false, + "afterEach" => false, + "beforeAll" => false, + "beforeEach" => false, + "describe" => false, + "expect" => false, + "expectAsync" => false, + "fail" => false, + "fdescribe" => false, + "fit" => false, + "it" => false, + "jasmine" => false, + "pending" => false, + "runs" => false, + "spyOn" => false, + "spyOnAllFunctions" => false, + "spyOnProperty" => false, + "waits" => false, + "waitsFor" => false, + "xdescribe" => false, + "xit" => false, + }, + "jest" => phf_map! { + "afterAll" => false, + "afterEach" => false, + "beforeAll" => false, + "beforeEach" => false, + "describe" => false, + "expect" => false, + "fdescribe" => false, + "fit" => false, + "it" => false, + "jest" => false, + "pit" => false, + "require" => false, + "test" => false, + "xdescribe" => false, + "xit" => false, + "xtest" => false, + }, + "phantomjs" => phf_map! { + "WebPage" => true, + "console" => true, + "exports" => true, + "phantom" => true, + "require" => true, + }, + "jquery" => phf_map! { + "$" => false, + "jQuery" => false, + }, + "qunit" => phf_map! { + "QUnit" => false, + "asyncTest" => false, + "deepEqual" => false, + "equal" => false, + "expect" => false, + "module" => false, + "notDeepEqual" => false, + "notEqual" => false, + "notOk" => false, + "notPropEqual" => false, + "notStrictEqual" => false, + "ok" => false, + "propEqual" => false, + "raises" => false, + "start" => false, + "stop" => false, + "strictEqual" => false, + "test" => false, + "throws" => false, + }, + "prototypejs" => phf_map! { + "$" => false, + "$$" => false, + "$A" => false, + "$F" => false, + "$H" => false, + "$R" => false, + "$break" => false, + "$continue" => false, + "$w" => false, + "Abstract" => false, + "Ajax" => false, + "Autocompleter" => false, + "Builder" => false, + "Class" => false, + "Control" => false, + "Draggable" => false, + "Draggables" => false, + "Droppables" => false, + "Effect" => false, + "Element" => false, + "Enumerable" => false, + "Event" => false, + "Field" => false, + "Form" => false, + "Hash" => false, + "Insertion" => false, + "ObjectRange" => false, + "PeriodicalExecuter" => false, + "Position" => false, + "Prototype" => false, + "Scriptaculous" => false, + "Selector" => false, + "Sortable" => false, + "SortableObserver" => false, + "Sound" => false, + "Template" => false, + "Toggle" => false, + "Try" => false, + }, + "shelljs" => phf_map! { + "cat" => false, + "cd" => false, + "chmod" => false, + "config" => false, + "cp" => false, + "dirs" => false, + "echo" => false, + "env" => false, + "error" => false, + "exec" => false, + "exit" => false, + "find" => false, + "grep" => false, + "ln" => false, + "ls" => false, + "mkdir" => false, + "mv" => false, + "popd" => false, + "pushd" => false, + "pwd" => false, + "rm" => false, + "sed" => false, + "set" => false, + "target" => false, + "tempdir" => false, + "test" => false, + "touch" => false, + "which" => false, + }, + "meteor" => phf_map! { + "$" => false, + "Accounts" => false, + "AccountsClient" => false, + "AccountsCommon" => false, + "AccountsServer" => false, + "App" => false, + "Assets" => false, + "Blaze" => false, + "Cordova" => false, + "DDP" => false, + "DDPRateLimiter" => false, + "DDPServer" => false, + "Deps" => false, + "EJSON" => false, + "Email" => false, + "HTTP" => false, + "Log" => false, + "Match" => false, + "Meteor" => false, + "Mongo" => false, + "MongoInternals" => false, + "Npm" => false, + "Package" => false, + "Plugin" => false, + "Random" => false, + "ReactiveDict" => false, + "ReactiveVar" => false, + "Router" => false, + "ServiceConfiguration" => false, + "Session" => false, + "Spacebars" => false, + "Template" => false, + "Tinytest" => false, + "Tracker" => false, + "UI" => false, + "Utils" => false, + "WebApp" => false, + "WebAppInternals" => false, + "check" => false, + "process" => false, + "share" => false, + }, + "mongo" => phf_map! { + "BulkWriteResult" => false, + "ISODate" => false, + "Mongo" => false, + "NumberInt" => false, + "NumberLong" => false, + "ObjectId" => false, + "PlanCache" => false, + "UUID" => false, + "WriteResult" => false, + "_isWindows" => false, + "_rand" => false, + "cat" => false, + "cd" => false, + "connect" => false, + "db" => false, + "getHostName" => false, + "getMemInfo" => false, + "hostname" => false, + "listFiles" => false, + "load" => false, + "ls" => false, + "md5sumFile" => false, + "mkdir" => false, + "print" => false, + "printjson" => false, + "pwd" => false, + "quit" => false, + "removeFile" => false, + "rs" => false, + "sh" => false, + "version" => false, + }, + "protractor" => phf_map! { + "$" => false, + "$$" => false, + "By" => false, + "DartObject" => false, + "browser" => false, + "by" => false, + "element" => false, + "protractor" => false, + }, + "applescript" => phf_map! { + "$" => false, + "Application" => false, + "Automation" => false, + "Library" => false, + "ObjC" => false, + "ObjectSpecifier" => false, + "Path" => false, + "Progress" => false, + "Ref" => false, + "console" => false, + "delay" => false, + }, + "nashorn" => phf_map! { + "JSAdapter" => false, + "Java" => false, + "JavaImporter" => false, + "Packages" => false, + "__DIR__" => false, + "__FILE__" => false, + "__LINE__" => false, + "com" => false, + "edu" => false, + "exit" => false, + "java" => false, + "javafx" => false, + "javax" => false, + "load" => false, + "loadWithNewGlobal" => false, + "org" => false, + "print" => false, + "quit" => false, + }, + "atomtest" => phf_map! { + "advanceClock" => false, + "atom" => false, + "fakeClearInterval" => false, + "fakeClearTimeout" => false, + "fakeSetInterval" => false, + "fakeSetTimeout" => false, + "resetTimeouts" => false, + "waitsForPromise" => false, + }, + "embertest" => phf_map! { + "andThen" => false, + "click" => false, + "currentPath" => false, + "currentRouteName" => false, + "currentURL" => false, + "fillIn" => false, + "find" => false, + "findAll" => false, + "findWithAssert" => false, + "keyEvent" => false, + "pauseTest" => false, + "resumeTest" => false, + "triggerEvent" => false, + "visit" => false, + "wait" => false, + }, + "webextensions" => phf_map! { + "browser" => false, + "chrome" => false, + "opr" => false, + }, + "greasemonkey" => phf_map! { + "GM" => false, + "GM_addElement" => false, + "GM_addStyle" => false, + "GM_addValueChangeListener" => false, + "GM_deleteValue" => false, + "GM_download" => false, + "GM_getResourceText" => false, + "GM_getResourceURL" => false, + "GM_getTab" => false, + "GM_getTabs" => false, + "GM_getValue" => false, + "GM_info" => false, + "GM_listValues" => false, + "GM_log" => false, + "GM_notification" => false, + "GM_openInTab" => false, + "GM_registerMenuCommand" => false, + "GM_removeValueChangeListener" => false, + "GM_saveTab" => false, + "GM_setClipboard" => false, + "GM_setValue" => false, + "GM_unregisterMenuCommand" => false, + "GM_xmlhttpRequest" => false, + "cloneInto" => false, + "createObjectIn" => false, + "exportFunction" => false, + "unsafeWindow" => false, + }, +}; diff --git a/crates/oxc_linter/src/lib.rs b/crates/oxc_linter/src/lib.rs index 2194d0d2e..d0c568d98 100644 --- a/crates/oxc_linter/src/lib.rs +++ b/crates/oxc_linter/src/lib.rs @@ -8,8 +8,10 @@ mod ast_util; mod config; mod context; mod disable_directives; +mod env; mod fixer; mod globals; +mod javascript_globals; mod options; pub mod partial_loader; pub mod rule; @@ -25,6 +27,7 @@ use oxc_diagnostics::Report; pub use crate::{ context::LintContext, + env::Env, fixer::Fix, fixer::{FixResult, Fixer, Message}, options::{AllowWarnDeny, LintOptions}, @@ -52,6 +55,7 @@ pub struct Linter { rules: Vec<(/* rule name */ &'static str, RuleEnum)>, options: LintOptions, settings: Arc, + env: Arc, } impl Default for Linter { @@ -65,9 +69,9 @@ impl Linter { /// /// Returns `Err` if there are any errors parsing the configuration file. pub fn from_options(options: LintOptions) -> Result { - let (rules, settings) = options.derive_rules_and_settings()?; + let (rules, settings, env) = options.derive_rules_and_settings_and_env()?; let rules = rules.into_iter().map(|rule| (rule.name(), rule)).collect(); - Ok(Self { rules, options, settings: Arc::new(settings) }) + Ok(Self { rules, options, settings: Arc::new(settings), env: Arc::new(env) }) } #[must_use] @@ -82,6 +86,12 @@ impl Linter { self } + #[must_use] + pub fn with_envs(mut self, env: Env) -> Self { + self.env = Arc::new(env); + self + } + pub fn options(&self) -> &LintOptions { &self.options } @@ -98,7 +108,8 @@ impl Linter { pub fn run<'a>(&self, ctx: LintContext<'a>) -> Vec> { let semantic = Rc::clone(ctx.semantic()); - let mut ctx = ctx.with_fix(self.options.fix).with_settings(&self.settings); + let mut ctx = + ctx.with_fix(self.options.fix).with_settings(&self.settings).with_env(&self.env); for (rule_name, rule) in &self.rules { ctx.with_rule_name(rule_name); diff --git a/crates/oxc_linter/src/options.rs b/crates/oxc_linter/src/options.rs index ab0a9320c..32ac324e0 100644 --- a/crates/oxc_linter/src/options.rs +++ b/crates/oxc_linter/src/options.rs @@ -9,7 +9,7 @@ use crate::{ ESLintConfig, }, rules::RULES, - LintSettings, RuleCategory, RuleEnum, + Env, LintSettings, RuleCategory, RuleEnum, }; use oxc_diagnostics::Error; use rustc_hash::FxHashSet; @@ -28,6 +28,7 @@ pub struct LintOptions { pub jsx_a11y_plugin: bool, pub nextjs_plugin: bool, pub react_perf_plugin: bool, + pub env: Env, } impl Default for LintOptions { @@ -42,6 +43,7 @@ impl Default for LintOptions { jsx_a11y_plugin: false, nextjs_plugin: false, react_perf_plugin: false, + env: Env::default(), } } } @@ -102,6 +104,12 @@ impl LintOptions { self.react_perf_plugin = yes; self } + + #[must_use] + pub fn with_env(mut self, env: Vec) -> Self { + self.env = Env::new(env); + self + } } #[derive(Debug, Clone, Copy, Eq, PartialEq)] @@ -168,7 +176,9 @@ impl LintOptions { /// # Errors /// /// * Returns `Err` if there are any errors parsing the configuration file. - pub fn derive_rules_and_settings(&self) -> Result<(Vec, LintSettings), Error> { + pub fn derive_rules_and_settings_and_env( + &self, + ) -> Result<(Vec, LintSettings, Env), Error> { let config = self.config_path.as_ref().map(|path| ESLintConfig::new(path)).transpose()?; let mut rules: FxHashSet = FxHashSet::default(); @@ -216,10 +226,13 @@ impl LintOptions { } let mut rules = rules.into_iter().collect::>(); + + let (settings, env) = config.map(ESLintConfig::properties).unwrap_or_default(); + // for stable diagnostics output ordering rules.sort_unstable_by_key(RuleEnum::name); - Ok((rules, config.map(ESLintConfig::settings).unwrap_or_default())) + Ok((rules, settings, env)) } // get final filtered rules by reading `self.jest_plugin` and `self.jsx_a11y_plugin` diff --git a/crates/oxc_linter/src/rules/eslint/no_constant_binary_expression.rs b/crates/oxc_linter/src/rules/eslint/no_constant_binary_expression.rs index 881e0d7fa..16744f4a4 100644 --- a/crates/oxc_linter/src/rules/eslint/no_constant_binary_expression.rs +++ b/crates/oxc_linter/src/rules/eslint/no_constant_binary_expression.rs @@ -11,7 +11,6 @@ use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, LogicalOperator, use crate::{ ast_util::{self, IsConstant}, context::LintContext, - globals::BUILTINS, rule::Rule, AstNode, }; @@ -349,7 +348,7 @@ impl NoConstantBinaryExpression { | Expression::RegExpLiteral(_) => true, Expression::NewExpression(call_expr) => { if let Expression::Identifier(ident) = &call_expr.callee { - return BUILTINS.contains_key(ident.name.as_str()) + return ctx.env_contains_var(ident.name.as_str()) && ctx.semantic().is_reference_to_global_variable(ident); } false diff --git a/crates/oxc_linter/src/rules/eslint/no_global_assign.rs b/crates/oxc_linter/src/rules/eslint/no_global_assign.rs index 629928e81..178e94783 100644 --- a/crates/oxc_linter/src/rules/eslint/no_global_assign.rs +++ b/crates/oxc_linter/src/rules/eslint/no_global_assign.rs @@ -5,7 +5,7 @@ use oxc_diagnostics::{ use oxc_macros::declare_oxc_lint; use oxc_span::{Atom, Span}; -use crate::{context::LintContext, globals::BUILTINS, rule::Rule}; +use crate::{context::LintContext, rule::Rule}; #[derive(Debug, Error, Diagnostic)] #[error("eslint(no-global-assign): Read-only global '{0}' should not be modified.")] @@ -71,7 +71,7 @@ impl Rule for NoGlobalAssign { if reference.is_write() && symbol_table.is_global_reference(reference_id) { let name = reference.name(); - if !self.excludes.contains(name) && BUILTINS.contains_key(name) { + if !self.excludes.contains(name) && ctx.env_contains_var(name) { ctx.diagnostic(NoGlobalAssignDiagnostic(name.clone(), reference.span())); } } diff --git a/crates/oxc_linter/src/rules/eslint/no_redeclare.rs b/crates/oxc_linter/src/rules/eslint/no_redeclare.rs index 1f5f7ef3a..3dabdb453 100644 --- a/crates/oxc_linter/src/rules/eslint/no_redeclare.rs +++ b/crates/oxc_linter/src/rules/eslint/no_redeclare.rs @@ -10,7 +10,7 @@ use oxc_macros::declare_oxc_lint; use oxc_semantic::VariableInfo; use oxc_span::{Atom, Span}; -use crate::{context::LintContext, globals::BUILTINS, rule::Rule}; +use crate::{context::LintContext, rule::Rule}; #[derive(Debug, Error, Diagnostic)] #[error("eslint(no-redeclare): '{0}' is already defined.")] @@ -106,7 +106,7 @@ impl NoRedeclare { variable: &VariableInfo, ident: &BindingIdentifier, ) { - if self.built_in_globals && BUILTINS.get(&ident.name).is_some() { + if self.built_in_globals && ctx.env_contains_var(&ident.name) { ctx.diagnostic(NoRedeclareAsBuiltiInDiagnostic(ident.name.clone(), ident.span)); } else if variable.span != ident.span { ctx.diagnostic(NoRedeclareDiagnostic(ident.name.clone(), ident.span, variable.span)); diff --git a/crates/oxc_linter/src/rules/eslint/no_undef.rs b/crates/oxc_linter/src/rules/eslint/no_undef.rs index 326cff29c..a80113225 100644 --- a/crates/oxc_linter/src/rules/eslint/no_undef.rs +++ b/crates/oxc_linter/src/rules/eslint/no_undef.rs @@ -7,7 +7,7 @@ use oxc_macros::declare_oxc_lint; use oxc_span::{Atom, Span}; use oxc_syntax::operator::UnaryOperator; -use crate::{context::LintContext, globals::BUILTINS, rule::Rule, AstNode}; +use crate::{context::LintContext, rule::Rule, AstNode}; #[derive(Debug, Error, Diagnostic)] #[error("eslint(no-undef): Disallow the use of undeclared variables")] @@ -35,7 +35,7 @@ declare_oxc_lint!( /// var bar = a + 1; /// ``` NoUndef, - nursery // https://github.com/oxc-project/oxc/issues/732 + nursery ); impl Rule for NoUndef { @@ -53,7 +53,7 @@ impl Rule for NoUndef { for reference_id_list in ctx.scopes().root_unresolved_references().values() { for &reference_id in reference_id_list { let reference = symbol_table.get_reference(reference_id); - if BUILTINS.contains_key(reference.name().as_str()) { + if ctx.env_contains_var(reference.name().as_str()) { return; } diff --git a/justfile b/justfile index 80dc85c56..344a7abb6 100755 --- a/justfile +++ b/justfile @@ -74,6 +74,10 @@ codecov: benchmark: cargo benchmark +# Generate the JavaScript global variables. See `tasks/javascript_globals` +javascript-globals: + cargo run -p javascript_globals + # Create a new lint rule by providing the ESLint name. See `tasks/rulegen` new-rule name: cargo run -p rulegen {{name}} diff --git a/tasks/javascript_globals/Cargo.toml b/tasks/javascript_globals/Cargo.toml new file mode 100644 index 000000000..9e16d7c41 --- /dev/null +++ b/tasks/javascript_globals/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "javascript_globals" +version = "0.0.0" +publish = false +edition.workspace = true +license.workspace = true + +[lints] +workspace = true + +[[bin]] +name = "javascript_globals" +test = false + +[dependencies] +oxc_tasks_common = { workspace = true } + +serde = { workspace = true, features = ["derive"] } +lazy_static = { workspace = true } + +handlebars = "5.0.0" diff --git a/tasks/javascript_globals/src/main.rs b/tasks/javascript_globals/src/main.rs new file mode 100644 index 000000000..2db8b138c --- /dev/null +++ b/tasks/javascript_globals/src/main.rs @@ -0,0 +1,167 @@ +use lazy_static::lazy_static; +use oxc_tasks_common::agent; +use serde::Serialize; +use std::collections::HashMap; +mod template; + +#[derive(Serialize, Debug)] +pub struct EnvVar<'a> { + pub name: &'a str, + pub writeable: bool, +} + +#[derive(Serialize, Debug)] +pub struct Env<'a> { + pub name: &'a str, + pub vars: Vec>, +} + +#[derive(Serialize)] +pub struct Context<'a> { + envs: Vec>, +} + +impl<'a> Context<'a> { + fn new(envs: Vec>) -> Self { + Self { envs } + } +} + +fn get_diff( + current: &HashMap, + prev: &HashMap, +) -> HashMap { + let mut retv: HashMap = HashMap::new(); + + for (key, value) in current { + if !prev.contains_key(key) { + retv.insert(key.clone(), *value); + } + } + + retv +} + +lazy_static! { + static ref NEW_GLOBALS_2017: HashMap = { + return HashMap::from([ + (String::from("Atomics"), false), + (String::from("SharedArrayBuffer"), false), + ]); + }; + static ref NEW_GLOBALS_2020: HashMap = { + return HashMap::from([ + (String::from("BigInt"), false), + (String::from("BigInt64Array"), false), + (String::from("BigUint64Array"), false), + (String::from("globalThis"), false), + ]); + }; + static ref NEW_GLOBALS_2021: HashMap = { + return HashMap::from([ + (String::from("AggregateError"), false), + (String::from("FinalizationRegistry"), false), + (String::from("WeakRef"), false), + ]); + }; +} + +fn main() { + // Each global is given a value of true or false. + // A value of true indicates that the variable may be overwritten. + // A value of false indicates that the variable should be considered read-only. + // open globals.json file relative to current file + // let globals: HashMap>; + let globals: HashMap> = match agent() + .get("https://raw.githubusercontent.com/sindresorhus/globals/main/globals.json") + .call() + { + Ok(response) => response.into_json().unwrap(), + Err(e) => { + panic!("Failed to fetch globals.json: {e}"); + } + }; + + // 19 variables such as Promise, Map, ... + let new_globals_2015 = get_diff(&globals["es2015"], &globals["es5"]); + + let new_globals_2015_2017 = { + let mut map = HashMap::new(); + map.extend(new_globals_2015.clone()); + map.extend(NEW_GLOBALS_2017.clone()); + map + }; + + let new_globals_2015_2017_2020 = { + let mut map = new_globals_2015_2017.clone(); + map.extend(NEW_GLOBALS_2020.clone()); + map + }; + + let new_globals_2015_2017_2020_2021 = { + let mut map = new_globals_2015_2017_2020.clone(); + map.extend(NEW_GLOBALS_2021.clone()); + map + }; + + let envs_preset: Vec = [ + // Language + ("builtin", &globals["builtin"]), // oxc uses builtin instead of es5 of ESLint + ("es6", &new_globals_2015), + ("es2015", &new_globals_2015), + ("es2016", &new_globals_2015), + ("es2017", &new_globals_2015_2017), + ("es2018", &new_globals_2015_2017), + ("es2019", &new_globals_2015_2017), + ("es2020", &new_globals_2015_2017_2020), + ("es2021", &new_globals_2015_2017_2020_2021), + ("es2022", &new_globals_2015_2017_2020_2021), + ("es2023", &new_globals_2015_2017_2020_2021), + ("es2024", &new_globals_2015_2017_2020_2021), + // Platforms + ("browser", &globals["browser"]), + ("node", &globals["node"]), + ("shared-node-browser", &globals["shared-node-browser"]), + ("worker", &globals["worker"]), + ("serviceworker", &globals["serviceworker"]), + // Frameworks + ("commonjs", &globals["commonjs"]), + ("amd", &globals["amd"]), + ("mocha", &globals["mocha"]), + ("jasmine", &globals["jasmine"]), + ("jest", &globals["jest"]), + ("phantomjs", &globals["phantomjs"]), + ("jquery", &globals["jquery"]), + ("qunit", &globals["qunit"]), + ("prototypejs", &globals["prototypejs"]), + ("shelljs", &globals["shelljs"]), + ("meteor", &globals["meteor"]), + ("mongo", &globals["mongo"]), + ("protractor", &globals["protractor"]), + ("applescript", &globals["applescript"]), + ("nashorn", &globals["nashorn"]), + ("atomtest", &globals["atomtest"]), + ("embertest", &globals["embertest"]), + ("webextensions", &globals["webextensions"]), + ("greasemonkey", &globals["greasemonkey"]), + ] + .iter() + .map(|(name, vars)| Env { name, vars: to_env_vars(vars) }) + .collect(); + + let context = Context::new(envs_preset); + let template = template::Template::with_context(&context); + if let Err(err) = template.render() { + eprintln!("failed to render environments template: {err}"); + } +} + +fn to_env_vars(env_var_map: &HashMap) -> Vec { + let mut result: Vec = vec![]; + for (key, value) in env_var_map { + result.push(EnvVar { name: key, writeable: *value }); + } + + result.sort_by(|a, b| a.name.cmp(b.name)); + result +} diff --git a/tasks/javascript_globals/src/template.rs b/tasks/javascript_globals/src/template.rs new file mode 100644 index 000000000..656f7f9e9 --- /dev/null +++ b/tasks/javascript_globals/src/template.rs @@ -0,0 +1,38 @@ +use std::{ + fs::File, + io::{Error, Write}, + path::Path, +}; + +use handlebars::Handlebars; + +use crate::Context; + +const ENV_TEMPLATE: &str = include_str!("../template.hbs"); + +pub struct Template<'a> { + context: &'a Context<'a>, + registry: Handlebars<'a>, +} + +impl<'a> Template<'a> { + pub fn with_context(context: &'a Context) -> Self { + let mut registry = handlebars::Handlebars::new(); + registry.register_escape_fn(handlebars::no_escape); + Self { context, registry } + } + + pub fn render(&self) -> Result<(), Error> { + let rendered = self + .registry + .render_template(ENV_TEMPLATE, &handlebars::to_json(self.context)) + .unwrap(); + + let out_path = Path::new("crates/oxc_linter/src/javascript_globals.rs"); + File::create(out_path)?.write_all(rendered.as_bytes())?; + + println!("Saved env file to {out_path:?}"); + + Ok(()) + } +} diff --git a/tasks/javascript_globals/template.hbs b/tasks/javascript_globals/template.hbs new file mode 100644 index 000000000..55463e993 --- /dev/null +++ b/tasks/javascript_globals/template.hbs @@ -0,0 +1,11 @@ +use phf::{phf_map, Map}; + +pub static ENVIRONMENTS: Map<&'static str, Map<&'static str, bool>> = phf_map! { +{{#each envs }} + "{{name}}" => phf_map! { + {{#each vars}} + "{{name}}" => {{writeable}}, + {{/each}} + }, +{{/each}} +};