Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions apps/oxlint/src-js/generated/deserialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -5558,13 +5558,11 @@ function deserializeTSImportEqualsDeclaration(pos) {
function deserializeTSModuleReference(pos) {
switch (uint8[pos]) {
case 0:
return deserializeBoxIdentifierReference(pos + 8);
return deserializeBoxTSExternalModuleReference(pos + 8);
case 1:
return deserializeBoxTSQualifiedName(pos + 8);
return deserializeBoxIdentifierReference(pos + 8);
case 2:
return deserializeBoxThisExpression(pos + 8);
case 3:
return deserializeBoxTSExternalModuleReference(pos + 8);
return deserializeBoxTSQualifiedName(pos + 8);
default:
throw Error(`Unexpected discriminant ${uint8[pos]} for TSModuleReference`);
}
Expand Down
2 changes: 1 addition & 1 deletion apps/oxlint/src-js/generated/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1617,7 +1617,7 @@ export interface TSImportEqualsDeclaration extends Span {
parent: Node;
}

export type TSModuleReference = TSExternalModuleReference | TSTypeName;
export type TSModuleReference = TSExternalModuleReference | IdentifierReference | TSQualifiedName;

export interface TSExternalModuleReference extends Span {
type: "TSExternalModuleReference";
Expand Down
18 changes: 11 additions & 7 deletions crates/oxc_ast/src/ast/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1628,20 +1628,24 @@ pub struct TSImportEqualsDeclaration<'a> {
pub import_kind: ImportOrExportKind,
}

inherit_variants! {
/// TS Module Reference
///
/// Inherits variants from [`TSTypeName`]. See [`ast` module docs] for explanation of inheritance.
/// The right-hand side of an `import x = ...` declaration.
///
/// [`ast` module docs]: `super`
/// ## Examples
///
/// ```ts
/// import x = foo; // IdentifierReference
/// import x = foo.bar; // QualifiedName
/// import x = require("x"); // ExternalModuleReference
/// ```
#[ast(visit)]
#[derive(Debug)]
#[generate_derive(CloneIn, Dummy, TakeIn, GetSpan, GetSpanMut, GetAddress, ContentEq, ESTree)]
pub enum TSModuleReference<'a> {
ExternalModuleReference(Box<'a, TSExternalModuleReference<'a>>) = 3,
// `TSTypeName` variants added here by `inherit_variants!` macro
@inherit TSTypeName
}
ExternalModuleReference(Box<'a, TSExternalModuleReference<'a>>) = 0,
IdentifierReference(Box<'a, IdentifierReference<'a>>) = 1,
QualifiedName(Box<'a, TSQualifiedName<'a>>) = 2,
}

#[ast(visit)]
Expand Down
62 changes: 62 additions & 0 deletions crates/oxc_ast/src/generated/ast_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14857,6 +14857,68 @@ impl<'a> AstBuilder<'a> {
)
}

/// Build a [`TSModuleReference::IdentifierReference`].
///
/// This node contains an [`IdentifierReference`] that will be stored in the memory arena.
///
/// ## Parameters
/// * `span`: The [`Span`] covering this node
/// * `name`: The name of the identifier being referenced.
#[inline]
pub fn ts_module_reference_identifier_reference<A1>(
self,
span: Span,
name: A1,
) -> TSModuleReference<'a>
where
A1: Into<Ident<'a>>,
{
TSModuleReference::IdentifierReference(self.alloc_identifier_reference(span, name))
}

/// Build a [`TSModuleReference::IdentifierReference`] with `reference_id`.
///
/// This node contains an [`IdentifierReference`] that will be stored in the memory arena.
///
/// ## Parameters
/// * `span`: The [`Span`] covering this node
/// * `name`: The name of the identifier being referenced.
/// * `reference_id`: Reference ID
#[inline]
pub fn ts_module_reference_identifier_reference_with_reference_id<A1>(
self,
span: Span,
name: A1,
reference_id: ReferenceId,
) -> TSModuleReference<'a>
where
A1: Into<Ident<'a>>,
{
TSModuleReference::IdentifierReference(self.alloc_identifier_reference_with_reference_id(
span,
name,
reference_id,
))
}

