mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 12:51:57 +00:00
389 lines
13 KiB
Rust
389 lines
13 KiB
Rust
use std::hash::{Hash, Hasher};
|
|
|
|
use miette::{SourceOffset, SourceSpan};
|
|
use serde::Serialize;
|
|
|
|
#[allow(clippy::wildcard_imports)]
|
|
use crate::ast::*;
|
|
|
|
/// Newtype for working with text sizes/ranges.
|
|
/// See the [`text-size`](https://docs.rs/text-size) crate for details.
|
|
/// Utility methods can be copied from the `text-size` crate if they are needed.
|
|
/// NOTE: `u32` is sufficient for "all" reasonable programs. Larger than u32 is a 4GB JS file.
|
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, PartialOrd, Ord)]
|
|
pub struct Span {
|
|
pub start: u32,
|
|
pub end: u32,
|
|
}
|
|
|
|
impl Span {
|
|
#[must_use]
|
|
#[inline]
|
|
pub const fn new(start: u32, end: u32) -> Self {
|
|
Self { start, end }
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn len(&self) -> u32 {
|
|
self.end - self.start
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn is_empty(&self) -> bool {
|
|
self.len() == 0
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn source_text<'a>(&self, source_text: &'a str) -> &'a str {
|
|
&source_text[self.start as usize..self.end as usize]
|
|
}
|
|
}
|
|
|
|
// #[allow(clippy::derive_hash_xor_eq)]
|
|
impl Hash for Span {
|
|
fn hash<H: Hasher>(&self, _state: &mut H) {
|
|
// hash to nothing so all ast spans can be comparible with hash
|
|
}
|
|
}
|
|
|
|
impl From<Span> for SourceSpan {
|
|
fn from(val: Span) -> Self {
|
|
Self::new(SourceOffset::from(val.start as usize), SourceOffset::from(val.len() as usize))
|
|
}
|
|
}
|
|
|
|
pub trait GetSpan {
|
|
#[must_use]
|
|
fn span(&self) -> Span;
|
|
}
|
|
|
|
impl<'a> GetSpan for Statement<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::BlockStatement(stmt) => stmt.span,
|
|
Self::BreakStatement(stmt) => stmt.span,
|
|
Self::ContinueStatement(stmt) => stmt.span,
|
|
Self::DebuggerStatement(stmt) => stmt.span,
|
|
Self::DoWhileStatement(stmt) => stmt.span,
|
|
Self::EmptyStatement(stmt) => stmt.span,
|
|
Self::ExpressionStatement(stmt) => stmt.span,
|
|
Self::ForInStatement(stmt) => stmt.span,
|
|
Self::ForOfStatement(stmt) => stmt.span,
|
|
Self::ForStatement(stmt) => stmt.span,
|
|
Self::IfStatement(stmt) => stmt.span,
|
|
Self::LabeledStatement(stmt) => stmt.span,
|
|
Self::ReturnStatement(stmt) => stmt.span,
|
|
Self::SwitchStatement(stmt) => stmt.span,
|
|
Self::ThrowStatement(stmt) => stmt.span,
|
|
Self::TryStatement(stmt) => stmt.span,
|
|
Self::WhileStatement(stmt) => stmt.span,
|
|
Self::WithStatement(stmt) => stmt.span,
|
|
Self::ModuleDeclaration(decl) => decl.span,
|
|
Self::Declaration(decl) => decl.span(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for Expression<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::BooleanLiteral(e) => e.span,
|
|
Self::NullLiteral(e) => e.span,
|
|
Self::NumberLiteral(e) => e.span,
|
|
Self::BigintLiteral(e) => e.span,
|
|
Self::RegExpLiteral(e) => e.span,
|
|
Self::StringLiteral(e) => e.span,
|
|
Self::TemplateLiteral(e) => e.span,
|
|
Self::Identifier(e) => e.span,
|
|
Self::MetaProperty(e) => e.span,
|
|
Self::Super(e) => e.span,
|
|
Self::ArrayExpression(e) => e.span,
|
|
Self::ArrowFunctionExpression(e) => e.span,
|
|
Self::AssignmentExpression(e) => e.span,
|
|
Self::AwaitExpression(e) => e.span,
|
|
Self::BinaryExpression(e) => e.span,
|
|
Self::PrivateInExpression(e) => e.span,
|
|
Self::CallExpression(e) => e.span,
|
|
Self::ChainExpression(e) => e.span,
|
|
Self::ClassExpression(e) => e.span,
|
|
Self::ConditionalExpression(e) => e.span,
|
|
Self::FunctionExpression(e) => e.span,
|
|
Self::ImportExpression(e) => e.span,
|
|
Self::LogicalExpression(e) => e.span,
|
|
Self::MemberExpression(e) => e.span(),
|
|
Self::NewExpression(e) => e.span,
|
|
Self::ObjectExpression(e) => e.span,
|
|
Self::ParenthesizedExpression(e) => e.span,
|
|
Self::SequenceExpression(e) => e.span,
|
|
Self::TaggedTemplateExpression(e) => e.span,
|
|
Self::ThisExpression(e) => e.span,
|
|
Self::UnaryExpression(e) => e.span,
|
|
Self::UpdateExpression(e) => e.span,
|
|
Self::YieldExpression(e) => e.span,
|
|
Self::JSXElement(e) => e.span,
|
|
Self::JSXFragment(e) => e.span,
|
|
Self::TSAsExpression(e) => e.span,
|
|
Self::TSTypeAssertion(e) => e.span,
|
|
Self::TSNonNullExpression(e) => e.span,
|
|
Self::TSInstantiationExpression(e) => e.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for BindingPatternKind<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::BindingIdentifier(ident) => ident.span,
|
|
Self::ObjectPattern(pat) => pat.span,
|
|
Self::ArrayPattern(pat) => pat.span,
|
|
Self::RestElement(elem) => elem.span,
|
|
Self::AssignmentPattern(pat) => pat.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for BindingPattern<'a> {
|
|
fn span(&self) -> Span {
|
|
match &self.kind {
|
|
BindingPatternKind::BindingIdentifier(ident) => ident.span,
|
|
BindingPatternKind::ObjectPattern(pat) => pat.span,
|
|
BindingPatternKind::ArrayPattern(pat) => pat.span,
|
|
BindingPatternKind::RestElement(pat) => pat.span,
|
|
BindingPatternKind::AssignmentPattern(pat) => pat.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for ClassElement<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::StaticBlock(block) => block.span,
|
|
Self::MethodDefinition(def) => def.span,
|
|
Self::PropertyDefinition(def) => def.span,
|
|
Self::AccessorProperty(def) => def.span,
|
|
Self::TSAbstractMethodDefinition(def) => def.method_definition.span,
|
|
Self::TSAbstractPropertyDefinition(def) => def.property_definition.span,
|
|
Self::TSIndexSignature(sig) => sig.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for PropertyKey<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::Identifier(ident) => ident.span,
|
|
Self::PrivateIdentifier(ident) => ident.span,
|
|
Self::Expression(expr) => expr.span(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for MemberExpression<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::ComputedMemberExpression(expr) => expr.span,
|
|
Self::StaticMemberExpression(expr) => expr.span,
|
|
Self::PrivateFieldExpression(expr) => expr.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl GetSpan for ImportAttributeKey {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::Identifier(identifier) => identifier.span,
|
|
Self::StringLiteral(literal) => literal.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl GetSpan for ModuleExportName {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::Identifier(identifier) => identifier.span,
|
|
Self::StringLiteral(literal) => literal.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for Declaration<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::VariableDeclaration(decl) => decl.span,
|
|
Self::FunctionDeclaration(decl) => decl.span,
|
|
Self::ClassDeclaration(decl) => decl.span,
|
|
Self::TSTypeAliasDeclaration(decl) => decl.span,
|
|
Self::TSInterfaceDeclaration(decl) => decl.span,
|
|
Self::TSEnumDeclaration(decl) => decl.span,
|
|
Self::TSModuleDeclaration(decl) => decl.span,
|
|
Self::TSImportEqualsDeclaration(decl) => decl.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl GetSpan for TSModuleDeclarationName {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::Identifier(ident) => ident.span,
|
|
Self::StringLiteral(lit) => lit.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for ObjectProperty<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::Property(p) => p.span,
|
|
Self::SpreadProperty(p) => p.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for ObjectPatternProperty<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::Property(p) => p.span,
|
|
Self::RestElement(e) => e.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for AssignmentTarget<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::SimpleAssignmentTarget(SimpleAssignmentTarget::AssignmentTargetIdentifier(
|
|
ident,
|
|
)) => ident.span,
|
|
Self::SimpleAssignmentTarget(SimpleAssignmentTarget::MemberAssignmentTarget(expr)) => {
|
|
expr.span()
|
|
}
|
|
Self::SimpleAssignmentTarget(SimpleAssignmentTarget::TSAsExpression(expr)) => expr.span,
|
|
Self::SimpleAssignmentTarget(SimpleAssignmentTarget::TSNonNullExpression(expr)) => {
|
|
expr.span
|
|
}
|
|
Self::SimpleAssignmentTarget(SimpleAssignmentTarget::TSTypeAssertion(expr)) => {
|
|
expr.span
|
|
}
|
|
Self::AssignmentTargetPattern(AssignmentTargetPattern::ArrayAssignmentTarget(pat)) => {
|
|
pat.span
|
|
}
|
|
Self::AssignmentTargetPattern(AssignmentTargetPattern::ObjectAssignmentTarget(pat)) => {
|
|
pat.span
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for PropertyValue<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::Pattern(pat) => pat.span(),
|
|
Self::Expression(expr) => expr.span(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for Argument<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::SpreadElement(e) => e.span,
|
|
Self::Expression(expr) => expr.span(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for ForStatementInit<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::VariableDeclaration(x) => x.span,
|
|
Self::Expression(x) => x.span(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for SimpleAssignmentTarget<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::AssignmentTargetIdentifier(ident) => ident.span,
|
|
Self::MemberAssignmentTarget(expr) => expr.span(),
|
|
Self::TSAsExpression(expr) => expr.span,
|
|
Self::TSNonNullExpression(expr) => expr.span,
|
|
Self::TSTypeAssertion(expr) => expr.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for JSXElementName<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::Identifier(ident) => ident.span,
|
|
Self::NamespacedName(name) => name.span,
|
|
Self::MemberExpression(expr) => expr.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for TSSignature<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::TSIndexSignature(sig) => sig.span,
|
|
Self::TSPropertySignature(sig) => sig.span,
|
|
Self::TSCallSignatureDeclaration(decl) => decl.span,
|
|
Self::TSConstructSignatureDeclaration(decl) => decl.span,
|
|
Self::TSMethodSignature(sig) => sig.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for TSType<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::TSConditionalType(t) => t.span,
|
|
Self::TSFunctionType(t) => t.span,
|
|
Self::TSLiteralType(t) => t.span,
|
|
Self::TSTypeReference(t) => t.span,
|
|
Self::TSTypeQuery(t) => t.span,
|
|
Self::TSUnionType(t) => t.span,
|
|
Self::TSTupleType(t) => t.span,
|
|
Self::TSArrayType(t) => t.span,
|
|
Self::TSIntersectionType(t) => t.span,
|
|
Self::TSMappedType(t) => t.span,
|
|
Self::TSInferType(t) => t.span,
|
|
Self::TSConstructorType(t) => t.span,
|
|
Self::TSIndexedAccessType(t) => t.span,
|
|
Self::TSTypeOperatorType(t) => t.span,
|
|
Self::TSImportType(t) => t.span,
|
|
Self::TSQualifiedName(t) => t.span,
|
|
Self::TSTypePredicate(t) => t.span,
|
|
Self::TSTypeLiteral(t) => t.span,
|
|
Self::TSTemplateLiteralType(t) => t.span,
|
|
Self::TSAnyKeyword(t) => t.span,
|
|
Self::TSUnknownKeyword(t) => t.span,
|
|
Self::TSUndefinedKeyword(t) => t.span,
|
|
Self::TSNullKeyword(t) => t.span,
|
|
Self::TSNumberKeyword(t) => t.span,
|
|
Self::TSStringKeyword(t) => t.span,
|
|
Self::TSNeverKeyword(t) => t.span,
|
|
Self::TSBooleanKeyword(t) => t.span,
|
|
Self::TSSymbolKeyword(t) => t.span,
|
|
Self::TSBigIntKeyword(t) => t.span,
|
|
Self::TSThisKeyword(t) => t.span,
|
|
Self::TSVoidKeyword(t) => t.span,
|
|
Self::TSObjectKeyword(t) => t.span,
|
|
Self::JSDocNullableType(t) => t.span,
|
|
Self::JSDocUnknownType(t) => t.span,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> GetSpan for ExportDefaultDeclarationKind<'a> {
|
|
fn span(&self) -> Span {
|
|
match self {
|
|
Self::ClassDeclaration(x) => x.span,
|
|
Self::Expression(x) => x.span(),
|
|
Self::FunctionDeclaration(x) => x.span,
|
|
Self::TSEnumDeclaration(x) => x.span,
|
|
Self::TSInterfaceDeclaration(x) => x.span,
|
|
}
|
|
}
|
|
}
|