mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
feat(ast): visit TSModuleReference (#1998)
### Failed cases: *7c29fbc4db/packages/babel-plugin-transform-typescript/test/fixtures/imports/elision-qualifiedname/input.ts*7c29fbc4db/packages/babel-plugin-transform-typescript/test/fixtures/imports/elide-react/input.tsWe need to distinguish whether a reference is a type or a js variable
This commit is contained in:
parent
afb2c501f5
commit
0a086860da
6 changed files with 132 additions and 17 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
//! [Archived TypeScript spec](https://github.com/microsoft/TypeScript/blob/3c99d50da5a579d9fa92d02664b1b66d4ff55944/doc/spec-ARCHIVED.md)
|
//! [Archived TypeScript spec](https://github.com/microsoft/TypeScript/blob/3c99d50da5a579d9fa92d02664b1b66d4ff55944/doc/spec-ARCHIVED.md)
|
||||||
|
|
||||||
use oxc_allocator::{Box, Vec};
|
use oxc_allocator::{Box, Vec};
|
||||||
use oxc_span::{Atom, Span};
|
use oxc_span::{Atom, GetSpan, Span};
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
|
@ -416,6 +416,15 @@ impl<'a> TSTypeName<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GetSpan for TSTypeName<'_> {
|
||||||
|
fn span(&self) -> Span {
|
||||||
|
match self {
|
||||||
|
TSTypeName::IdentifierReference(ident) => ident.span,
|
||||||
|
TSTypeName::QualifiedName(name) => name.span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type", rename_all = "camelCase"))]
|
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type", rename_all = "camelCase"))]
|
||||||
pub struct TSQualifiedName<'a> {
|
pub struct TSQualifiedName<'a> {
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,10 @@ pub enum AstKind<'a> {
|
||||||
TSEnumBody(&'a TSEnumBody<'a>),
|
TSEnumBody(&'a TSEnumBody<'a>),
|
||||||
|
|
||||||
TSImportEqualsDeclaration(&'a TSImportEqualsDeclaration<'a>),
|
TSImportEqualsDeclaration(&'a TSImportEqualsDeclaration<'a>),
|
||||||
|
TSTypeName(&'a TSTypeName<'a>),
|
||||||
|
TSExternalModuleReference(&'a TSExternalModuleReference),
|
||||||
|
TSQualifiedName(&'a TSQualifiedName<'a>),
|
||||||
|
|
||||||
TSInterfaceDeclaration(&'a TSInterfaceDeclaration<'a>),
|
TSInterfaceDeclaration(&'a TSInterfaceDeclaration<'a>),
|
||||||
TSModuleDeclaration(&'a TSModuleDeclaration<'a>),
|
TSModuleDeclaration(&'a TSModuleDeclaration<'a>),
|
||||||
TSTypeAliasDeclaration(&'a TSTypeAliasDeclaration<'a>),
|
TSTypeAliasDeclaration(&'a TSTypeAliasDeclaration<'a>),
|
||||||
|
|
@ -456,6 +460,9 @@ impl<'a> GetSpan for AstKind<'a> {
|
||||||
Self::TSEnumBody(x) => x.span,
|
Self::TSEnumBody(x) => x.span,
|
||||||
|
|
||||||
Self::TSImportEqualsDeclaration(x) => x.span,
|
Self::TSImportEqualsDeclaration(x) => x.span,
|
||||||
|
Self::TSTypeName(x) => x.span(),
|
||||||
|
Self::TSExternalModuleReference(x) => x.span,
|
||||||
|
Self::TSQualifiedName(x) => x.span,
|
||||||
Self::TSInterfaceDeclaration(x) => x.span,
|
Self::TSInterfaceDeclaration(x) => x.span,
|
||||||
Self::TSModuleDeclaration(x) => x.span,
|
Self::TSModuleDeclaration(x) => x.span,
|
||||||
Self::TSTypeAliasDeclaration(x) => x.span,
|
Self::TSTypeAliasDeclaration(x) => x.span,
|
||||||
|
|
@ -633,6 +640,9 @@ impl<'a> AstKind<'a> {
|
||||||
Self::TSEnumMember(_) => "TSEnumMember".into(),
|
Self::TSEnumMember(_) => "TSEnumMember".into(),
|
||||||
|
|
||||||
Self::TSImportEqualsDeclaration(_) => "TSImportEqualsDeclaration".into(),
|
Self::TSImportEqualsDeclaration(_) => "TSImportEqualsDeclaration".into(),
|
||||||
|
Self::TSTypeName(_) => "TSTypeName".into(),
|
||||||
|
Self::TSExternalModuleReference(_) => "TSExternalModuleReference".into(),
|
||||||
|
Self::TSQualifiedName(_) => "TSQualifiedName".into(),
|
||||||
Self::TSInterfaceDeclaration(_) => "TSInterfaceDeclaration".into(),
|
Self::TSInterfaceDeclaration(_) => "TSInterfaceDeclaration".into(),
|
||||||
Self::TSModuleDeclaration(_) => "TSModuleDeclaration".into(),
|
Self::TSModuleDeclaration(_) => "TSModuleDeclaration".into(),
|
||||||
Self::TSTypeAliasDeclaration(_) => "TSTypeAliasDeclaration".into(),
|
Self::TSTypeAliasDeclaration(_) => "TSTypeAliasDeclaration".into(),
|
||||||
|
|
|
||||||
|
|
@ -1451,6 +1451,41 @@ pub trait Visit<'a>: Sized {
|
||||||
let kind = AstKind::TSImportEqualsDeclaration(self.alloc(decl));
|
let kind = AstKind::TSImportEqualsDeclaration(self.alloc(decl));
|
||||||
self.enter_node(kind);
|
self.enter_node(kind);
|
||||||
self.visit_binding_identifier(&decl.id);
|
self.visit_binding_identifier(&decl.id);
|
||||||
|
self.visit_ts_module_reference(&decl.module_reference);
|
||||||
|
self.leave_node(kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ts_module_reference(&mut self, reference: &TSModuleReference<'a>) {
|
||||||
|
match reference {
|
||||||
|
TSModuleReference::TypeName(name) => self.visit_ts_type_name(name),
|
||||||
|
TSModuleReference::ExternalModuleReference(reference) => {
|
||||||
|
self.visit_ts_external_module_reference(reference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ts_type_name(&mut self, name: &TSTypeName<'a>) {
|
||||||
|
let kind = AstKind::TSTypeName(self.alloc(name));
|
||||||
|
self.enter_node(kind);
|
||||||
|
match &name {
|
||||||
|
TSTypeName::IdentifierReference(ident) => self.visit_identifier_reference(ident),
|
||||||
|
TSTypeName::QualifiedName(name) => self.visit_ts_qualified_name(name),
|
||||||
|
}
|
||||||
|
self.leave_node(kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ts_external_module_reference(&mut self, reference: &TSExternalModuleReference) {
|
||||||
|
let kind = AstKind::TSExternalModuleReference(self.alloc(reference));
|
||||||
|
self.enter_node(kind);
|
||||||
|
self.visit_string_literal(&reference.expression);
|
||||||
|
self.leave_node(kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ts_qualified_name(&mut self, name: &TSQualifiedName<'a>) {
|
||||||
|
let kind = AstKind::TSQualifiedName(self.alloc(name));
|
||||||
|
self.enter_node(kind);
|
||||||
|
self.visit_ts_type_name(&name.left);
|
||||||
|
self.visit_identifier_name(&name.right);
|
||||||
self.leave_node(kind);
|
self.leave_node(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1681,13 +1716,6 @@ pub trait Visit<'a>: Sized {
|
||||||
self.visit_ts_type(&ty.element_type);
|
self.visit_ts_type(&ty.element_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ts_type_name(&mut self, name: &TSTypeName<'a>) {
|
|
||||||
match &name {
|
|
||||||
TSTypeName::IdentifierReference(ident) => self.visit_identifier_reference(ident),
|
|
||||||
TSTypeName::QualifiedName(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_ts_null_keyword(&mut self, ty: &TSNullKeyword) {
|
fn visit_ts_null_keyword(&mut self, ty: &TSNullKeyword) {
|
||||||
let kind = AstKind::TSNullKeyword(self.alloc(ty));
|
let kind = AstKind::TSNullKeyword(self.alloc(ty));
|
||||||
self.enter_node(kind);
|
self.enter_node(kind);
|
||||||
|
|
|
||||||
|
|
@ -1443,6 +1443,41 @@ pub trait VisitMut<'a>: Sized {
|
||||||
let kind = AstKind::TSImportEqualsDeclaration(self.alloc(decl));
|
let kind = AstKind::TSImportEqualsDeclaration(self.alloc(decl));
|
||||||
self.enter_node(kind);
|
self.enter_node(kind);
|
||||||
self.visit_binding_identifier(&mut decl.id);
|
self.visit_binding_identifier(&mut decl.id);
|
||||||
|
self.visit_ts_module_reference(&mut decl.module_reference);
|
||||||
|
self.leave_node(kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ts_module_reference(&mut self, reference: &mut TSModuleReference<'a>) {
|
||||||
|
match reference {
|
||||||
|
TSModuleReference::TypeName(name) => self.visit_ts_type_name(name),
|
||||||
|
TSModuleReference::ExternalModuleReference(reference) => {
|
||||||
|
self.visit_ts_external_module_reference(reference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ts_type_name(&mut self, name: &mut TSTypeName<'a>) {
|
||||||
|
let kind = AstKind::TSTypeName(self.alloc(name));
|
||||||
|
self.enter_node(kind);
|
||||||
|
match name {
|
||||||
|
TSTypeName::IdentifierReference(ident) => self.visit_identifier_reference(ident),
|
||||||
|
TSTypeName::QualifiedName(name) => self.visit_ts_qualified_name(name),
|
||||||
|
}
|
||||||
|
self.leave_node(kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ts_external_module_reference(&mut self, reference: &mut TSExternalModuleReference) {
|
||||||
|
let kind = AstKind::TSExternalModuleReference(self.alloc(reference));
|
||||||
|
self.enter_node(kind);
|
||||||
|
self.visit_string_literal(&mut reference.expression);
|
||||||
|
self.leave_node(kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_ts_qualified_name(&mut self, name: &mut TSQualifiedName<'a>) {
|
||||||
|
let kind = AstKind::TSQualifiedName(self.alloc(name));
|
||||||
|
self.enter_node(kind);
|
||||||
|
self.visit_ts_type_name(&mut name.left);
|
||||||
|
self.visit_identifier_name(&mut name.right);
|
||||||
self.leave_node(kind);
|
self.leave_node(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1673,13 +1708,6 @@ pub trait VisitMut<'a>: Sized {
|
||||||
self.visit_ts_type(&mut ty.element_type);
|
self.visit_ts_type(&mut ty.element_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_ts_type_name(&mut self, name: &mut TSTypeName<'a>) {
|
|
||||||
match name {
|
|
||||||
TSTypeName::IdentifierReference(ident) => self.visit_identifier_reference(ident),
|
|
||||||
TSTypeName::QualifiedName(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_ts_null_keyword(&mut self, ty: &mut TSNullKeyword) {
|
fn visit_ts_null_keyword(&mut self, ty: &mut TSNullKeyword) {
|
||||||
let kind = AstKind::TSNullKeyword(self.alloc(ty));
|
let kind = AstKind::TSNullKeyword(self.alloc(ty));
|
||||||
self.enter_node(kind);
|
self.enter_node(kind);
|
||||||
|
|
|
||||||
|
|
@ -8624,6 +8624,38 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
16 │
|
16 │
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
× The keyword 'public' is reserved
|
||||||
|
╭─[compiler/strictModeReservedWord.ts:16:1]
|
||||||
|
16 │
|
||||||
|
17 │ var b: public.bar;
|
||||||
|
· ──────
|
||||||
|
18 │
|
||||||
|
╰────
|
||||||
|
|
||||||
|
× The keyword 'private' is reserved
|
||||||
|
╭─[compiler/strictModeReservedWord.ts:18:1]
|
||||||
|
18 │
|
||||||
|
19 │ function foo(x: private.x) { }
|
||||||
|
· ───────
|
||||||
|
20 │ function foo1(x: private.package.x) { }
|
||||||
|
╰────
|
||||||
|
|
||||||
|
× The keyword 'private' is reserved
|
||||||
|
╭─[compiler/strictModeReservedWord.ts:19:1]
|
||||||
|
19 │ function foo(x: private.x) { }
|
||||||
|
20 │ function foo1(x: private.package.x) { }
|
||||||
|
· ───────
|
||||||
|
21 │ function foo2(x: private.package.protected) { }
|
||||||
|
╰────
|
||||||
|
|
||||||
|
× The keyword 'private' is reserved
|
||||||
|
╭─[compiler/strictModeReservedWord.ts:20:1]
|
||||||
|
20 │ function foo1(x: private.package.x) { }
|
||||||
|
21 │ function foo2(x: private.package.protected) { }
|
||||||
|
· ───────
|
||||||
|
22 │ let b: interface.package.implements.B;
|
||||||
|
╰────
|
||||||
|
|
||||||
× Identifier `b` has already been declared
|
× Identifier `b` has already been declared
|
||||||
╭─[compiler/strictModeReservedWord.ts:16:1]
|
╭─[compiler/strictModeReservedWord.ts:16:1]
|
||||||
16 │
|
16 │
|
||||||
|
|
@ -8640,6 +8672,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
23 │ ublic();
|
23 │ ublic();
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
× The keyword 'interface' is reserved
|
||||||
|
╭─[compiler/strictModeReservedWord.ts:21:1]
|
||||||
|
21 │ function foo2(x: private.package.protected) { }
|
||||||
|
22 │ let b: interface.package.implements.B;
|
||||||
|
· ─────────
|
||||||
|
23 │ ublic();
|
||||||
|
╰────
|
||||||
|
|
||||||
× The keyword 'static' is reserved
|
× The keyword 'static' is reserved
|
||||||
╭─[compiler/strictModeReservedWord.ts:23:1]
|
╭─[compiler/strictModeReservedWord.ts:23:1]
|
||||||
23 │ ublic();
|
23 │ ublic();
|
||||||
|
|
|
||||||
|
|
@ -863,9 +863,10 @@ Passed: 298/1179
|
||||||
* imports/elide-injected/input.ts
|
* imports/elide-injected/input.ts
|
||||||
* imports/elide-no-import-specifiers/input.ts
|
* imports/elide-no-import-specifiers/input.ts
|
||||||
* imports/elide-preact/input.ts
|
* imports/elide-preact/input.ts
|
||||||
* imports/elide-type-referenced-in-imports-equal-no/input.ts
|
* imports/elide-react/input.ts
|
||||||
* imports/elision/input.ts
|
* imports/elision/input.ts
|
||||||
* imports/elision-locations/input.ts
|
* imports/elision-locations/input.ts
|
||||||
|
* imports/elision-qualifiedname/input.ts
|
||||||
* imports/elision-rename/input.ts
|
* imports/elision-rename/input.ts
|
||||||
* imports/enum-id/input.ts
|
* imports/enum-id/input.ts
|
||||||
* imports/enum-value/input.ts
|
* imports/enum-value/input.ts
|
||||||
|
|
@ -881,7 +882,6 @@ Passed: 298/1179
|
||||||
* imports/type-only-export-specifier-2/input.ts
|
* imports/type-only-export-specifier-2/input.ts
|
||||||
* imports/type-only-import-specifier-3/input.ts
|
* imports/type-only-import-specifier-3/input.ts
|
||||||
* imports/type-only-import-specifier-4/input.ts
|
* imports/type-only-import-specifier-4/input.ts
|
||||||
* namespace/alias/input.ts
|
|
||||||
* namespace/ambient-module-nested/input.ts
|
* namespace/ambient-module-nested/input.ts
|
||||||
* namespace/ambient-module-nested-exported/input.ts
|
* namespace/ambient-module-nested-exported/input.ts
|
||||||
* namespace/canonical/input.ts
|
* namespace/canonical/input.ts
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue