|
6 | 6 | "github.com/microsoft/typescript-go/internal/ast"
|
7 | 7 | "github.com/microsoft/typescript-go/internal/checker"
|
8 | 8 | "github.com/microsoft/typescript-go/internal/collections"
|
| 9 | + "github.com/microsoft/typescript-go/internal/compiler" |
9 | 10 | "github.com/microsoft/typescript-go/internal/core"
|
10 | 11 | "github.com/microsoft/typescript-go/internal/debug"
|
11 | 12 | )
|
@@ -42,6 +43,22 @@ type ImportsResult struct {
|
42 | 43 |
|
43 | 44 | type ImportTracker func(exportSymbol *ast.Symbol, exportInfo *ExportInfo, isForRename bool) *ImportsResult
|
44 | 45 |
|
| 46 | +type ModuleReferenceKind int32 |
| 47 | + |
| 48 | +const ( |
| 49 | + ModuleReferenceKindImport ModuleReferenceKind = iota |
| 50 | + ModuleReferenceKindReference |
| 51 | + ModuleReferenceKindImplicit |
| 52 | +) |
| 53 | + |
| 54 | +// ModuleReference represents a reference to a module, either via import, <reference>, or implicit reference |
| 55 | +type ModuleReference struct { |
| 56 | + kind ModuleReferenceKind |
| 57 | + literal *ast.Node // for import and implicit kinds (StringLiteralLike) |
| 58 | + referencingFile *ast.SourceFile |
| 59 | + ref *ast.FileReference // for reference kind |
| 60 | +} |
| 61 | + |
45 | 62 | // Creates the imports map and returns an ImportTracker that uses it. Call this lazily to avoid calling `getDirectImportsMap` unnecessarily.
|
46 | 63 | func createImportTracker(sourceFiles []*ast.SourceFile, sourceFilesSet *collections.Set[string], checker *checker.Checker) ImportTracker {
|
47 | 64 | allDirectImports := getDirectImportsMap(sourceFiles, checker)
|
@@ -654,3 +671,58 @@ func symbolNameNoDefault(symbol *ast.Symbol) string {
|
654 | 671 | }
|
655 | 672 | return ""
|
656 | 673 | }
|
| 674 | + |
| 675 | +// findModuleReferences finds all references to a module symbol across the given source files. |
| 676 | +// This includes import statements, <reference> directives, and implicit references (e.g., JSX runtime imports). |
| 677 | +func findModuleReferences(program *compiler.Program, sourceFiles []*ast.SourceFile, searchModuleSymbol *ast.Symbol, checker *checker.Checker) []ModuleReference { |
| 678 | + refs := []ModuleReference{} |
| 679 | + |
| 680 | + for _, referencingFile := range sourceFiles { |
| 681 | + searchSourceFile := searchModuleSymbol.ValueDeclaration |
| 682 | + if searchSourceFile != nil && searchSourceFile.Kind == ast.KindSourceFile { |
| 683 | + // Check <reference path> directives |
| 684 | + for _, ref := range referencingFile.ReferencedFiles { |
| 685 | + if program.GetSourceFileFromReference(referencingFile, ref) == searchSourceFile.AsSourceFile() { |
| 686 | + refs = append(refs, ModuleReference{ |
| 687 | + kind: ModuleReferenceKindReference, |
| 688 | + referencingFile: referencingFile, |
| 689 | + ref: ref, |
| 690 | + }) |
| 691 | + } |
| 692 | + } |
| 693 | + |
| 694 | + // Check <reference types> directives |
| 695 | + for _, ref := range referencingFile.TypeReferenceDirectives { |
| 696 | + referenced := program.GetResolvedTypeReferenceDirectiveFromTypeReferenceDirective(ref, referencingFile) |
| 697 | + if referenced != nil && referenced.ResolvedFileName == searchSourceFile.AsSourceFile().FileName() { |
| 698 | + refs = append(refs, ModuleReference{ |
| 699 | + kind: ModuleReferenceKindReference, |
| 700 | + referencingFile: referencingFile, |
| 701 | + ref: ref, |
| 702 | + }) |
| 703 | + } |
| 704 | + } |
| 705 | + } |
| 706 | + |
| 707 | + // Check all imports (including require() calls) |
| 708 | + forEachImport(referencingFile, func(importDecl *ast.Node, moduleSpecifier *ast.Node) { |
| 709 | + moduleSymbol := checker.GetSymbolAtLocation(moduleSpecifier) |
| 710 | + if moduleSymbol == searchModuleSymbol { |
| 711 | + if ast.NodeIsSynthesized(importDecl) { |
| 712 | + refs = append(refs, ModuleReference{ |
| 713 | + kind: ModuleReferenceKindImplicit, |
| 714 | + literal: moduleSpecifier, |
| 715 | + referencingFile: referencingFile, |
| 716 | + }) |
| 717 | + } else { |
| 718 | + refs = append(refs, ModuleReference{ |
| 719 | + kind: ModuleReferenceKindImport, |
| 720 | + literal: moduleSpecifier, |
| 721 | + }) |
| 722 | + } |
| 723 | + } |
| 724 | + }) |
| 725 | + } |
| 726 | + |
| 727 | + return refs |
| 728 | +} |
0 commit comments