Skip to content

Port IsSourceFileFromExternalLibrary, fix node18 emit #1234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 20, 2025
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions internal/compiler/emitHost.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,7 @@ func (host *emitHost) GetEmitResolver(file *ast.SourceFile, skipDiagnostics bool
defer done()
return checker.GetEmitResolver(file, skipDiagnostics)
}

func (host *emitHost) IsSourceFileFromExternalLibrary(file *ast.SourceFile) bool {
return host.program.IsSourceFileFromExternalLibrary(file)
}
6 changes: 1 addition & 5 deletions internal/compiler/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package compiler

import (
"encoding/base64"
"strings"

"github.com/microsoft/typescript-go/internal/ast"
"github.com/microsoft/typescript-go/internal/core"
Expand Down Expand Up @@ -305,10 +304,7 @@ func sourceFileMayBeEmitted(sourceFile *ast.SourceFile, host printer.EmitHost, f
return false
}

// !!! Source file from node_modules are not emitted. In Strada, this depends on module resolution and uses
// `sourceFilesFoundSearchingNodeModules` in `createProgram`. For now, we will just check for `/node_modules/` in
// the file name.
if strings.Contains(sourceFile.FileName(), "/node_modules/") {
if host.IsSourceFileFromExternalLibrary(sourceFile) {
return false
}

Expand Down
42 changes: 25 additions & 17 deletions internal/compiler/fileloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ type processedFiles struct {
jsxRuntimeImportSpecifiers map[tspath.Path]*jsxRuntimeImportSpecifier
importHelpersImportSpecifiers map[tspath.Path]*ast.Node
// List of present unsupported extensions
unsupportedExtensions []string
unsupportedExtensions []string
sourceFilesFoundSearchingNodeModules collections.Set[tspath.Path]
}

type jsxRuntimeImportSpecifier struct {
Expand Down Expand Up @@ -111,6 +112,7 @@ func processAllProgramFiles(
var jsxRuntimeImportSpecifiers map[tspath.Path]*jsxRuntimeImportSpecifier
var importHelpersImportSpecifiers map[tspath.Path]*ast.Node
var unsupportedExtensions []string
var sourceFilesFoundSearchingNodeModules collections.Set[tspath.Path]

loader.parseTasks.collect(&loader, loader.rootTasks, func(task *parseTask, _ []tspath.Path) {
file := task.file
Expand Down Expand Up @@ -148,22 +150,26 @@ func processAllProgramFiles(
if slices.Contains(tspath.SupportedJSExtensionsFlat, extension) {
unsupportedExtensions = core.AppendIfUnique(unsupportedExtensions, extension)
}
if task.isFromExternalLibrary {
sourceFilesFoundSearchingNodeModules.Add(path)
}
})
loader.sortLibs(libFiles)

allFiles := append(libFiles, files...)

return processedFiles{
resolver: loader.resolver,
files: allFiles,
filesByPath: filesByPath,
projectReferenceFileMapper: loader.projectReferenceFileMapper,
resolvedModules: resolvedModules,
typeResolutionsInFile: typeResolutionsInFile,
sourceFileMetaDatas: sourceFileMetaDatas,
jsxRuntimeImportSpecifiers: jsxRuntimeImportSpecifiers,
importHelpersImportSpecifiers: importHelpersImportSpecifiers,
unsupportedExtensions: unsupportedExtensions,
resolver: loader.resolver,
files: allFiles,
filesByPath: filesByPath,
projectReferenceFileMapper: loader.projectReferenceFileMapper,
resolvedModules: resolvedModules,
typeResolutionsInFile: typeResolutionsInFile,
sourceFileMetaDatas: sourceFileMetaDatas,
jsxRuntimeImportSpecifiers: jsxRuntimeImportSpecifiers,
importHelpersImportSpecifiers: importHelpersImportSpecifiers,
unsupportedExtensions: unsupportedExtensions,
sourceFilesFoundSearchingNodeModules: sourceFilesFoundSearchingNodeModules,
}
}

Expand Down Expand Up @@ -319,9 +325,10 @@ func (p *fileLoader) resolveTypeReferenceDirectives(file *ast.SourceFile, meta a
typeResolutionsInFile[module.ModeAwareCacheKey{Name: ref.FileName, Mode: resolutionMode}] = resolved
if resolved.IsResolved() {
toParse = append(toParse, resolvedRef{
fileName: resolved.ResolvedFileName,
increaseDepth: resolved.IsExternalLibraryImport,
elideOnDepth: false,
fileName: resolved.ResolvedFileName,
increaseDepth: resolved.IsExternalLibraryImport,
elideOnDepth: false,
isFromExternalLibrary: resolved.IsExternalLibraryImport,
})
}
}
Expand Down Expand Up @@ -412,9 +419,10 @@ func (p *fileLoader) resolveImportsAndModuleAugmentations(file *ast.SourceFile,

if shouldAddFile {
toParse = append(toParse, resolvedRef{
fileName: resolvedFileName,
increaseDepth: resolvedModule.IsExternalLibraryImport,
elideOnDepth: isJsFileFromNodeModules,
fileName: resolvedFileName,
increaseDepth: resolvedModule.IsExternalLibraryImport,
elideOnDepth: isJsFileFromNodeModules,
isFromExternalLibrary: isFromNodeModulesSearch,
})
}
}
Expand Down
19 changes: 15 additions & 4 deletions internal/compiler/parsetask.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ type parseTask struct {
jsxRuntimeImportSpecifier *jsxRuntimeImportSpecifier
increaseDepth bool
elideOnDepth bool

// Track if this file is from an external library (node_modules)
// This mirrors the TypeScript currentNodeModulesDepth > 0 check
isFromExternalLibrary bool
}

func (t *parseTask) FileName() string {
Expand Down Expand Up @@ -98,14 +102,21 @@ func (t *parseTask) redirect(loader *fileLoader, fileName string) {
}

type resolvedRef struct {
fileName string
increaseDepth bool
elideOnDepth bool
fileName string
increaseDepth bool
elideOnDepth bool
isFromExternalLibrary bool
}

func (t *parseTask) addSubTask(ref resolvedRef, isLib bool) {
normalizedFilePath := tspath.NormalizePath(ref.fileName)
subTask := &parseTask{normalizedFilePath: normalizedFilePath, isLib: isLib, increaseDepth: ref.increaseDepth, elideOnDepth: ref.elideOnDepth}
subTask := &parseTask{
normalizedFilePath: normalizedFilePath,
isLib: isLib,
increaseDepth: ref.increaseDepth,
elideOnDepth: ref.elideOnDepth,
isFromExternalLibrary: ref.isFromExternalLibrary || t.isFromExternalLibrary, // Propagate external library status
}
t.subTasks = append(t.subTasks, subTask)
}

Expand Down
4 changes: 4 additions & 0 deletions internal/compiler/program.go
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,10 @@ func (p *Program) getModeForTypeReferenceDirectiveInFile(ref *ast.FileReference,
return p.GetDefaultResolutionModeForFile(sourceFile)
}

func (p *Program) IsSourceFileFromExternalLibrary(file *ast.SourceFile) bool {
return p.sourceFilesFoundSearchingNodeModules.Has(file.Path())
}

type FileIncludeKind int

const (
Expand Down
1 change: 1 addition & 0 deletions internal/printer/emithost.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ type EmitHost interface {
GetEmitModuleFormatOfFile(file ast.HasFileName) core.ModuleKind
GetEmitResolver(file *ast.SourceFile, skipDiagnostics bool) EmitResolver
GetOutputAndProjectReference(path tspath.Path) *tsoptions.OutputDtsAndProjectReference
IsSourceFileFromExternalLibrary(file *ast.SourceFile) bool
}
1 change: 1 addition & 0 deletions internal/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,7 @@ func (p *Project) GetFileNames(excludeFilesFromExternalLibraries bool, excludeCo
result := []string{}
sourceFiles := p.program.GetSourceFiles()
for _, sourceFile := range sourceFiles {
// !! This is probably ready to be implemented now?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we have IsSourceFileFromExternalLibrary

// if excludeFilesFromExternalLibraries && p.program.IsSourceFileFromExternalLibrary(sourceFile) {
// continue;
// }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export {};
//// [app.ts]
import "A"

//// [index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//// [app.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,22 @@ export const x: () => Thing = null as any;
"exports": "./index.ts"
}

//// [other.js]
export const x = null;
//// [index.js]
// esm format file
export { x } from "./other.js";
//// [index.js]
export const a = (await import("inner")).x();


//// [other.d.ts]
// esm format file
export interface Thing {
}
export declare const x: () => Thing;
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [index.d.ts]
export declare const a: any;
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
--- old.nodeModulesExportsSourceTs(module=node16).js
+++ new.nodeModulesExportsSourceTs(module=node16).js
@@= skipped -26, +26 lines =@@
"exports": "./index.ts"
}

-//// [other.js]
-export const x = null;
-//// [index.js]
-// esm format file
-export { x } from "./other.js";
//// [index.js]
export const a = (await import("inner")).x();
@@= skipped -36, +36 lines =@@


-//// [other.d.ts]
-export interface Thing {
-}
-export declare const x: () => Thing;
//// [other.d.ts]
+// esm format file
export interface Thing {
}
export declare const x: () => Thing;
//// [index.d.ts]
-export { x } from "./other.js";
+// esm format file
export { x } from "./other.js";
+//// [index.d.ts]
+export declare const a: any;
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,32 @@ export const x: () => Thing = null as any;
"exports": "./index.ts"
}

//// [other.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.x = void 0;
exports.x = null;
//// [index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.x = void 0;
// esm format file
const other_js_1 = require("./other.js");
Object.defineProperty(exports, "x", { enumerable: true, get: function () { return other_js_1.x; } });
//// [index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.a = void 0;
exports.a = (await import("inner")).x();


//// [other.d.ts]
// esm format file
export interface Thing {
}
export declare const x: () => Thing;
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [index.d.ts]
export declare const a: any;
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
--- old.nodeModulesExportsSourceTs(module=node18).js
+++ new.nodeModulesExportsSourceTs(module=node18).js
@@= skipped -26, +26 lines =@@
"exports": "./index.ts"
@@= skipped -27, +27 lines =@@
}

-//// [other.js]
//// [other.js]
-export const x = null;
-//// [index.js]
-// esm format file
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.x = void 0;
+exports.x = null;
//// [index.js]
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.x = void 0;
// esm format file
-export { x } from "./other.js";
-//// [index.js]
+const other_js_1 = require("./other.js");
+Object.defineProperty(exports, "x", { enumerable: true, get: function () { return other_js_1.x; } });
//// [index.js]
-export const a = (await import("inner")).x();
-
-
-//// [other.d.ts]
-export interface Thing {
-}
-export declare const x: () => Thing;
+//// [index.js]
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.a = void 0;
+exports.a = (await import("inner")).x();
+
+


//// [other.d.ts]
+// esm format file
export interface Thing {
}
export declare const x: () => Thing;
//// [index.d.ts]
-export { x } from "./other.js";
+// esm format file
export { x } from "./other.js";
+//// [index.d.ts]
+export declare const a: any;
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,22 @@ export const x: () => Thing = null as any;
"exports": "./index.ts"
}

//// [other.js]
export const x = null;
//// [index.js]
// esm format file
export { x } from "./other.js";
//// [index.js]
export const a = (await import("inner")).x();


//// [other.d.ts]
// esm format file
export interface Thing {
}
export declare const x: () => Thing;
//// [index.d.ts]
// esm format file
export { x } from "./other.js";
//// [index.d.ts]
export declare const a: any;
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
--- old.nodeModulesExportsSourceTs(module=nodenext).js
+++ new.nodeModulesExportsSourceTs(module=nodenext).js
@@= skipped -26, +26 lines =@@
"exports": "./index.ts"
}

-//// [other.js]
-export const x = null;
-//// [index.js]
-// esm format file
-export { x } from "./other.js";
//// [index.js]
export const a = (await import("inner")).x();
@@= skipped -36, +36 lines =@@


-//// [other.d.ts]
-export interface Thing {
-}
-export declare const x: () => Thing;
//// [other.d.ts]
+// esm format file
export interface Thing {
}
export declare const x: () => Thing;
//// [index.d.ts]
-export { x } from "./other.js";
+// esm format file
export { x } from "./other.js";
+//// [index.d.ts]
+export declare const a: any;
Loading