Skip to content

Commit

Permalink
feat(ast): improve AstKind::debug_name
Browse files Browse the repository at this point in the history
> Part of #4445

Improve `debug_name` to show identifier names for more AST kinds.
  • Loading branch information
DonIsaac committed Jul 30, 2024
1 parent 48792d1 commit 0ab3503
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 37 deletions.
20 changes: 20 additions & 0 deletions crates/oxc_ast/src/ast_impl/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,13 @@ impl<'a> IdentifierName<'a> {
}
}

impl<'a> fmt::Display for IdentifierName<'a> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.name.fmt(f)
}
}

impl<'a> Hash for IdentifierReference<'a> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
Expand All @@ -319,6 +326,12 @@ impl<'a> IdentifierReference<'a> {
}
}

impl<'a> fmt::Display for IdentifierReference<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.name.fmt(f)
}
}

impl<'a> Hash for BindingIdentifier<'a> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
Expand All @@ -331,6 +344,13 @@ impl<'a> BindingIdentifier<'a> {
}
}

impl<'a> fmt::Display for BindingIdentifier<'a> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.name.fmt(f)
}
}

impl<'a> ArrayExpressionElement<'a> {
pub fn is_elision(&self) -> bool {
matches!(self, Self::Elision(_))
Expand Down
48 changes: 40 additions & 8 deletions crates/oxc_ast/src/ast_impl/jsx.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
//! [JSX](https://facebook.github.io/jsx)
use std::fmt;
use crate::ast::*;
use oxc_span::{Atom, Span};

// 1.2 JSX Elements

impl<'a> std::fmt::Display for JSXNamespacedName<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
impl<'a> JSXIdentifier<'a> {
pub fn new(span: Span, name: Atom<'a>) -> Self {
Self { span, name }
}
}
impl<'a> fmt::Display for JSXIdentifier<'a> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.name.fmt(f)
}
}

impl<'a> fmt::Display for JSXNamespacedName<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}", self.namespace.name, self.property.name)
}
}
Expand Down Expand Up @@ -41,6 +54,31 @@ impl<'a> JSXMemberExpression<'a> {
}
}

impl<'a> fmt::Display for JSXMemberExpression<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}.{}", self.object, self.property)
}
}

impl<'a> fmt::Display for JSXMemberExpressionObject<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Identifier(id) => id.fmt(f),
Self::MemberExpression(expr) => expr.fmt(f),
}
}
}

impl<'a> fmt::Display for JSXElementName<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Identifier(ident) => ident.fmt(f),
Self::NamespacedName(namespaced) => namespaced.fmt(f),
Self::MemberExpression(member_expr) => member_expr.fmt(f),
}
}
}

impl<'a> JSXExpression<'a> {
/// Determines whether the given expr is a `undefined` literal
pub fn is_undefined(&self) -> bool {
Expand All @@ -57,9 +95,3 @@ impl<'a> JSXAttribute<'a> {
self.is_identifier("key")
}
}

impl<'a> JSXIdentifier<'a> {
pub fn new(span: Span, name: Atom<'a>) -> Self {
Self { span, name }
}
}
26 changes: 25 additions & 1 deletion crates/oxc_ast/src/ast_impl/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! [AST Spec](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/ast-spec)
//! [Archived TypeScript spec](https://github.com/microsoft/TypeScript/blob/3c99d50da5a579d9fa92d02664b1b66d4ff55944/doc/spec-ARCHIVED.md)
use std::{cell::Cell, hash::Hash};
use std::{cell::Cell, fmt, hash::Hash};

use oxc_allocator::Vec;
use oxc_span::{Atom, Span};
Expand Down Expand Up @@ -100,6 +100,21 @@ impl<'a> TSTypeName<'a> {
}
}

impl<'a> fmt::Display for TSTypeName<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TSTypeName::IdentifierReference(ident) => ident.fmt(f),
TSTypeName::QualifiedName(qualified) => qualified.fmt(f),
}
}
}

impl<'a> fmt::Display for TSQualifiedName<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}.{}", self.left, self.right)
}
}