/// Build a [`TSModuleReference::QualifiedName`].
///
/// This node contains a [`TSQualifiedName`] that will be stored in the memory arena.
///
/// ## Parameters
/// * `span`: The [`Span`] covering this node
/// * `left`
/// * `right`
#[inline]
pub fn ts_module_reference_qualified_name(
self,
span: Span,
left: TSTypeName<'a>,
right: IdentifierName<'a>,
) -> TSModuleReference<'a> {
TSModuleReference::QualifiedName(self.alloc_ts_qualified_name(span, left, right))
}

/// Build a [`TSExternalModuleReference`].
///
/// If you want the built node to be allocated in the memory arena,
Expand Down
6 changes: 0 additions & 6 deletions crates/oxc_ast/src/generated/derive_clone_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7757,9 +7757,6 @@ impl<'new_alloc> CloneIn<'new_alloc> for TSModuleReference<'_> {
Self::QualifiedName(it) => {
TSModuleReference::QualifiedName(CloneIn::clone_in(it, allocator))
}
Self::ThisExpression(it) => {
TSModuleReference::ThisExpression(CloneIn::clone_in(it, allocator))
}
}
}

Expand All @@ -7774,9 +7771,6 @@ impl<'new_alloc> CloneIn<'new_alloc> for TSModuleReference<'_> {
Self::QualifiedName(it) => {
TSModuleReference::QualifiedName(CloneIn::clone_in_with_semantic_ids(it, allocator))
}
Self::ThisExpression(it) => TSModuleReference::ThisExpression(
CloneIn::clone_in_with_semantic_ids(it, allocator),
),
}
}
}
Expand Down
1 change: 0 additions & 1 deletion crates/oxc_ast/src/generated/derive_content_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2434,7 +2434,6 @@ impl ContentEq for TSModuleReference<'_> {
(Self::ExternalModuleReference(a), Self::ExternalModuleReference(b)) => a.content_eq(b),
(Self::IdentifierReference(a), Self::IdentifierReference(b)) => a.content_eq(b),
(Self::QualifiedName(a), Self::QualifiedName(b)) => a.content_eq(b),
(Self::ThisExpression(a), Self::ThisExpression(b)) => a.content_eq(b),
_ => false,
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/oxc_ast/src/generated/derive_dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2798,7 +2798,7 @@ impl<'a> Dummy<'a> for TSTypeAssertion<'a> {
impl<'a> Dummy<'a> for TSImportEqualsDeclaration<'a> {
/// Create a dummy [`TSImportEqualsDeclaration`].
///
/// Has cost of making 1 allocation (8 bytes).
/// Has cost of making 1 allocation (32 bytes).
fn dummy(allocator: &'a Allocator) -> Self {
Self {
span: Dummy::dummy(allocator),
Expand All @@ -2812,9 +2812,9 @@ impl<'a> Dummy<'a> for TSImportEqualsDeclaration<'a> {
impl<'a> Dummy<'a> for TSModuleReference<'a> {
/// Create a dummy [`TSModuleReference`].
///
/// Has cost of making 1 allocation (8 bytes).
/// Has cost of making 1 allocation (32 bytes).
fn dummy(allocator: &'a Allocator) -> Self {
Self::ThisExpression(Dummy::dummy(allocator))
Self::IdentifierReference(Dummy::dummy(allocator))
}
}

Expand Down
1 change: 0 additions & 1 deletion crates/oxc_ast/src/generated/derive_estree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3111,7 +3111,6 @@ impl ESTree for TSModuleReference<'_> {
Self::ExternalModuleReference(it) => it.serialize(serializer),
Self::IdentifierReference(it) => it.serialize(serializer),
Self::QualifiedName(it) => it.serialize(serializer),
Self::ThisExpression(it) => it.serialize(serializer),
}
}
}
Expand Down
1 change: 0 additions & 1 deletion crates/oxc_ast/src/generated/derive_get_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,6 @@ impl GetAddress for TSModuleReference<'_> {
Self::ExternalModuleReference(it) => GetAddress::address(it),
Self::IdentifierReference(it) => GetAddress::address(it),
Self::QualifiedName(it) => GetAddress::address(it),
Self::ThisExpression(it) => GetAddress::address(it),
}
}
}
1 change: 0 additions & 1 deletion crates/oxc_ast/src/generated/derive_get_span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2113,7 +2113,6 @@ impl GetSpan for TSModuleReference<'_> {
Self::ExternalModuleReference(it) => GetSpan::span(&**it),
Self::IdentifierReference(it) => GetSpan::span(&**it),
Self::QualifiedName(it) => GetSpan::span(&**it),
Self::ThisExpression(it) => GetSpan::span(&**it),
}
}
}
Expand Down
1 change: 0 additions & 1 deletion crates/oxc_ast/src/generated/derive_get_span_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2113,7 +2113,6 @@ impl GetSpanMut for TSModuleReference<'_> {
Self::ExternalModuleReference(it) => GetSpanMut::span_mut(&mut **it),
Self::IdentifierReference(it) => GetSpanMut::span_mut(&mut **it),
Self::QualifiedName(it) => GetSpanMut::span_mut(&mut **it),
Self::ThisExpression(it) => GetSpanMut::span_mut(&mut **it),
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions crates/oxc_ast_visit/src/generated/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4127,9 +4127,8 @@ pub mod walk {
TSModuleReference::ExternalModuleReference(it) => {
visitor.visit_ts_external_module_reference(it)
}
match_ts_type_name!(TSModuleReference) => {
visitor.visit_ts_type_name(it.to_ts_type_name())
}
TSModuleReference::IdentifierReference(it) => visitor.visit_identifier_reference(it),
TSModuleReference::QualifiedName(it) => visitor.visit_ts_qualified_name(it),
}
}

