mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(syntax): export is_reserved_keyword and is_global_object method (#3384)
This commit is contained in:
parent
bb2221e4f4
commit
e2dd8ac8fc
5 changed files with 97 additions and 26 deletions
|
|
@ -4,7 +4,7 @@ use oxc_ast::ast::*;
|
|||
use oxc_span::GetSpan;
|
||||
use oxc_syntax::{
|
||||
identifier::{LS, PS},
|
||||
keyword::is_keyword,
|
||||
keyword::is_reserved_keyword_or_global_object,
|
||||
number::NumberBase,
|
||||
operator::{BinaryOperator, UnaryOperator},
|
||||
precedence::{GetPrecedence, Precedence},
|
||||
|
|
@ -1735,17 +1735,19 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for AssignmentExpression<'a> {
|
|||
|
||||
let identifier_is_keyword = match &self.left {
|
||||
AssignmentTarget::AssignmentTargetIdentifier(target) => {
|
||||
is_keyword(target.name.as_str())
|
||||
is_reserved_keyword_or_global_object(target.name.as_str())
|
||||
}
|
||||
AssignmentTarget::ComputedMemberExpression(expression) => match &expression.object {
|
||||
Expression::Identifier(ident) => is_keyword(ident.name.as_str()),
|
||||
Expression::Identifier(ident) => {
|
||||
is_reserved_keyword_or_global_object(ident.name.as_str())
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
AssignmentTarget::StaticMemberExpression(expression) => {
|
||||
is_keyword(expression.property.name.as_str())
|
||||
is_reserved_keyword_or_global_object(expression.property.name.as_str())
|
||||
}
|
||||
AssignmentTarget::PrivateFieldExpression(expression) => {
|
||||
is_keyword(expression.field.name.as_str())
|
||||
is_reserved_keyword_or_global_object(expression.field.name.as_str())
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,5 +23,5 @@ fn undefined() {
|
|||
test("try {} catch(undefined) {}", "try{}catch(undefined){}");
|
||||
test("for (undefined in {}) {}", "for(undefined in {}){}");
|
||||
test("undefined++", "undefined++;");
|
||||
test("undefined += undefined;", "(undefined+=void 0);");
|
||||
test("undefined += undefined;", "undefined+=void 0;");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,82 @@
|
|||
#[rustfmt::skip]
|
||||
pub fn is_keyword(s: &str) -> bool {
|
||||
matches!(s, "as" | "do" | "if" | "in" | "is" | "of"
|
||||
| "any" | "for" | "get" | "let" | "new" | "out" | "set" | "try" | "var"
|
||||
| "case" | "else" | "enum" | "from" | "meta" | "null" | "this" | "true" | "type" | "void" | "with"
|
||||
| "async" | "await" | "break" | "catch" | "class" | "const" | "false" | "infer" | "keyof" | "never" | "super" | "throw" | "using" | "while" | "yield"
|
||||
| "assert" | "bigint" | "delete" | "export" | "global" | "import" | "module" | "number" | "object" | "public" | "return" | "static" | "string" | "switch" | "symbol" | "target" | "typeof" | "unique"
|
||||
| "asserts" | "boolean" | "declare" | "default" | "extends" | "finally" | "package" | "private" | "require" | "unknown" | "abstract"
|
||||
| "accessor" | "continue" | "debugger" | "function" | "override" | "readonly" | "interface" | "intrinsic" | "namespace" | "protected" | "satisfies" | "undefined"
|
||||
| "implements" | "instanceof"
|
||||
| "constructor"
|
||||
)
|
||||
use phf::{phf_set, Set};
|
||||
|
||||
#[inline]
|
||||
pub fn is_reserved_keyword_or_global_object(s: &str) -> bool {
|
||||
is_reserved_keyword(s) || is_reserved_keyword(s)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_reserved_keyword(s: &str) -> bool {
|
||||
RESERVED_KEYWORDS.contains(s)
|
||||
}
|
||||
|
||||
/// Checks `Infinity`, `NaN`, `globalThis` and `undefined`
|
||||
#[inline]
|
||||
pub fn is_global_object(s: &str) -> bool {
|
||||
GLOBAL_OBJECTS.contains(s)
|
||||
}
|
||||
|
||||
/// Value properties of the global object
|
||||
///
|
||||
/// Reference: <https://tc39.es/ecma262/multipage/global-object.html#sec-value-properties-of-the-global-object>
|
||||
pub const GLOBAL_OBJECTS: Set<&'static str> = phf_set! {
|
||||
"Infinity",
|
||||
"NaN",
|
||||
"globalThis",
|
||||
"undefined",
|
||||
};
|
||||
|
||||
/// All reserved keywords, including keywords that are contextually disallowed as identifiers.
|
||||
///
|
||||
/// Reference: <https://tc39.es/ecma262/#prod-ReservedWord>
|
||||
pub const RESERVED_KEYWORDS: Set<&'static str> = phf_set! {
|
||||
// contextually disallowed as identifiers
|
||||
"let",
|
||||
"static",
|
||||
// future reserved keywords
|
||||
"implements",
|
||||
"interface",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
// reserved word
|
||||
"await",
|
||||
"break",
|
||||
"case",
|
||||
"catch",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"debugger",
|
||||
"default",
|
||||
"delete",
|
||||
"do",
|
||||
"else",
|
||||
"enum",
|
||||
"export",
|
||||
"extends",
|
||||
"false",
|
||||
"finally",
|
||||
"for",
|
||||
"function",
|
||||
"if",
|
||||
"import",
|
||||
"in",
|
||||
"instanceof",
|
||||
"new",
|
||||
"null",
|
||||
"return",
|
||||
"super",
|
||||
"switch",
|
||||
"this",
|
||||
"throw",
|
||||
"true",
|
||||
"try",
|
||||
"typeof",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
"with",
|
||||
"yield",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1132,9 +1132,9 @@ Invalid Character `[`
|
|||
(430:43-430:55) ".prototype =" --> (217:45-217:57) ".prototype ="
|
||||
(430:55-430:59) " new" --> (217:57-217:61) " new"
|
||||
(430:59-431:0) " ComponentDummy();" --> (217:61-218:0) " ComponentDummy();"
|
||||
(431:0-431:23) "\npureComponentPrototype" --> (218:0-218:26) "\n\t\t(pureComponentPrototype"
|
||||
(431:23-431:37) ".constructor =" --> (218:26-218:40) ".constructor ="
|
||||
(431:37-433:0) " PureComponent; // Avoid an extra prototype jump for these methods.\n" --> (218:40-219:0) " PureComponent);"
|
||||
(431:0-431:23) "\npureComponentPrototype" --> (218:0-218:25) "\n\t\tpureComponentPrototype"
|
||||
(431:23-431:37) ".constructor =" --> (218:25-218:39) ".constructor ="
|
||||
(431:37-433:0) " PureComponent; // Avoid an extra prototype jump for these methods.\n" --> (218:39-219:0) " PureComponent;"
|
||||
(433:0-433:8) "\n_assign" --> (219:0-219:10) "\n\t\t_assign"
|
||||
(433:8-433:32) "(pureComponentPrototype," --> (219:10-219:34) "(pureComponentPrototype,"
|
||||
(433:32-433:42) " Component" --> (219:34-219:44) " Component"
|
||||
|
|
@ -5045,9 +5045,9 @@ Invalid Character `[`
|
|||
(2246:58-2246:64) "(null," --> (1464:59-1464:65) "(null,"
|
||||
(2246:64-2246:69) " type" --> (1464:65-1464:70) " type"
|
||||
(2246:69-2247:2) ");\n " --> (1464:70-1465:0) ");"
|
||||
(2247:2-2247:19) " validatedFactory" --> (1465:0-1465:21) "\n\t\t\t(validatedFactory"
|
||||
(2247:19-2247:26) ".type =" --> (1465:21-1465:28) ".type ="
|
||||
(2247:26-2249:2) " type;\n\n " --> (1465:28-1466:3) " type);\n\t\t"
|
||||
(2247:2-2247:19) " validatedFactory" --> (1465:0-1465:20) "\n\t\t\tvalidatedFactory"
|
||||
(2247:19-2247:26) ".type =" --> (1465:20-1465:27) ".type ="
|
||||
(2247:26-2249:2) " type;\n\n " --> (1465:27-1466:3) " type;\n\t\t"
|
||||
(2249:2-2250:4) " {\n " --> (1466:3-1467:0) "\t{"
|
||||
(2250:4-2250:9) " if (" --> (1467:0-1467:10) "\n\t\t\t\tif ( "
|
||||
(2250:9-2250:46) "!didWarnAboutDeprecatedCreateFactory)" --> (1467:10-1467:47) "!didWarnAboutDeprecatedCreateFactory)"
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ test = false
|
|||
|
||||
[dependencies]
|
||||
oxc_linter = { workspace = true }
|
||||
oxc_cli = { path = "../../crates/oxc_cli" }
|
||||
oxc_cli = { path = "../../crates/oxc_cli" }
|
||||
|
||||
bpaf = { workspace = true, features = ["docgen"] }
|
||||
bpaf = { workspace = true, features = ["docgen"] }
|
||||
pico-args = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
schemars = { workspace = true }
|
||||
|
|
|
|||
Loading…
Reference in a new issue