Skip to content

Commit 371473c

Browse files
committed
feat(ast, semantic): implement GetAddress for AstKind and AstNode (#11758)
Implement `GetAddress` on `AstKind` and `AstNode`. This should make it a bit easier to migrate away from comparing spans to find out if 2 AST nodes are the same. This was unblocked by #11684 (thank you @ulrichstark).
1 parent f539f64 commit 371473c

File tree

3 files changed

+218
-0
lines changed

3 files changed

+218
-0
lines changed

crates/oxc_ast/src/generated/ast_kind.rs

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use std::ptr;
88

9+
use oxc_allocator::{Address, GetAddress};
910
use oxc_span::{GetSpan, Span};
1011

1112
use crate::ast::*;
@@ -598,6 +599,194 @@ impl GetSpan for AstKind<'_> {
598599
}
599600
}
600601

602+
impl GetAddress for AstKind<'_> {
603+
fn address(&self) -> Address {
604+
match *self {
605+
Self::Program(it) => Address::from_ptr(it),
606+
Self::IdentifierName(it) => Address::from_ptr(it),
607+
Self::IdentifierReference(it) => Address::from_ptr(it),
608+
Self::BindingIdentifier(it) => Address::from_ptr(it),
609+
Self::LabelIdentifier(it) => Address::from_ptr(it),
610+
Self::ThisExpression(it) => Address::from_ptr(it),
611+
Self::ArrayExpression(it) => Address::from_ptr(it),
612+
Self::Elision(it) => Address::from_ptr(it),
613+
Self::ObjectExpression(it) => Address::from_ptr(it),
614+
Self::ObjectProperty(it) => Address::from_ptr(it),
615+
Self::PropertyKey(it) => it.address(),
616+
Self::TemplateLiteral(it) => Address::from_ptr(it),
617+
Self::TaggedTemplateExpression(it) => Address::from_ptr(it),
618+
Self::MemberExpression(it) => it.address(),
619+
Self::CallExpression(it) => Address::from_ptr(it),
620+
Self::NewExpression(it) => Address::from_ptr(it),
621+
Self::MetaProperty(it) => Address::from_ptr(it),
622+
Self::SpreadElement(it) => Address::from_ptr(it),
623+
Self::Argument(it) => it.address(),
624+
Self::UpdateExpression(it) => Address::from_ptr(it),
625+
Self::UnaryExpression(it) => Address::from_ptr(it),
626+
Self::BinaryExpression(it) => Address::from_ptr(it),
627+
Self::PrivateInExpression(it) => Address::from_ptr(it),
628+
Self::LogicalExpression(it) => Address::from_ptr(it),
629+
Self::ConditionalExpression(it) => Address::from_ptr(it),
630+
Self::AssignmentExpression(it) => Address::from_ptr(it),
631+
Self::AssignmentTarget(it) => it.address(),
632+
Self::SimpleAssignmentTarget(it) => it.address(),
633+
Self::AssignmentTargetPattern(it) => it.address(),
634+
Self::ArrayAssignmentTarget(it) => Address::from_ptr(it),
635+
Self::ObjectAssignmentTarget(it) => Address::from_ptr(it),
636+
Self::AssignmentTargetWithDefault(it) => Address::from_ptr(it),
637+
Self::SequenceExpression(it) => Address::from_ptr(it),
638+
Self::Super(it) => Address::from_ptr(it),
639+
Self::AwaitExpression(it) => Address::from_ptr(it),
640+
Self::ChainExpression(it) => Address::from_ptr(it),
641+
Self::ParenthesizedExpression(it) => Address::from_ptr(it),
642+
Self::Directive(it) => Address::from_ptr(it),
643+
Self::Hashbang(it) => Address::from_ptr(it),
644+
Self::BlockStatement(it) => Address::from_ptr(it),
645+
Self::VariableDeclaration(it) => Address::from_ptr(it),
646+
Self::VariableDeclarator(it) => Address::from_ptr(it),
647+
Self::EmptyStatement(it) => Address::from_ptr(it),
648+
Self::ExpressionStatement(it) => Address::from_ptr(it),
649+
Self::IfStatement(it) => Address::from_ptr(it),
650+
Self::DoWhileStatement(it) => Address::from_ptr(it),
651+
Self::WhileStatement(it) => Address::from_ptr(it),
652+
Self::ForStatement(it) => Address::from_ptr(it),
653+
Self::ForInStatement(it) => Address::from_ptr(it),
654+
Self::ForOfStatement(it) => Address::from_ptr(it),
655+
Self::ContinueStatement(it) => Address::from_ptr(it),
656+
Self::BreakStatement(it) => Address::from_ptr(it),
657+
Self::ReturnStatement(it) => Address::from_ptr(it),
658+
Self::WithStatement(it) => Address::from_ptr(it),
659+
Self::SwitchStatement(it) => Address::from_ptr(it),
660+
Self::SwitchCase(it) => Address::from_ptr(it),
661+
Self::LabeledStatement(it) => Address::from_ptr(it),
662+
Self::ThrowStatement(it) => Address::from_ptr(it),
663+
Self::TryStatement(it) => Address::from_ptr(it),
664+
Self::CatchClause(it) => Address::from_ptr(it),
665+
Self::CatchParameter(it) => Address::from_ptr(it),
666+
Self::DebuggerStatement(it) => Address::from_ptr(it),
667+
Self::AssignmentPattern(it) => Address::from_ptr(it),
668+
Self::ObjectPattern(it) => Address::from_ptr(it),
669+
Self::ArrayPattern(it) => Address::from_ptr(it),
670+
Self::BindingRestElement(it) => Address::from_ptr(it),
671+
Self::Function(it) => Address::from_ptr(it),
672+
Self::FormalParameters(it) => Address::from_ptr(it),
673+
Self::FormalParameter(it) => Address::from_ptr(it),
674+
Self::FunctionBody(it) => Address::from_ptr(it),
675+
Self::ArrowFunctionExpression(it) => Address::from_ptr(it),
676+
Self::YieldExpression(it) => Address::from_ptr(it),
677+
Self::Class(it) => Address::from_ptr(it),
678+
Self::ClassBody(it) => Address::from_ptr(it),
679+
Self::MethodDefinition(it) => Address::from_ptr(it),
680+
Self::PropertyDefinition(it) => Address::from_ptr(it),
681+
Self::PrivateIdentifier(it) => Address::from_ptr(it),
682+
Self::StaticBlock(it) => Address::from_ptr(it),
683+
Self::ModuleDeclaration(it) => it.address(),
684+
Self::AccessorProperty(it) => Address::from_ptr(it),
685+
Self::ImportExpression(it) => Address::from_ptr(it),
686+
Self::ImportDeclaration(it) => Address::from_ptr(it),
687+
Self::ImportSpecifier(it) => Address::from_ptr(it),
688+
Self::ImportDefaultSpecifier(it) => Address::from_ptr(it),
689+
Self::ImportNamespaceSpecifier(it) => Address::from_ptr(it),
690+
Self::WithClause(it) => Address::from_ptr(it),
691+
Self::ImportAttribute(it) => Address::from_ptr(it),
692+
Self::ExportNamedDeclaration(it) => Address::from_ptr(it),
693+
Self::ExportDefaultDeclaration(it) => Address::from_ptr(it),
694+
Self::ExportAllDeclaration(it) => Address::from_ptr(it),
695+
Self::ExportSpecifier(it) => Address::from_ptr(it),
696+
Self::V8IntrinsicExpression(it) => Address::from_ptr(it),
697+
Self::BooleanLiteral(it) => Address::from_ptr(it),
698+
Self::NullLiteral(it) => Address::from_ptr(it),
699+
Self::NumericLiteral(it) => Address::from_ptr(it),
700+
Self::StringLiteral(it) => Address::from_ptr(it),
701+
Self::BigIntLiteral(it) => Address::from_ptr(it),
702+
Self::RegExpLiteral(it) => Address::from_ptr(it),
703+
Self::JSXElement(it) => Address::from_ptr(it),
704+
Self::JSXOpeningElement(it) => Address::from_ptr(it),
705+
Self::JSXClosingElement(it) => Address::from_ptr(it),
706+
Self::JSXFragment(it) => Address::from_ptr(it),
707+
Self::JSXOpeningFragment(it) => Address::from_ptr(it),
708+
Self::JSXClosingFragment(it) => Address::from_ptr(it),
709+
Self::JSXNamespacedName(it) => Address::from_ptr(it),
710+
Self::JSXMemberExpression(it) => Address::from_ptr(it),
711+
Self::JSXExpressionContainer(it) => Address::from_ptr(it),
712+
Self::JSXEmptyExpression(it) => Address::from_ptr(it),
713+
Self::JSXAttribute(it) => Address::from_ptr(it),
714+
Self::JSXSpreadAttribute(it) => Address::from_ptr(it),
715+
Self::JSXIdentifier(it) => Address::from_ptr(it),
716+
Self::JSXSpreadChild(it) => Address::from_ptr(it),
717+
Self::JSXText(it) => Address::from_ptr(it),
718+
Self::TSThisParameter(it) => Address::from_ptr(it),
719+
Self::TSEnumDeclaration(it) => Address::from_ptr(it),
720+
Self::TSEnumBody(it) => Address::from_ptr(it),
721+
Self::TSEnumMember(it) => Address::from_ptr(it),
722+
Self::TSTypeAnnotation(it) => Address::from_ptr(it),
723+
Self::TSLiteralType(it) => Address::from_ptr(it),
724+
Self::TSConditionalType(it) => Address::from_ptr(it),
725+
Self::TSUnionType(it) => Address::from_ptr(it),
726+
Self::TSIntersectionType(it) => Address::from_ptr(it),
727+
Self::TSParenthesizedType(it) => Address::from_ptr(it),
728+
Self::TSTypeOperator(it) => Address::from_ptr(it),
729+
Self::TSArrayType(it) => Address::from_ptr(it),
730+
Self::TSIndexedAccessType(it) => Address::from_ptr(it),
731+
Self::TSTupleType(it) => Address::from_ptr(it),
732+
Self::TSNamedTupleMember(it) => Address::from_ptr(it),
733+
Self::TSOptionalType(it) => Address::from_ptr(it),
734+
Self::TSRestType(it) => Address::from_ptr(it),
735+
Self::TSAnyKeyword(it) => Address::from_ptr(it),
736+
Self::TSStringKeyword(it) => Address::from_ptr(it),
737+
Self::TSBooleanKeyword(it) => Address::from_ptr(it),
738+
Self::TSNumberKeyword(it) => Address::from_ptr(it),
739+
Self::TSNeverKeyword(it) => Address::from_ptr(it),
740+
Self::TSIntrinsicKeyword(it) => Address::from_ptr(it),
741+
Self::TSUnknownKeyword(it) => Address::from_ptr(it),
742+
Self::TSNullKeyword(it) => Address::from_ptr(it),
743+
Self::TSUndefinedKeyword(it) => Address::from_ptr(it),
744+
Self::TSVoidKeyword(it) => Address::from_ptr(it),
745+
Self::TSSymbolKeyword(it) => Address::from_ptr(it),
746+
Self::TSThisType(it) => Address::from_ptr(it),
747+
Self::TSObjectKeyword(it) => Address::from_ptr(it),
748+
Self::TSBigIntKeyword(it) => Address::from_ptr(it),
749+
Self::TSTypeReference(it) => Address::from_ptr(it),
750+
Self::TSTypeName(it) => it.address(),
751+
Self::TSQualifiedName(it) => Address::from_ptr(it),
752+
Self::TSTypeParameterInstantiation(it) => Address::from_ptr(it),
753+
Self::TSTypeParameter(it) => Address::from_ptr(it),
754+
Self::TSTypeParameterDeclaration(it) => Address::from_ptr(it),
755+
Self::TSTypeAliasDeclaration(it) => Address::from_ptr(it),
756+
Self::TSClassImplements(it) => Address::from_ptr(it),
757+
Self::TSInterfaceDeclaration(it) => Address::from_ptr(it),
758+
Self::TSPropertySignature(it) => Address::from_ptr(it),
759+
Self::TSCallSignatureDeclaration(it) => Address::from_ptr(it),
760+
Self::TSMethodSignature(it) => Address::from_ptr(it),
761+
Self::TSConstructSignatureDeclaration(it) => Address::from_ptr(it),
762+
Self::TSIndexSignatureName(it) => Address::from_ptr(it),
763+
Self::TSInterfaceHeritage(it) => Address::from_ptr(it),
764+
Self::TSTypePredicate(it) => Address::from_ptr(it),
765+
Self::TSModuleDeclaration(it) => Address::from_ptr(it),
766+
Self::TSModuleBlock(it) => Address::from_ptr(it),
767+
Self::TSTypeLiteral(it) => Address::from_ptr(it),
768+
Self::TSInferType(it) => Address::from_ptr(it),
769+
Self::TSTypeQuery(it) => Address::from_ptr(it),
770+
Self::TSImportType(it) => Address::from_ptr(it),
771+
Self::TSMappedType(it) => Address::from_ptr(it),
772+
Self::TSTemplateLiteralType(it) => Address::from_ptr(it),
773+
Self::TSAsExpression(it) => Address::from_ptr(it),
774+
Self::TSSatisfiesExpression(it) => Address::from_ptr(it),
775+
Self::TSTypeAssertion(it) => Address::from_ptr(it),
776+
Self::TSImportEqualsDeclaration(it) => Address::from_ptr(it),
777+
Self::TSExternalModuleReference(it) => Address::from_ptr(it),
778+
Self::TSNonNullExpression(it) => Address::from_ptr(it),
779+
Self::Decorator(it) => Address::from_ptr(it),
780+
Self::TSExportAssignment(it) => Address::from_ptr(it),
781+
Self::TSNamespaceExportDeclaration(it) => Address::from_ptr(it),
782+
Self::TSInstantiationExpression(it) => Address::from_ptr(it),
783+
Self::JSDocNullableType(it) => Address::from_ptr(it),
784+
Self::JSDocNonNullableType(it) => Address::from_ptr(it),
785+
Self::JSDocUnknownType(it) => Address::from_ptr(it),
786+
}
787+
}
788+
}
789+
601790
impl<'a> AstKind<'a> {
602791
#[inline]
603792
pub fn as_program(self) -> Option<&'a Program<'a>> {

crates/oxc_semantic/src/node.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use oxc_allocator::{Address, GetAddress};
12
use oxc_ast::AstKind;
23
use oxc_cfg::BlockNodeId;
34
use oxc_index::IndexVec;
@@ -85,6 +86,13 @@ impl GetSpan for AstNode<'_> {
8586
}
8687
}
8788

89+
impl GetAddress for AstNode<'_> {
90+
#[inline]
91+
fn address(&self) -> Address {
92+
self.kind.address()
93+
}
94+
}
95+
8896
/// Untyped AST nodes flattened into an vec
8997
#[derive(Debug, Default)]
9098
pub struct AstNodes<'a> {

tasks/ast_tools/src/generators/ast_kind.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! * `AstKind::ty` method.
66
//! * `AstKind::as_*` methods.
77
//! * `GetSpan` impl for `AstKind`.
8+
//! * `GetAddress` impl for `AstKind`.
89
//!
910
//! Variants of `AstKind` and `AstType` are created for:
1011
//!
@@ -108,6 +109,7 @@ impl Generator for AstKindGenerator {
108109
let mut type_variants = quote!();
109110
let mut kind_variants = quote!();
110111
let mut span_match_arms = quote!();
112+
let mut address_match_arms = quote!();
111113
let mut as_methods = quote!();
112114

113115
let mut next_index = 0u16;
@@ -131,6 +133,13 @@ impl Generator for AstKindGenerator {
131133

132134
span_match_arms.extend(quote!( Self::#type_ident(it) => it.span(), ));
133135

136+
let get_address = match type_def {
137+
TypeDef::Struct(_) => quote!(Address::from_ptr(it)),
138+
TypeDef::Enum(_) => quote!(it.address()),
139+
_ => unreachable!(),
140+
};
141+
address_match_arms.extend(quote!( Self::#type_ident(it) => #get_address, ));
142+
134143
let as_method_name = format_ident!("as_{}", type_def.snake_name());
135144
as_methods.extend(quote! {
136145
///@@line_break
@@ -154,6 +163,7 @@ impl Generator for AstKindGenerator {
154163
use std::ptr;
155164

156165
///@@line_break
166+
use oxc_allocator::{Address, GetAddress};
157167
use oxc_span::{GetSpan, Span};
158168

159169
///@@line_break
@@ -196,6 +206,17 @@ impl Generator for AstKindGenerator {
196206
}
197207
}
198208

209+
///@@line_break
210+
impl GetAddress for AstKind<'_> {
211+
// TODO: Once only structs have `AstKind`s (https://github.com/oxc-project/oxc/issues/11490),
212+
// mark this method `#[inline]`, because then it'll be boiled down to a single instruction.
213+
fn address(&self) -> Address {
214+
match *self {
215+
#address_match_arms
216+
}
217+
}
218+
}
219+
199220
///@@line_break
200221
impl<'a> AstKind<'a> {
201222
#as_methods

0 commit comments

Comments
 (0)