Expand Down
5 changes: 2 additions & 3 deletions crates/oxc_ast_visit/src/generated/visit_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4351,9 +4351,8 @@ pub mod walk_mut {
TSModuleReference::ExternalModuleReference(it) => {
visitor.visit_ts_external_module_reference(it)
}
match_ts_type_name!(TSModuleReference) => {
visitor.visit_ts_type_name(it.to_ts_type_name_mut())
}
TSModuleReference::IdentifierReference(it) => visitor.visit_identifier_reference(it),
TSModuleReference::QualifiedName(it) => visitor.visit_ts_qualified_name(it),
}
}

Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3844,7 +3844,8 @@ impl Gen for TSModuleReference<'_> {
p.print_string_literal(&decl.expression, false);
p.print_ascii_byte(b')');
}
match_ts_type_name!(Self) => self.to_ts_type_name().print(p, ctx),
Self::IdentifierReference(ident) => ident.print(p, ctx),
Self::QualifiedName(qualified) => qualified.print(p, ctx),
}
}
}
Expand Down
25 changes: 15 additions & 10 deletions crates/oxc_formatter/src/ast_nodes/generated/ast_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9433,16 +9433,21 @@ impl<'a> AstNode<'a, TSModuleReference<'a>> {
following_span_start: self.following_span_start,
}))
}
it @ match_ts_type_name!(TSModuleReference) => {
return self
.allocator
.alloc(AstNode {
inner: it.to_ts_type_name(),
parent,
allocator: self.allocator,
following_span_start: self.following_span_start,
})
.as_ast_nodes();
TSModuleReference::IdentifierReference(s) => {
AstNodes::IdentifierReference(self.allocator.alloc(AstNode {
inner: s.as_ref(),
parent,
allocator: self.allocator,
following_span_start: self.following_span_start,
}))
}
TSModuleReference::QualifiedName(s) => {
AstNodes::TSQualifiedName(self.allocator.alloc(AstNode {
inner: s.as_ref(),
parent,
allocator: self.allocator,
following_span_start: self.following_span_start,
}))
}
};
self.allocator.alloc(node)
Expand Down
15 changes: 12 additions & 3 deletions crates/oxc_formatter/src/ast_nodes/generated/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5519,10 +5519,19 @@ impl<'a> Format<'a> for AstNode<'a, TSModuleReference<'a>> {
})
.fmt(f);
}
it @ match_ts_type_name!(TSModuleReference) => {
let inner = it.to_ts_type_name();
TSModuleReference::IdentifierReference(inner) => {
allocator
.alloc(AstNode::<'a, TSTypeName> {
.alloc(AstNode::<IdentifierReference> {
inner,
parent,
allocator,
following_span_start: self.following_span_start,
})
.fmt(f);
}
TSModuleReference::QualifiedName(inner) => {
allocator
.alloc(AstNode::<TSQualifiedName> {
inner,
parent,
allocator,
Expand Down
3 changes: 1 addition & 2 deletions crates/oxc_linter/src/rules/import/first.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ impl Rule for First {
}
}
TSModuleReference::IdentifierReference(_)
| TSModuleReference::QualifiedName(_)
| TSModuleReference::ThisExpression(_) => {}
| TSModuleReference::QualifiedName(_) => {}
},
Statement::ImportDeclaration(decl) => {
if matches!(self.0, AbsoluteFirst::AbsoluteFirst) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,8 @@ impl Rule for NoRequireImports {

ctx.diagnostic(no_require_imports_diagnostic(decl.span));
}
TSModuleReference::IdentifierReference(_)
| TSModuleReference::QualifiedName(_)
| TSModuleReference::ThisExpression(_) => {}
TSModuleReference::IdentifierReference(_) | TSModuleReference::QualifiedName(_) => {
}
},
_ => {}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,7 @@ impl Rule for TripleSlashReference {
}
}
TSModuleReference::IdentifierReference(_)
| TSModuleReference::QualifiedName(_)
| TSModuleReference::ThisExpression(_) => {}
| TSModuleReference::QualifiedName(_) => {}
},
Statement::ImportDeclaration(decl) => {
if let Some(v) = refs_for_import.get(decl.source.value.as_str()) {
Expand Down
36 changes: 34 additions & 2 deletions crates/oxc_parser/src/ts/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,8 +573,7 @@ impl<'a> ParserImpl<'a> {
expression,
)
} else {
let type_name = self.parse_ts_type_name();
TSModuleReference::from(type_name)
self.parse_ts_module_reference(reference_span)
};

self.asi();
Expand All @@ -588,6 +587,39 @@ impl<'a> ParserImpl<'a> {
self.ast.declaration_ts_import_equals(span, identifier, module_reference, import_kind)
}

/// Parse `TSModuleReference` for `import x = foo` or `import x = foo.bar`.
///
/// Unlike `parse_ts_type_name`, this does not allow `this` as the identifier.
fn parse_ts_module_reference(&mut self, span: u32) -> TSModuleReference<'a> {
// Check for invalid `this` keyword
if self.at(Kind::This) {
let this_span = self.cur_token().span();
self.error(diagnostics::identifier_reserved_word(this_span, "this"));
self.bump_any();
// Recover by creating a dummy identifier
let ident = self.ast.alloc_identifier_reference(this_span, "this");
return TSModuleReference::IdentifierReference(ident);
}

let ident = self.parse_identifier_name();
let left = self.ast.ts_type_name_identifier_reference(ident.span, ident.name);

// Parse qualified name: foo.bar.baz
let type_name =
if self.at(Kind::Dot) { self.parse_ts_qualified_type_name(span, left) } else { left };

// Convert TSTypeName to TSModuleReference
match type_name {
TSTypeName::IdentifierReference(ident) => TSModuleReference::IdentifierReference(ident),
TSTypeName::QualifiedName(qualified) => TSModuleReference::QualifiedName(qualified),
TSTypeName::ThisExpression(_) => {
// This shouldn't happen since we check for `this` above,
// but handle it for completeness
unreachable!("ThisExpression should have been caught earlier")
}
}
}

pub(crate) fn parse_ts_this_parameter(&mut self) -> TSThisParameter<'a> {
let span = self.start_span();
self.bump_any();
Expand Down
Loading
Loading