Skip to content

Commit 3ccbe80

Browse files
Expose import mode calculation functions (#49360)
* Expose import mode calculation functions * Make `SourceFileImportsList` internal again. * Accepted API baselines. * Fix lints. Co-authored-by: Daniel Rosenwasser <[email protected]>
1 parent 9c8e6b5 commit 3ccbe80

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

src/compiler/program.ts

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -536,20 +536,39 @@ namespace ts {
536536
return resolutions;
537537
}
538538

539-
/* @internal */
540-
interface SourceFileImportsList {
541-
imports: SourceFile["imports"];
542-
moduleAugmentations: SourceFile["moduleAugmentations"];
539+
/**
540+
* Subset of a SourceFile used to calculate index-based resolutions
541+
* This includes some internal fields, so unless you have very good reason,
542+
* (and are willing to use some less stable internals) you should probably just pass a SourceFile.
543+
*
544+
* @internal
545+
*/
546+
export interface SourceFileImportsList {
547+
/* @internal */ imports: SourceFile["imports"];
548+
/* @internal */ moduleAugmentations: SourceFile["moduleAugmentations"];
543549
impliedNodeFormat?: SourceFile["impliedNodeFormat"];
544550
};
545551

546-
/* @internal */
552+
/**
553+
* Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly
554+
* provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file.
555+
*/
547556
export function getModeForFileReference(ref: FileReference | string, containingFileMode: SourceFile["impliedNodeFormat"]) {
548557
return (isString(ref) ? containingFileMode : ref.resolutionMode) || containingFileMode;
549558
}
550559

551-
/* @internal */
552-
export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: number) {
560+
/**
561+
* Calculates the final resolution mode for an import at some index within a file's imports list. This is generally the explicitly
562+
* defined mode of the import if provided, or, if not, the mode of the containing file (with some exceptions: import=require is always commonjs, dynamic import is always esm).
563+
* If you have an actual import node, prefer using getModeForUsageLocation on the reference string node.
564+
* @param file File to fetch the resolution mode within
565+
* @param index Index into the file's complete resolution list to get the resolution of - this is a concatenation of the file's imports and module augmentations
566+
*/
567+
export function getModeForResolutionAtIndex(file: SourceFile, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined;
568+
/** @internal */
569+
// eslint-disable-next-line @typescript-eslint/unified-signatures
570+
export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined;
571+
export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined {
553572
if (file.impliedNodeFormat === undefined) return undefined;
554573
// we ensure all elements of file.imports and file.moduleAugmentations have the relevant parent pointers set during program setup,
555574
// so it's safe to use them even pre-bind
@@ -567,7 +586,15 @@ namespace ts {
567586
return false;
568587
}
569588

570-
/* @internal */
589+
/**
590+
* Calculates the final resolution mode for a given module reference node. This is generally the explicitly provided resolution mode, if
591+
* one exists, or the mode of the containing source file. (Excepting import=require, which is always commonjs, and dynamic import, which is always esm).
592+
* Notably, this function always returns `undefined` if the containing file has an `undefined` `impliedNodeFormat` - this field is only set when
593+
* `moduleResolution` is `node16`+.
594+
* @param file The file the import or import-like reference is contained within
595+
* @param usage The module reference string
596+
* @returns The final resolution mode of the import
597+
*/
571598
export function getModeForUsageLocation(file: {impliedNodeFormat?: SourceFile["impliedNodeFormat"]}, usage: StringLiteralLike) {
572599
if (file.impliedNodeFormat === undefined) return undefined;
573600
if ((isImportDeclaration(usage.parent) || isExportDeclaration(usage.parent))) {

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5103,6 +5103,31 @@ declare namespace ts {
51035103
export function formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): string;
51045104
export function formatDiagnosticsWithColorAndContext(diagnostics: readonly Diagnostic[], host: FormatDiagnosticsHost): string;
51055105
export function flattenDiagnosticMessageText(diag: string | DiagnosticMessageChain | undefined, newLine: string, indent?: number): string;
5106+
/**
5107+
* Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly
5108+
* provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file.
5109+
*/
5110+
export function getModeForFileReference(ref: FileReference | string, containingFileMode: SourceFile["impliedNodeFormat"]): ModuleKind.CommonJS | ModuleKind.ESNext | undefined;
5111+
/**
5112+
* Calculates the final resolution mode for an import at some index within a file's imports list. This is generally the explicitly
5113+
* defined mode of the import if provided, or, if not, the mode of the containing file (with some exceptions: import=require is always commonjs, dynamic import is always esm).
5114+
* If you have an actual import node, prefer using getModeForUsageLocation on the reference string node.
5115+
* @param file File to fetch the resolution mode within
5116+
* @param index Index into the file's complete resolution list to get the resolution of - this is a concatenation of the file's imports and module augmentations
5117+
*/
5118+
export function getModeForResolutionAtIndex(file: SourceFile, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined;
5119+
/**
5120+
* Calculates the final resolution mode for a given module reference node. This is generally the explicitly provided resolution mode, if
5121+
* one exists, or the mode of the containing source file. (Excepting import=require, which is always commonjs, and dynamic import, which is always esm).
5122+
* Notably, this function always returns `undefined` if the containing file has an `undefined` `impliedNodeFormat` - this field is only set when
5123+
* `moduleResolution` is `node16`+.
5124+
* @param file The file the import or import-like reference is contained within
5125+
* @param usage The module reference string
5126+
* @returns The final resolution mode of the import
5127+
*/
5128+
export function getModeForUsageLocation(file: {
5129+
impliedNodeFormat?: SourceFile["impliedNodeFormat"];
5130+
}, usage: StringLiteralLike): ModuleKind.CommonJS | ModuleKind.ESNext | undefined;
51065131
export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): readonly Diagnostic[];
51075132
/**
51085133
* A function for determining if a given file is esm or cjs format, assuming modern node module resolution rules, as configured by the

tests/baselines/reference/api/typescript.d.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5103,6 +5103,31 @@ declare namespace ts {
51035103
export function formatDiagnostic(diagnostic: Diagnostic, host: FormatDiagnosticsHost): string;
51045104
export function formatDiagnosticsWithColorAndContext(diagnostics: readonly Diagnostic[], host: FormatDiagnosticsHost): string;
51055105
export function flattenDiagnosticMessageText(diag: string | DiagnosticMessageChain | undefined, newLine: string, indent?: number): string;
5106+
/**
5107+
* Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly
5108+
* provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file.
5109+
*/
5110+
export function getModeForFileReference(ref: FileReference | string, containingFileMode: SourceFile["impliedNodeFormat"]): ModuleKind.CommonJS | ModuleKind.ESNext | undefined;
5111+
/**
5112+
* Calculates the final resolution mode for an import at some index within a file's imports list. This is generally the explicitly
5113+
* defined mode of the import if provided, or, if not, the mode of the containing file (with some exceptions: import=require is always commonjs, dynamic import is always esm).
5114+
* If you have an actual import node, prefer using getModeForUsageLocation on the reference string node.
5115+
* @param file File to fetch the resolution mode within
5116+
* @param index Index into the file's complete resolution list to get the resolution of - this is a concatenation of the file's imports and module augmentations
5117+
*/
5118+
export function getModeForResolutionAtIndex(file: SourceFile, index: number): ModuleKind.CommonJS | ModuleKind.ESNext | undefined;
5119+
/**
5120+
* Calculates the final resolution mode for a given module reference node. This is generally the explicitly provided resolution mode, if
5121+
* one exists, or the mode of the containing source file. (Excepting import=require, which is always commonjs, and dynamic import, which is always esm).
5122+
* Notably, this function always returns `undefined` if the containing file has an `undefined` `impliedNodeFormat` - this field is only set when
5123+
* `moduleResolution` is `node16`+.
5124+
* @param file The file the import or import-like reference is contained within
5125+
* @param usage The module reference string
5126+
* @returns The final resolution mode of the import
5127+
*/
5128+
export function getModeForUsageLocation(file: {
5129+
impliedNodeFormat?: SourceFile["impliedNodeFormat"];
5130+
}, usage: StringLiteralLike): ModuleKind.CommonJS | ModuleKind.ESNext | undefined;
51065131
export function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): readonly Diagnostic[];
51075132
/**
51085133
* A function for determining if a given file is esm or cjs format, assuming modern node module resolution rules, as configured by the

0 commit comments

Comments
 (0)