fix(es/typescript): Analyze import chain (#9369)

- Closes #9368

---------

Co-authored-by: Donny/강동윤 <kdy1997.dev@gmail.com>
This commit is contained in:
magic-akari 2024-08-02 09:15:18 +08:00 committed by GitHub
parent 4190657218
commit 4f9116f925
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 70 additions and 14 deletions

View File

@ -0,0 +1,5 @@
---
swc_ecma_transforms_typescript: patch
---
fix(es/typescript): Analyze import chain

View File

@ -38,9 +38,8 @@ define([
//// [foo_1.ts]
define([
"require",
"exports",
"./foo_0"
], function(require, exports, _foo_0) {
"exports"
], function(require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true

View File

@ -27,9 +27,8 @@ define([
//// [foo_1.ts]
define([
"require",
"exports",
"./foo_0"
], function(require, exports, _foo_0) {
"exports"
], function(require, exports) {
Object.defineProperty(exports, "__esModule", {
value: !0
});

View File

@ -35,7 +35,6 @@ var E1;
Object.defineProperty(exports, "__esModule", {
value: true
});
var foo = require("./foo_0");
var i;
var x = {};
var y = false;

View File

@ -21,4 +21,4 @@ C1.s1 = !0, (E1 = E11 || (E11 = {}))[E1.A = 0] = "A", E1[E1.B = 1] = "B", E1[E1.
//// [foo_1.ts]
Object.defineProperty(exports, "__esModule", {
value: !0
}), require("./foo_0");
});

View File

@ -2,7 +2,6 @@
var C;
// no code gen expected
(function(C) {
var a = A;
var m;
var p;
var p = {

View File

@ -1,5 +1,5 @@
//// [importStatementsInterfaces.ts]
var C, D, E;
C || (C = {}), A, D || (D = {}), (E || (E = {})).xDist = function(x) {
C || (C = {}), D || (D = {}), (E || (E = {})).xDist = function(x) {
return 0 - x.x;
};

View File

@ -1,6 +1,6 @@
use std::mem;
use swc_common::collections::AHashSet;
use swc_common::collections::{AHashMap, AHashSet};
use swc_ecma_ast::*;
use swc_ecma_utils::stack_size::maybe_grow_default;
use swc_ecma_visit::{noop_visit_type, Visit, VisitMut, VisitMutWith, VisitWith};
@ -10,11 +10,15 @@ use crate::{strip_type::IsConcrete, ImportsNotUsedAsValues};
#[derive(Debug, Default)]
struct UsageCollect {
id_usage: AHashSet<Id>,
import_chain: AHashMap<Id, Id>,
}
impl From<AHashSet<Id>> for UsageCollect {
fn from(id_usage: AHashSet<Id>) -> Self {
Self { id_usage }
Self {
id_usage,
import_chain: Default::default(),
}
}
}
@ -68,7 +72,15 @@ impl Visit for UsageCollect {
return;
};
get_module_ident(ts_entity_name).visit_with(self);
let id = get_module_ident(ts_entity_name);
if n.is_export {
id.visit_with(self);
n.id.visit_with(self);
return;
}
self.import_chain.insert(n.id.to_id(), id.to_id());
}
fn visit_export_named_specifier(&mut self, n: &ExportNamedSpecifier) {
@ -101,6 +113,26 @@ impl UsageCollect {
fn has_usage(&self, id: &Id) -> bool {
self.id_usage.contains(id)
}
fn analyze_import_chain(&mut self) {
if self.import_chain.is_empty() {
return;
}
let mut new_usage = AHashSet::default();
for id in &self.id_usage {
let mut entry = self.import_chain.remove_entry(id);
while let Some((id, next)) = entry {
new_usage.insert(next);
entry = self.import_chain.remove_entry(&id);
}
if self.import_chain.is_empty() {
break;
}
}
self.import_chain.clear();
self.id_usage.extend(new_usage);
}
}
fn get_module_ident(ts_entity_name: &TsEntityName) -> &Ident {
@ -264,6 +296,8 @@ impl VisitMut for StripImportExport {
n.visit_with(&mut usage_info);
n.visit_with(&mut declare_info);
usage_info.analyze_import_chain();
let mut strip_ts_import_equals = StripTsImportEquals;
n.retain_mut(|module_item| match module_item {

View File

@ -1,2 +1 @@
import * as mongo from 'https://deno.land/x/mongo@v0.27.0/mod.ts';
const mongoClient = {};

View File

@ -0,0 +1,16 @@
import { Schemas } from './types.d';
import AddressResource = Schemas.AddressResource;
// type usage
const x: AddressResource = {};
import { foo, bar } from "mod";
// value usage
import y = foo.y;
// type usage
import z = bar.z;
console.log(y as z);

View File

@ -0,0 +1,6 @@
// type usage
const x = {};
import { foo } from "mod";
// value usage
const y = foo.y;
console.log(y);