mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(transformer/typescript): replace reference collector with symbols references (#3533)
https://github.com/oxc-project/oxc/pull/3524 handled the references correctly, now we can remove the reference collector.
This commit is contained in:
parent
ee9a215a21
commit
6978269be0
10 changed files with 108 additions and 99 deletions
|
|
@ -60,6 +60,10 @@ impl Reference {
|
||||||
self.symbol_id = Some(symbol_id);
|
self.symbol_id = Some(symbol_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn flag_mut(&mut self) -> &mut ReferenceFlag {
|
||||||
|
&mut self.flag
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if the identifier value was read. This is not mutually
|
/// Returns `true` if the identifier value was read. This is not mutually
|
||||||
/// exclusive with [`#is_write`]
|
/// exclusive with [`#is_write`]
|
||||||
pub fn is_read(&self) -> bool {
|
pub fn is_read(&self) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,10 @@ impl SymbolTable {
|
||||||
&self.references[reference_id]
|
&self.references[reference_id]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_reference_mut(&mut self, reference_id: ReferenceId) -> &mut Reference {
|
||||||
|
&mut self.references[reference_id]
|
||||||
|
}
|
||||||
|
|
||||||
pub fn has_binding(&self, reference_id: ReferenceId) -> bool {
|
pub fn has_binding(&self, reference_id: ReferenceId) -> bool {
|
||||||
self.references[reference_id].symbol_id().is_some()
|
self.references[reference_id].symbol_id().is_some()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ use oxc_allocator::Allocator;
|
||||||
use oxc_codegen::{Codegen, CodegenOptions};
|
use oxc_codegen::{Codegen, CodegenOptions};
|
||||||
use oxc_parser::Parser;
|
use oxc_parser::Parser;
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
use oxc_transformer::{TransformOptions, Transformer};
|
use oxc_transformer::{
|
||||||
|
ArrowFunctionsOptions, ES2015Options, ReactOptions, TransformOptions, Transformer,
|
||||||
|
TypeScriptOptions,
|
||||||
|
};
|
||||||
|
|
||||||
// Instruction:
|
// Instruction:
|
||||||
// create a `test.js`,
|
// create a `test.js`,
|
||||||
|
|
@ -32,7 +35,17 @@ fn main() {
|
||||||
println!("{source_text}\n");
|
println!("{source_text}\n");
|
||||||
|
|
||||||
let mut program = ret.program;
|
let mut program = ret.program;
|
||||||
let transform_options = TransformOptions::default();
|
let transform_options = TransformOptions {
|
||||||
|
typescript: TypeScriptOptions::default(),
|
||||||
|
es2015: ES2015Options { arrow_function: Some(ArrowFunctionsOptions::default()) },
|
||||||
|
react: ReactOptions {
|
||||||
|
jsx_plugin: true,
|
||||||
|
jsx_self_plugin: true,
|
||||||
|
jsx_source_plugin: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
Transformer::new(&allocator, path, source_type, &source_text, &ret.trivias, transform_options)
|
Transformer::new(&allocator, path, source_type, &source_text, &ret.trivias, transform_options)
|
||||||
.build(&mut program)
|
.build(&mut program)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -102,9 +102,9 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
||||||
self.x0_typescript.transform_program(program, ctx);
|
self.x0_typescript.transform_program(program, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit_program(&mut self, program: &mut Program<'a>, _ctx: &mut TraverseCtx<'a>) {
|
fn exit_program(&mut self, program: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x1_react.transform_program_on_exit(program);
|
self.x1_react.transform_program_on_exit(program);
|
||||||
self.x0_typescript.transform_program_on_exit(program);
|
self.x0_typescript.transform_program_on_exit(program, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ALPHASORT
|
// ALPHASORT
|
||||||
|
|
@ -232,20 +232,12 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
||||||
self.x0_typescript.transform_tagged_template_expression(expr);
|
self.x0_typescript.transform_tagged_template_expression(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_identifier_reference(
|
|
||||||
&mut self,
|
|
||||||
ident: &mut IdentifierReference<'a>,
|
|
||||||
ctx: &mut TraverseCtx<'a>,
|
|
||||||
) {
|
|
||||||
self.x0_typescript.transform_identifier_reference(ident, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x0_typescript.transform_statement(stmt, ctx);
|
self.x0_typescript.transform_statement(stmt, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, _ctx: &mut TraverseCtx<'a>) {
|
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.x0_typescript.transform_declaration(decl);
|
self.x0_typescript.transform_declaration(decl, ctx);
|
||||||
self.x3_es2015.transform_declaration(decl);
|
self.x3_es2015.transform_declaration(decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,9 @@ use oxc_allocator::Vec;
|
||||||
use oxc_ast::ast::*;
|
use oxc_ast::ast::*;
|
||||||
use oxc_span::{Atom, SPAN};
|
use oxc_span::{Atom, SPAN};
|
||||||
use oxc_syntax::operator::AssignmentOperator;
|
use oxc_syntax::operator::AssignmentOperator;
|
||||||
|
use oxc_traverse::TraverseCtx;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
use super::collector::TypeScriptReferenceCollector;
|
|
||||||
|
|
||||||
pub struct TypeScriptAnnotations<'a> {
|
pub struct TypeScriptAnnotations<'a> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
options: Rc<TypeScriptOptions>,
|
options: Rc<TypeScriptOptions>,
|
||||||
|
|
@ -25,6 +24,7 @@ pub struct TypeScriptAnnotations<'a> {
|
||||||
has_jsx_fragment: bool,
|
has_jsx_fragment: bool,
|
||||||
jsx_element_import_name: String,
|
jsx_element_import_name: String,
|
||||||
jsx_fragment_import_name: String,
|
jsx_fragment_import_name: String,
|
||||||
|
type_identifier_names: FxHashSet<Atom<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeScriptAnnotations<'a> {
|
impl<'a> TypeScriptAnnotations<'a> {
|
||||||
|
|
@ -50,6 +50,7 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
has_jsx_fragment: false,
|
has_jsx_fragment: false,
|
||||||
jsx_element_import_name,
|
jsx_element_import_name,
|
||||||
jsx_fragment_import_name,
|
jsx_fragment_import_name,
|
||||||
|
type_identifier_names: FxHashSet::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,19 +83,20 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
|
|
||||||
// Remove type only imports/exports
|
// Remove type only imports/exports
|
||||||
pub fn transform_program_on_exit(
|
pub fn transform_program_on_exit(
|
||||||
&self,
|
&mut self,
|
||||||
program: &mut Program<'a>,
|
program: &mut Program<'a>,
|
||||||
references: &TypeScriptReferenceCollector,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) {
|
) {
|
||||||
let mut type_names = FxHashSet::default();
|
|
||||||
let mut module_count = 0;
|
let mut module_count = 0;
|
||||||
let mut removed_count = 0;
|
let mut removed_count = 0;
|
||||||
|
|
||||||
|
// let mut type_identifier_names = self.type_identifier_names.clone();
|
||||||
|
|
||||||
program.body.retain_mut(|stmt| {
|
program.body.retain_mut(|stmt| {
|
||||||
// fix namespace/export-type-only/input.ts
|
// fix namespace/export-type-only/input.ts
|
||||||
// The namespace is type only. So if its name appear in the ExportNamedDeclaration, we should remove it.
|
// The namespace is type only. So if its name appear in the ExportNamedDeclaration, we should remove it.
|
||||||
if let Statement::TSModuleDeclaration(decl) = stmt {
|
if let Statement::TSModuleDeclaration(decl) = stmt {
|
||||||
type_names.insert(decl.id.name().clone());
|
self.type_identifier_names.insert(decl.id.name().clone());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,7 +108,7 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
ModuleDeclaration::ExportNamedDeclaration(decl) => {
|
ModuleDeclaration::ExportNamedDeclaration(decl) => {
|
||||||
decl.specifiers.retain(|specifier| {
|
decl.specifiers.retain(|specifier| {
|
||||||
!(specifier.export_kind.is_type()
|
!(specifier.export_kind.is_type()
|
||||||
|| type_names.contains(specifier.exported.name()))
|
|| self.type_identifier_names.contains(specifier.exported.name()))
|
||||||
});
|
});
|
||||||
|
|
||||||
decl.export_kind.is_type()
|
decl.export_kind.is_type()
|
||||||
|
|
@ -117,6 +119,9 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
.is_some_and(Declaration::is_typescript_syntax))
|
.is_some_and(Declaration::is_typescript_syntax))
|
||||||
&& decl.specifiers.is_empty())
|
&& decl.specifiers.is_empty())
|
||||||
}
|
}
|
||||||
|
ModuleDeclaration::ExportAllDeclaration(decl) => {
|
||||||
|
return !decl.export_kind.is_type()
|
||||||
|
}
|
||||||
ModuleDeclaration::ImportDeclaration(decl) => {
|
ModuleDeclaration::ImportDeclaration(decl) => {
|
||||||
let is_type = decl.import_kind.is_type();
|
let is_type = decl.import_kind.is_type();
|
||||||
|
|
||||||
|
|
@ -127,7 +132,7 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
specifiers.retain(|specifier| match specifier {
|
specifiers.retain(|specifier| match specifier {
|
||||||
ImportDeclarationSpecifier::ImportSpecifier(s) => {
|
ImportDeclarationSpecifier::ImportSpecifier(s) => {
|
||||||
if is_type || s.import_kind.is_type() {
|
if is_type || s.import_kind.is_type() {
|
||||||
type_names.insert(s.local.name.clone());
|
self.type_identifier_names.insert(s.local.name.clone());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,32 +140,31 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
references.has_reference(&s.local.name)
|
self.has_value_reference(&s.local.name, ctx)
|
||||||
|| self.is_jsx_imports(&s.local.name)
|
|
||||||
}
|
}
|
||||||
ImportDeclarationSpecifier::ImportDefaultSpecifier(s) => {
|
ImportDeclarationSpecifier::ImportDefaultSpecifier(s) => {
|
||||||
if is_type {
|
if is_type {
|
||||||
type_names.insert(s.local.name.clone());
|
self.type_identifier_names.insert(s.local.name.clone());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.options.only_remove_type_imports {
|
if self.options.only_remove_type_imports {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
references.has_reference(&s.local.name)
|
|
||||||
|| self.is_jsx_imports(&s.local.name)
|
self.has_value_reference(&s.local.name, ctx)
|
||||||
}
|
}
|
||||||
ImportDeclarationSpecifier::ImportNamespaceSpecifier(s) => {
|
ImportDeclarationSpecifier::ImportNamespaceSpecifier(s) => {
|
||||||
if is_type {
|
if is_type {
|
||||||
type_names.insert(s.local.name.clone());
|
self.type_identifier_names.insert(s.local.name.clone());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.options.only_remove_type_imports {
|
if self.options.only_remove_type_imports {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
references.has_reference(&s.local.name)
|
self.has_value_reference(&s.local.name, ctx)
|
||||||
|| self.is_jsx_imports(&s.local.name)
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -428,4 +432,32 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
pub fn transform_jsx_fragment(&mut self, _elem: &mut JSXFragment<'a>) {
|
pub fn transform_jsx_fragment(&mut self, _elem: &mut JSXFragment<'a>) {
|
||||||
self.has_jsx_fragment = true;
|
self.has_jsx_fragment = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn transform_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) {
|
||||||
|
let is_type = decl.export_kind.is_type();
|
||||||
|
for specifier in &decl.specifiers {
|
||||||
|
if is_type || specifier.export_kind.is_type() {
|
||||||
|
self.type_identifier_names.insert(specifier.local.name().clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_value_reference(&self, name: &Atom<'a>, ctx: &TraverseCtx<'a>) -> bool {
|
||||||
|
if let Some(symbol_id) = ctx.scopes().get_root_binding(name) {
|
||||||
|
if ctx.symbols().get_flag(symbol_id).is_export()
|
||||||
|
&& !self.type_identifier_names.contains(name)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ctx
|
||||||
|
.symbols()
|
||||||
|
.get_resolved_references(symbol_id)
|
||||||
|
.any(|reference| !reference.is_type())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.is_jsx_imports(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
use oxc_ast::ast::{ExportNamedDeclaration, IdentifierReference};
|
|
||||||
use oxc_span::Atom;
|
|
||||||
use rustc_hash::FxHashSet;
|
|
||||||
|
|
||||||
/// Collects identifier references
|
|
||||||
/// Indicates whether the BindingIdentifier is referenced or used in the ExportNamedDeclaration
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TypeScriptReferenceCollector<'a> {
|
|
||||||
names: FxHashSet<Atom<'a>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TypeScriptReferenceCollector<'a> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self { names: FxHashSet::default() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_reference(&self, name: &Atom) -> bool {
|
|
||||||
self.names.contains(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn visit_identifier_reference(&mut self, ident: &IdentifierReference<'a>) {
|
|
||||||
self.names.insert(ident.name.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn visit_transform_export_named_declaration(&mut self, decl: &ExportNamedDeclaration<'a>) {
|
|
||||||
if decl.export_kind.is_type() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for specifier in &decl.specifiers {
|
|
||||||
if specifier.export_kind.is_value() {
|
|
||||||
self.names.insert(specifier.local.name().clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
mod annotations;
|
mod annotations;
|
||||||
mod collector;
|
|
||||||
mod diagnostics;
|
mod diagnostics;
|
||||||
mod r#enum;
|
mod r#enum;
|
||||||
mod module;
|
mod module;
|
||||||
|
|
@ -14,10 +13,7 @@ use oxc_traverse::TraverseCtx;
|
||||||
|
|
||||||
use crate::context::Ctx;
|
use crate::context::Ctx;
|
||||||
|
|
||||||
use self::{
|
use self::{annotations::TypeScriptAnnotations, r#enum::TypeScriptEnum};
|
||||||
annotations::TypeScriptAnnotations, collector::TypeScriptReferenceCollector,
|
|
||||||
r#enum::TypeScriptEnum,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use self::options::TypeScriptOptions;
|
pub use self::options::TypeScriptOptions;
|
||||||
|
|
||||||
|
|
@ -49,7 +45,6 @@ pub struct TypeScript<'a> {
|
||||||
|
|
||||||
annotations: TypeScriptAnnotations<'a>,
|
annotations: TypeScriptAnnotations<'a>,
|
||||||
r#enum: TypeScriptEnum<'a>,
|
r#enum: TypeScriptEnum<'a>,
|
||||||
reference_collector: TypeScriptReferenceCollector<'a>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeScript<'a> {
|
impl<'a> TypeScript<'a> {
|
||||||
|
|
@ -59,7 +54,6 @@ impl<'a> TypeScript<'a> {
|
||||||
Self {
|
Self {
|
||||||
annotations: TypeScriptAnnotations::new(&options, ctx),
|
annotations: TypeScriptAnnotations::new(&options, ctx),
|
||||||
r#enum: TypeScriptEnum::new(ctx),
|
r#enum: TypeScriptEnum::new(ctx),
|
||||||
reference_collector: TypeScriptReferenceCollector::new(),
|
|
||||||
options,
|
options,
|
||||||
ctx: Rc::clone(ctx),
|
ctx: Rc::clone(ctx),
|
||||||
}
|
}
|
||||||
|
|
@ -79,8 +73,12 @@ impl<'a> TypeScript<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_program_on_exit(&self, program: &mut Program<'a>) {
|
pub fn transform_program_on_exit(
|
||||||
self.annotations.transform_program_on_exit(program, &self.reference_collector);
|
&mut self,
|
||||||
|
program: &mut Program<'a>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) {
|
||||||
|
self.annotations.transform_program_on_exit(program, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) {
|
pub fn transform_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) {
|
||||||
|
|
@ -104,7 +102,7 @@ impl<'a> TypeScript<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) {
|
pub fn transform_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) {
|
||||||
self.reference_collector.visit_transform_export_named_declaration(decl);
|
self.annotations.transform_export_named_declaration(decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
||||||
|
|
@ -196,22 +194,12 @@ impl<'a> TypeScript<'a> {
|
||||||
self.annotations.transform_tagged_template_expression(expr);
|
self.annotations.transform_tagged_template_expression(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_identifier_reference(
|
pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
&mut self,
|
|
||||||
ident: &mut IdentifierReference<'a>,
|
|
||||||
ctx: &TraverseCtx<'a>,
|
|
||||||
) {
|
|
||||||
if !ctx.parent().is_ts_interface_heritage() && !ctx.parent().is_ts_type_reference() {
|
|
||||||
self.reference_collector.visit_identifier_reference(ident);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>) {
|
|
||||||
match decl {
|
match decl {
|
||||||
Declaration::TSImportEqualsDeclaration(ts_import_equals)
|
Declaration::TSImportEqualsDeclaration(ts_import_equals)
|
||||||
if ts_import_equals.import_kind.is_value() =>
|
if ts_import_equals.import_kind.is_value() =>
|
||||||
{
|
{
|
||||||
*decl = self.transform_ts_import_equals(ts_import_equals);
|
*decl = self.transform_ts_import_equals(ts_import_equals, ctx);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,31 @@
|
||||||
use oxc_allocator::Box;
|
use oxc_allocator::Box;
|
||||||
use oxc_ast::ast::*;
|
use oxc_ast::ast::*;
|
||||||
use oxc_span::SPAN;
|
use oxc_span::SPAN;
|
||||||
|
use oxc_syntax::reference::ReferenceFlag;
|
||||||
|
use oxc_traverse::TraverseCtx;
|
||||||
|
|
||||||
use super::TypeScript;
|
use super::TypeScript;
|
||||||
|
|
||||||
impl<'a> TypeScript<'a> {
|
impl<'a> TypeScript<'a> {
|
||||||
fn transform_ts_type_name(&self, type_name: &mut TSTypeName<'a>) -> Expression<'a> {
|
fn transform_ts_type_name(
|
||||||
|
&self,
|
||||||
|
type_name: &mut TSTypeName<'a>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) -> Expression<'a> {
|
||||||
match type_name {
|
match type_name {
|
||||||
TSTypeName::IdentifierReference(reference) => {
|
TSTypeName::IdentifierReference(ident) => {
|
||||||
self.ctx.ast.identifier_reference_expression(IdentifierReference::new(
|
ident.reference_flag = ReferenceFlag::Read;
|
||||||
SPAN,
|
if let Some(reference_id) = ident.reference_id.get() {
|
||||||
reference.name.clone(),
|
let reference = ctx.symbols_mut().get_reference_mut(reference_id);
|
||||||
))
|
*reference.flag_mut() = ReferenceFlag::Read;
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
self.ctx.ast.identifier_reference_expression(ctx.ast.copy(ident))
|
||||||
}
|
}
|
||||||
TSTypeName::QualifiedName(qualified_name) => self.ctx.ast.static_member_expression(
|
TSTypeName::QualifiedName(qualified_name) => self.ctx.ast.static_member_expression(
|
||||||
SPAN,
|
SPAN,
|
||||||
self.transform_ts_type_name(&mut qualified_name.left),
|
self.transform_ts_type_name(&mut qualified_name.left, ctx),
|
||||||
qualified_name.right.clone(),
|
qualified_name.right.clone(),
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
|
@ -33,6 +43,7 @@ impl<'a> TypeScript<'a> {
|
||||||
pub fn transform_ts_import_equals(
|
pub fn transform_ts_import_equals(
|
||||||
&self,
|
&self,
|
||||||
decl: &mut Box<'a, TSImportEqualsDeclaration<'a>>,
|
decl: &mut Box<'a, TSImportEqualsDeclaration<'a>>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) -> Declaration<'a> {
|
) -> Declaration<'a> {
|
||||||
let kind = VariableDeclarationKind::Var;
|
let kind = VariableDeclarationKind::Var;
|
||||||
let decls = {
|
let decls = {
|
||||||
|
|
@ -43,7 +54,7 @@ impl<'a> TypeScript<'a> {
|
||||||
|
|
||||||
let init = match &mut decl.module_reference {
|
let init = match &mut decl.module_reference {
|
||||||
type_name @ match_ts_type_name!(TSModuleReference) => {
|
type_name @ match_ts_type_name!(TSModuleReference) => {
|
||||||
self.transform_ts_type_name(&mut *type_name.to_ts_type_name_mut())
|
self.transform_ts_type_name(&mut *type_name.to_ts_type_name_mut(), ctx)
|
||||||
}
|
}
|
||||||
TSModuleReference::ExternalModuleReference(reference) => {
|
TSModuleReference::ExternalModuleReference(reference) => {
|
||||||
if self.ctx.source_type.is_module() {
|
if self.ctx.source_type.is_module() {
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@
|
||||||
//! scheme could very easily be derailed entirely by a single mistake, so in my opinion, it's unwise
|
//! scheme could very easily be derailed entirely by a single mistake, so in my opinion, it's unwise
|
||||||
//! to edit by hand.
|
//! to edit by hand.
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use oxc_allocator::Allocator;
|
use oxc_allocator::Allocator;
|
||||||
use oxc_ast::ast::Program;
|
use oxc_ast::ast::Program;
|
||||||
use oxc_semantic::SemanticBuilder;
|
use oxc_semantic::SemanticBuilder;
|
||||||
|
|
@ -147,6 +149,7 @@ pub fn traverse_mut<'a, Tr: Traverse<'a>>(
|
||||||
) {
|
) {
|
||||||
let semantic = SemanticBuilder::new(source_text, source_type)
|
let semantic = SemanticBuilder::new(source_text, source_type)
|
||||||
.with_check_syntax_error(true)
|
.with_check_syntax_error(true)
|
||||||
|
.build_module_record(PathBuf::default(), program)
|
||||||
.build(program)
|
.build(program)
|
||||||
.semantic;
|
.semantic;
|
||||||
let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree();
|
let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree();
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@ commit: 64d2eeea
|
||||||
|
|
||||||
transformer_typescript Summary:
|
transformer_typescript Summary:
|
||||||
AST Parsed : 5243/5243 (100.00%)
|
AST Parsed : 5243/5243 (100.00%)
|
||||||
Positive Passed: 5238/5243 (99.90%)
|
Positive Passed: 5240/5243 (99.94%)
|
||||||
Mismatch: "compiler/elidedEmbeddedStatementsReplacedWithSemicolon.ts"
|
Mismatch: "compiler/elidedEmbeddedStatementsReplacedWithSemicolon.ts"
|
||||||
Mismatch: "compiler/jsxComplexSignatureHasApplicabilityError.tsx"
|
Mismatch: "compiler/jsxComplexSignatureHasApplicabilityError.tsx"
|
||||||
Mismatch: "compiler/jsxEmptyExpressionNotCountedAsChild.tsx"
|
|
||||||
Mismatch: "compiler/styledComponentsInstantiaionLimitNotReached.ts"
|
|
||||||
Mismatch: "compiler/tsxReactPropsInferenceSucceedsOnIntersections.tsx"
|
Mismatch: "compiler/tsxReactPropsInferenceSucceedsOnIntersections.tsx"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue