feat: optimize `can_cast` codegen for unions
MODIFY
crates/rslint_parser/src/ast/generated/nodes.rs
crates/rslint_parser/src/ast/generated/nodes.rs
@@ -4919,17 +4919,16 @@ impl From<JsUnknownStatement> for JsAnyStatement {
}
impl AstNode for JsAnyStatement {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
+ matches!(
+ kind,
JS_BLOCK_STATEMENT
| JS_EMPTY_STATEMENT
| JS_EXPRESSION_STATEMENT
| JS_IF_STATEMENT
| JS_DO_WHILE_STATEMENT
| JS_WHILE_STATEMENT
- | FOR_STMT
- | FOR_IN_STMT
- | FOR_OF_STMT
- | JS_CONTINUE_STATEMENT
+ | FOR_STMT | FOR_IN_STMT
+ | FOR_OF_STMT | JS_CONTINUE_STATEMENT
| JS_BREAK_STATEMENT
| JS_RETURN_STATEMENT
| JS_WITH_STATEMENT
@@ -4942,23 +4941,18 @@ impl AstNode for JsAnyStatement {
| JS_FUNCTION_DECLARATION
| JS_CLASS_DECLARATION
| JS_VARIABLE_DECLARATION_STATEMENT
- | TS_ENUM
- | TS_TYPE_ALIAS_DECL
+ | TS_ENUM | TS_TYPE_ALIAS_DECL
| TS_NAMESPACE_DECL
- | TS_MODULE_DECL
- | TS_INTERFACE_DECL
- | IMPORT_DECL
- | EXPORT_NAMED
+ | TS_MODULE_DECL | TS_INTERFACE_DECL
+ | IMPORT_DECL | EXPORT_NAMED
| EXPORT_DEFAULT_DECL
| EXPORT_DEFAULT_EXPR
| EXPORT_WILDCARD
- | EXPORT_DECL
- | TS_IMPORT_EQUALS_DECL
+ | EXPORT_DECL | TS_IMPORT_EQUALS_DECL
| TS_EXPORT_ASSIGNMENT
| TS_NAMESPACE_EXPORT_DECL
- | JS_UNKNOWN_STATEMENT => true,
- _ => false,
- }
+ | JS_UNKNOWN_STATEMENT
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5382,12 +5376,7 @@ impl From<JsDefaultClause> for JsAnySwitchClause {
fn from(node: JsDefaultClause) -> JsAnySwitchClause { JsAnySwitchClause::JsDefaultClause(node) }
}
impl AstNode for JsAnySwitchClause {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- JS_CASE_CLAUSE | JS_DEFAULT_CLAUSE => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, JS_CASE_CLAUSE | JS_DEFAULT_CLAUSE) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
JS_CASE_CLAUSE => JsAnySwitchClause::JsCaseClause(JsCaseClause { syntax }),
@@ -5426,11 +5415,13 @@ impl From<JsUnknownPattern> for Pattern {
}
impl AstNode for Pattern {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- SINGLE_PATTERN | REST_PATTERN | ASSIGN_PATTERN | OBJECT_PATTERN | ARRAY_PATTERN
- | EXPR_PATTERN | JS_UNKNOWN_PATTERN => true,
- _ => false,
- }
+ matches!(
+ kind,
+ SINGLE_PATTERN
+ | REST_PATTERN | ASSIGN_PATTERN
+ | OBJECT_PATTERN | ARRAY_PATTERN
+ | EXPR_PATTERN | JS_UNKNOWN_PATTERN
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5477,11 +5468,15 @@ impl From<JsRegexLiteral> for JsAnyLiteral {
}
impl AstNode for JsAnyLiteral {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- JS_STRING_LITERAL | JS_NUMBER_LITERAL | JS_BIG_INT_LITERAL | JS_BOOLEAN_LITERAL
- | JS_NULL_LITERAL | JS_REGEX_LITERAL => true,
- _ => false,
- }
+ matches!(
+ kind,
+ JS_STRING_LITERAL
+ | JS_NUMBER_LITERAL
+ | JS_BIG_INT_LITERAL
+ | JS_BOOLEAN_LITERAL
+ | JS_NULL_LITERAL
+ | JS_REGEX_LITERAL
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5518,10 +5513,7 @@ impl From<JsIdentifierBinding> for JsAnyArrowFunctionParameters {
}
impl AstNode for JsAnyArrowFunctionParameters {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- JS_PARAMETER_LIST | JS_IDENTIFIER_BINDING => true,
- _ => false,
- }
+ matches!(kind, JS_PARAMETER_LIST | JS_IDENTIFIER_BINDING)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5645,10 +5637,7 @@ impl From<JsComputedMemberName> for JsAnyObjectMemberName {
}
impl AstNode for JsAnyObjectMemberName {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- JS_LITERAL_MEMBER_NAME | JS_COMPUTED_MEMBER_NAME => true,
- _ => false,
- }
+ matches!(kind, JS_LITERAL_MEMBER_NAME | JS_COMPUTED_MEMBER_NAME)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5705,17 +5694,16 @@ impl From<JsUnknownMember> for JsAnyObjectMember {
}
impl AstNode for JsAnyObjectMember {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
+ matches!(
+ kind,
JS_PROPERTY_OBJECT_MEMBER
| JS_METHOD_OBJECT_MEMBER
| JS_GETTER_OBJECT_MEMBER
| JS_SETTER_OBJECT_MEMBER
| INITIALIZED_PROP
| JS_SHORTHAND_PROPERTY_OBJECT_MEMBER
- | JS_SPREAD
- | JS_UNKNOWN_MEMBER => true,
- _ => false,
- }
+ | JS_SPREAD | JS_UNKNOWN_MEMBER
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5776,15 +5764,13 @@ impl From<JsUnknownBinding> for PropName {
}
impl AstNode for PropName {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
+ matches!(
+ kind,
COMPUTED_PROPERTY_NAME
| JS_STRING_LITERAL
| JS_NUMBER_LITERAL
- | IDENT
- | NAME
- | JS_UNKNOWN_BINDING => true,
- _ => false,
- }
+ | IDENT | NAME | JS_UNKNOWN_BINDING
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5849,7 +5835,8 @@ impl From<JsUnknownMember> for JsAnyClassMember {
}
impl AstNode for JsAnyClassMember {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
+ matches!(
+ kind,
JS_CONSTRUCTOR_CLASS_MEMBER
| JS_PROPERTY_CLASS_MEMBER
| JS_METHOD_CLASS_MEMBER
@@ -5857,9 +5844,8 @@ impl AstNode for JsAnyClassMember {
| JS_SETTER_CLASS_MEMBER
| JS_EMPTY_CLASS_MEMBER
| TS_INDEX_SIGNATURE
- | JS_UNKNOWN_MEMBER => true,
- _ => false,
- }
+ | JS_UNKNOWN_MEMBER
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5917,10 +5903,10 @@ impl From<JsPrivateClassMemberName> for JsAnyClassMemberName {
}
impl AstNode for JsAnyClassMemberName {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- JS_LITERAL_MEMBER_NAME | JS_COMPUTED_MEMBER_NAME | JS_PRIVATE_CLASS_MEMBER_NAME => true,
- _ => false,
- }
+ matches!(
+ kind,
+ JS_LITERAL_MEMBER_NAME | JS_COMPUTED_MEMBER_NAME | JS_PRIVATE_CLASS_MEMBER_NAME
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -5998,11 +5984,10 @@ impl From<JsUnknownPattern> for ObjectPatternProp {
}
impl AstNode for ObjectPatternProp {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- ASSIGN_PATTERN | KEY_VALUE_PATTERN | REST_PATTERN | SINGLE_PATTERN
- | JS_UNKNOWN_PATTERN => true,
- _ => false,
- }
+ matches!(
+ kind,
+ ASSIGN_PATTERN | KEY_VALUE_PATTERN | REST_PATTERN | SINGLE_PATTERN | JS_UNKNOWN_PATTERN
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -6120,15 +6105,27 @@ impl From<TsInfer> for TsType {
}
impl AstNode for TsType {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- TS_ANY | TS_UNKNOWN | TS_NUMBER | TS_OBJECT | TS_BOOLEAN | TS_BIGINT | TS_STRING
- | TS_SYMBOL | TS_VOID | TS_UNDEFINED | TS_NULL | TS_NEVER | TS_THIS | TS_LITERAL
- | TS_PREDICATE | TS_TUPLE | TS_PAREN | TS_TYPE_REF | TS_TEMPLATE | TS_MAPPED_TYPE
- | TS_IMPORT | TS_ARRAY | TS_INDEXED_ARRAY | TS_TYPE_OPERATOR | TS_INTERSECTION
- | TS_UNION | TS_FN_TYPE | TS_CONSTRUCTOR_TYPE | TS_CONDITIONAL_TYPE
- | TS_OBJECT_TYPE | TS_INFER => true,
- _ => false,
- }
+ matches!(
+ kind,
+ TS_ANY
+ | TS_UNKNOWN | TS_NUMBER
+ | TS_OBJECT | TS_BOOLEAN
+ | TS_BIGINT | TS_STRING
+ | TS_SYMBOL | TS_VOID
+ | TS_UNDEFINED | TS_NULL
+ | TS_NEVER | TS_THIS
+ | TS_LITERAL | TS_PREDICATE
+ | TS_TUPLE | TS_PAREN
+ | TS_TYPE_REF | TS_TEMPLATE
+ | TS_MAPPED_TYPE | TS_IMPORT
+ | TS_ARRAY | TS_INDEXED_ARRAY
+ | TS_TYPE_OPERATOR
+ | TS_INTERSECTION
+ | TS_UNION | TS_FN_TYPE
+ | TS_CONSTRUCTOR_TYPE
+ | TS_CONDITIONAL_TYPE
+ | TS_OBJECT_TYPE | TS_INFER
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -6219,10 +6216,10 @@ impl From<ImportStringSpecifier> for ImportClause {
}
impl AstNode for ImportClause {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- WILDCARD_IMPORT | NAMED_IMPORTS | NAME | IMPORT_STRING_SPECIFIER => true,
- _ => false,
- }
+ matches!(
+ kind,
+ WILDCARD_IMPORT | NAMED_IMPORTS | NAME | IMPORT_STRING_SPECIFIER
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -6253,10 +6250,7 @@ impl From<JsClassDeclaration> for DefaultDecl {
}
impl AstNode for DefaultDecl {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- JS_FUNCTION_DECLARATION | JS_CLASS_DECLARATION => true,
- _ => false,
- }
+ matches!(kind, JS_FUNCTION_DECLARATION | JS_CLASS_DECLARATION)
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -6315,17 +6309,15 @@ impl From<TsInterfaceDecl> for JsAnyExportDeclaration {
}
impl AstNode for JsAnyExportDeclaration {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
+ matches!(
+ kind,
JS_FUNCTION_DECLARATION
| JS_CLASS_DECLARATION
| JS_VARIABLE_DECLARATION_STATEMENT
- | TS_ENUM
- | TS_TYPE_ALIAS_DECL
+ | TS_ENUM | TS_TYPE_ALIAS_DECL
| TS_NAMESPACE_DECL
- | TS_MODULE_DECL
- | TS_INTERFACE_DECL => true,
- _ => false,
- }
+ | TS_MODULE_DECL | TS_INTERFACE_DECL
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -6437,12 +6429,7 @@ impl From<TsQualifiedPath> for TsEntityName {
fn from(node: TsQualifiedPath) -> TsEntityName { TsEntityName::TsQualifiedPath(node) }
}
impl AstNode for TsEntityName {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- TS_TYPE_NAME | TS_QUALIFIED_PATH => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, TS_TYPE_NAME | TS_QUALIFIED_PATH) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
TS_TYPE_NAME => TsEntityName::TsTypeName(TsTypeName { syntax }),
@@ -6465,12 +6452,7 @@ impl From<TsTypeName> for TsThisOrMore {
fn from(node: TsTypeName) -> TsThisOrMore { TsThisOrMore::TsTypeName(node) }
}
impl AstNode for TsThisOrMore {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- TS_THIS | TS_TYPE_NAME => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, TS_THIS | TS_TYPE_NAME) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
TS_THIS => TsThisOrMore::TsThis(TsThis { syntax }),
@@ -6505,14 +6487,14 @@ impl From<TsIndexSignature> for TsTypeElement {
}
impl AstNode for TsTypeElement {
fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
+ matches!(
+ kind,
TS_CALL_SIGNATURE_DECL
| TS_CONSTRUCT_SIGNATURE_DECL
| TS_PROPERTY_SIGNATURE
| TS_METHOD_SIGNATURE
- | TS_INDEX_SIGNATURE => true,
- _ => false,
- }
+ | TS_INDEX_SIGNATURE
+ )
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
@@ -6548,12 +6530,7 @@ impl From<TsNamespaceDecl> for TsNamespaceBody {
fn from(node: TsNamespaceDecl) -> TsNamespaceBody { TsNamespaceBody::TsNamespaceDecl(node) }
}
impl AstNode for TsNamespaceBody {
- fn can_cast(kind: SyntaxKind) -> bool {
- match kind {
- TS_MODULE_BLOCK | TS_NAMESPACE_DECL => true,
- _ => false,
- }
- }
+ fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, TS_MODULE_BLOCK | TS_NAMESPACE_DECL) }
fn cast(syntax: SyntaxNode) -> Option<Self> {
let res = match syntax.kind() {
TS_MODULE_BLOCK => TsNamespaceBody::TsModuleBlock(TsModuleBlock { syntax }),

MODIFY
xtask/src/codegen/generate_nodes.rs
xtask/src/codegen/generate_nodes.rs
@@ -293,6 +293,21 @@ pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
None
}
};
+
+ let can_cast_fn = if en.variants.iter().any(|v| !simple_variants.contains(&v)) {
+ quote! {
+ match kind {
+ #all_kinds
+ #(#vv_can_cast)*
+ _ => false
+ }
+ }
+ } else {
+ quote! {
+ matches!(kind, #(#kinds)|*)
+ }
+ };
+
let variant_can_cast: Vec<_> = simple_variants
.iter()
.map(|_| {
@@ -321,12 +336,7 @@ pub fn generate_nodes(ast: &AstSrc) -> Result<String> {
impl AstNode for #name {
fn can_cast(kind: SyntaxKind) -> bool {
- // matches!(kind, #(#kinds)|*)
- match kind {
- #all_kinds
- #(#vv_can_cast)*
- _ => false
- }
+ #can_cast_fn
}
fn cast(syntax: SyntaxNode) -> Option<Self> {
#cast_fn

feat: optimize `can_cast` codegen for unions (#1790)