impl<'a> TSType<'a> {
/// Remove nested parentheses from this type.
pub fn without_parenthesized(&self) -> &Self {
Expand Down Expand Up @@ -154,6 +169,15 @@ impl<'a> TSModuleDeclarationName<'a> {
}
}

impl<'a> fmt::Display for TSModuleDeclarationName<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Identifier(id) => id.fmt(f),
Self::StringLiteral(lit) => lit.fmt(f),
}
}
}

impl<'a> TSModuleDeclarationBody<'a> {
pub fn is_strict(&self) -> bool {
matches!(self, Self::TSModuleBlock(block) if block.is_strict())
Expand Down
85 changes: 57 additions & 28 deletions crates/oxc_ast/src/ast_kind_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ impl<'a> AstKind<'a> {
/// Note that this method does not exist in release builds. Do not include
/// usage of this method within your code.
pub fn debug_name(&self) -> std::borrow::Cow<str> {
use std::borrow::Cow;

const COMPUTED: Cow<'static, str> = Cow::Borrowed("<computed>");
const UNKNOWN: Cow<'static, str> = Cow::Borrowed("<unknown>");
const ANONYMOUS: Cow<'static, str> = Cow::Borrowed("<anonymous>");
const DESTRUCTURE: Cow<'static, str> = Cow::Borrowed("<destructure>");

#[inline]
fn or_anonymous<'a>(id: Option<&BindingIdentifier<'a>>) -> Cow<'a, str> {
id.map_or_else(|| ANONYMOUS.as_ref(), |id| id.name.as_str()).into()
}

match self {
Self::Program(_) => "Program".into(),
Self::Directive(d) => d.directive.as_ref().into(),
Expand All @@ -195,7 +207,7 @@ impl<'a> AstKind<'a> {
Self::ForStatement(_) => "ForStatement".into(),
Self::ForStatementInit(_) => "ForStatementInit".into(),
Self::IfStatement(_) => "IfStatement".into(),
Self::LabeledStatement(_) => "LabeledStatement".into(),
Self::LabeledStatement(l) => format!("LabeledStatement({})", l.label.name).into(),
Self::ReturnStatement(_) => "ReturnStatement".into(),
Self::SwitchStatement(_) => "SwitchStatement".into(),
Self::ThrowStatement(_) => "ThrowStatement".into(),
Expand All @@ -208,7 +220,11 @@ impl<'a> AstKind<'a> {
Self::FinallyClause(_) => "FinallyClause".into(),

Self::VariableDeclaration(_) => "VariableDeclaration".into(),
Self::VariableDeclarator(_) => "VariableDeclarator".into(),
Self::VariableDeclarator(v) => format!(
"VariableDeclarator({})",
v.id.get_identifier().unwrap_or(Atom::from(DESTRUCTURE.as_ref()))
)
.into(),

Self::UsingDeclaration(_) => "UsingDeclaration".into(),

Expand Down Expand Up @@ -237,13 +253,26 @@ impl<'a> AstKind<'a> {
Self::ArrowFunctionExpression(_) => "ArrowFunctionExpression".into(),
Self::AssignmentExpression(_) => "AssignmentExpression".into(),
Self::AwaitExpression(_) => "AwaitExpression".into(),
Self::BinaryExpression(b) => format!("BinaryExpression{}", b.operator.as_str()).into(),
Self::CallExpression(_) => "CallExpression".into(),
Self::BinaryExpression(b) => {
format!("BinaryExpression({})", b.operator.as_str()).into()
}
Self::CallExpression(c) => {
format!("CallExpression({})", c.callee_name().unwrap_or(&COMPUTED)).into()
}
Self::ChainExpression(_) => "ChainExpression".into(),
Self::ConditionalExpression(_) => "ConditionalExpression".into(),
Self::LogicalExpression(_) => "LogicalExpression".into(),
Self::MemberExpression(_) => "MemberExpression".into(),
Self::NewExpression(_) => "NewExpression".into(),
Self::NewExpression(n) => {
let callee = match &n.callee {
Expression::Identifier(id) => Some(id.name.as_str()),
match_member_expression!(Expression) => {
n.callee.to_member_expression().static_property_name()
}
_ => None,
};
format!("NewExpression({})", callee.unwrap_or(&COMPUTED)).into()
}
Self::ObjectExpression(_) => "ObjectExpression".into(),
Self::ParenthesizedExpression(_) => "ParenthesizedExpression".into(),
Self::SequenceExpression(_) => "SequenceExpression".into(),
Expand All @@ -255,12 +284,16 @@ impl<'a> AstKind<'a> {
Self::ImportExpression(_) => "ImportExpression".into(),
Self::PrivateInExpression(_) => "PrivateInExpression".into(),

Self::ObjectProperty(_) => "ObjectProperty".into(),
Self::PropertyKey(_) => "PropertyKey".into(),
Self::ObjectProperty(p) => {
format!("ObjectProperty({})", p.key.name().unwrap_or(COMPUTED)).into()
}
Self::PropertyKey(p) => format!("PropertyKey({})", p.name().unwrap_or(COMPUTED)).into(),
Self::Argument(_) => "Argument".into(),
Self::ArrayExpressionElement(_) => "ArrayExpressionElement".into(),
Self::AssignmentTarget(_) => "AssignmentTarget".into(),
Self::SimpleAssignmentTarget(_) => "SimpleAssignmentTarget".into(),
Self::SimpleAssignmentTarget(a) => {
format!("SimpleAssignmentTarget({})", a.get_identifier().unwrap_or(&UNKNOWN)).into()
}
Self::AssignmentTargetPattern(_) => "AssignmentTargetPattern".into(),
Self::ArrayAssignmentTarget(_) => "ArrayAssignmentTarget".into(),
Self::ObjectAssignmentTarget(_) => "ObjectAssignmentTarget".into(),
Expand All @@ -270,21 +303,17 @@ impl<'a> AstKind<'a> {
Self::ExpressionArrayElement(_) => "ExpressionArrayElement".into(),
Self::BindingRestElement(_) => "BindingRestElement".into(),

Self::Function(x) => format!(
"Function({})",
x.id.as_ref().map_or_else(|| "<anonymous>", |id| id.name.as_str())
)
.into(),
Self::Function(x) => format!("Function({})", or_anonymous(x.id.as_ref())).into(),
Self::FunctionBody(_) => "FunctionBody".into(),
Self::FormalParameters(_) => "FormalParameters".into(),
Self::FormalParameter(_) => "FormalParameter".into(),
Self::CatchParameter(_) => "CatchParameter".into(),

Self::Class(c) => format!(
"Class({})",
c.id.as_ref().map_or_else(|| "<anonymous>", |id| id.name.as_str())
Self::FormalParameter(p) => format!(
"FormalParameter({})",
p.pattern.get_identifier().unwrap_or(Atom::from(DESTRUCTURE.as_ref()))
)
.into(),
Self::CatchParameter(_) => "CatchParameter".into(),

Self::Class(c) => format!("Class({})", or_anonymous(c.id.as_ref())).into(),
Self::TSClassImplements(_) => "TSClassImplements".into(),
Self::ClassBody(_) => "ClassBody".into(),
Self::ClassHeritage(_) => "ClassHeritage".into(),
Expand All @@ -300,23 +329,23 @@ impl<'a> AstKind<'a> {

Self::ModuleDeclaration(_) => "ModuleDeclaration".into(),
Self::ImportDeclaration(_) => "ImportDeclaration".into(),
Self::ImportSpecifier(_) => "ImportSpecifier".into(),
Self::ExportSpecifier(_) => "ExportSpecifier".into(),
Self::ImportSpecifier(i) => format!("ImportSpecifier({})", i.local.name).into(),
Self::ExportSpecifier(e) => format!("ExportSpecifier({})", e.local.name()).into(),
Self::ImportDefaultSpecifier(_) => "ImportDefaultSpecifier".into(),
Self::ImportNamespaceSpecifier(_) => "ImportNamespaceSpecifier".into(),
Self::ExportDefaultDeclaration(_) => "ExportDefaultDeclaration".into(),
Self::ExportNamedDeclaration(_) => "ExportNamedDeclaration".into(),
Self::ExportAllDeclaration(_) => "ExportAllDeclaration".into(),
Self::JSXOpeningElement(_) => "JSXOpeningElement".into(),
Self::JSXClosingElement(_) => "JSXClosingElement".into(),
Self::JSXElementName(_) => "JSXElementName".into(),
Self::JSXElementName(n) => format!("JSXElementName({n})").into(),
Self::JSXElement(_) => "JSXElement".into(),
Self::JSXFragment(_) => "JSXFragment".into(),
Self::JSXAttributeItem(_) => "JSXAttributeItem".into(),
Self::JSXSpreadAttribute(_) => "JSXSpreadAttribute".into(),
Self::JSXText(_) => "JSXText".into(),
Self::JSXExpressionContainer(_) => "JSXExpressionContainer".into(),
Self::JSXIdentifier(_) => "JSXIdentifier".into(),
Self::JSXIdentifier(id) => format!("JSXIdentifier({id})").into(),
Self::JSXMemberExpression(_) => "JSXMemberExpression".into(),
Self::JSXMemberExpressionObject(_) => "JSXMemberExpressionObject".into(),
Self::JSXNamespacedName(_) => "JSXNamespacedName".into(),
Expand All @@ -329,7 +358,7 @@ impl<'a> AstKind<'a> {
Self::TSMethodSignature(_) => "TSMethodSignature".into(),
Self::TSNullKeyword(_) => "TSNullKeyword".into(),
Self::TSTypeLiteral(_) => "TSTypeLiteral".into(),
Self::TSTypeReference(_) => "TSTypeReference".into(),
Self::TSTypeReference(t) => format!("TSTypeReference({})", t.type_name).into(),
Self::TSUnionType(_) => "TSUnionType".into(),
Self::TSParenthesizedType(_) => "TSParenthesizedType".into(),
Self::TSVoidKeyword(_) => "TSVoidKeyword".into(),
Expand Down Expand Up @@ -359,18 +388,18 @@ impl<'a> AstKind<'a> {
Self::TSEnumMember(_) => "TSEnumMember".into(),

Self::TSImportEqualsDeclaration(_) => "TSImportEqualsDeclaration".into(),
Self::TSTypeName(_) => "TSTypeName".into(),
Self::TSTypeName(n) => format!("TSTypeName({n})").into(),
Self::TSExternalModuleReference(_) => "TSExternalModuleReference".into(),
Self::TSQualifiedName(_) => "TSQualifiedName".into(),
Self::TSQualifiedName(n) => format!("TSQualifiedName({n})").into(),
Self::TSInterfaceDeclaration(_) => "TSInterfaceDeclaration".into(),
Self::TSInterfaceHeritage(_) => "TSInterfaceHeritage".into(),
Self::TSModuleDeclaration(_) => "TSModuleDeclaration".into(),
Self::TSModuleDeclaration(m) => format!("TSModuleDeclaration({})", m.id).into(),
Self::TSTypeAliasDeclaration(_) => "TSTypeAliasDeclaration".into(),
Self::TSTypeAnnotation(_) => "TSTypeAnnotation".into(),
Self::TSTypeQuery(_) => "TSTypeQuery".into(),
Self::TSTypeAssertion(_) => "TSTypeAssertion".into(),
Self::TSThisParameter(_) => "TSThisParameter".into(),
Self::TSTypeParameter(_) => "TSTypeParameter".into(),
Self::TSTypeParameter(t) => format!("TSTypeParameter({})", t.name).into(),
Self::TSTypeParameterDeclaration(_) => "TSTypeParameterDeclaration".into(),
Self::TSTypeParameterInstantiation(_) => "TSTypeParameterInstantiation".into(),
Self::TSImportType(_) => "TSImportType".into(),
Expand Down

0 comments on commit 0ab3503

Please sign in to comment.