Skip to content

Fix incorrect usage of getResolvedTypeReferenceDirectives and some refactoring #58527

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 1 commit into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 12 additions & 8 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1243,11 +1243,11 @@ export function isReferenceFileLocation(location: ReferenceFileLocation | Synthe
export function getReferencedFileLocation(program: Program, ref: ReferencedFile): ReferenceFileLocation | SyntheticReferenceFileLocation {
const file = Debug.checkDefined(program.getSourceFileByPath(ref.file));
const { kind, index } = ref;
let pos: number | undefined, end: number | undefined, packageId: PackageId | undefined, resolutionMode: FileReference["resolutionMode"] | undefined;
let pos: number | undefined, end: number | undefined, packageId: PackageId | undefined;
switch (kind) {
case FileIncludeKind.Import:
const importLiteral = getModuleNameStringLiteralAt(file, index);
packageId = program.getResolvedModule(file, importLiteral.text, program.getModeForUsageLocation(file, importLiteral))?.resolvedModule?.packageId;
packageId = program.getResolvedModuleFromModuleSpecifier(importLiteral, file)?.resolvedModule?.packageId;
if (importLiteral.pos === -1) return { file, packageId, text: importLiteral.text };
pos = skipTrivia(file.text, importLiteral.pos);
end = importLiteral.end;
Expand All @@ -1256,8 +1256,8 @@ export function getReferencedFileLocation(program: Program, ref: ReferencedFile)
({ pos, end } = file.referencedFiles[index]);
break;
case FileIncludeKind.TypeReferenceDirective:
({ pos, end, resolutionMode } = file.typeReferenceDirectives[index]);
packageId = program.getResolvedTypeReferenceDirective(file, toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), resolutionMode || file.impliedNodeFormat)?.resolvedTypeReferenceDirective?.packageId;
({ pos, end } = file.typeReferenceDirectives[index]);
packageId = program.getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(file.typeReferenceDirectives[index], file)?.resolvedTypeReferenceDirective?.packageId;
break;
case FileIncludeKind.LibReferenceDirective:
({ pos, end } = file.libReferenceDirectives[index]);
Expand Down Expand Up @@ -1930,6 +1930,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
resolvedLibProcessing = undefined;
resolvedModulesProcessing = undefined;
resolvedTypeReferenceDirectiveNamesProcessing = undefined;
resolvedTypeReferenceDirectives = undefined!;

const program: Program = {
getRootFileNames: () => rootNames,
Expand Down Expand Up @@ -1961,7 +1962,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
getInstantiationCount: () => getTypeChecker().getInstantiationCount(),
getRelationCacheSizes: () => getTypeChecker().getRelationCacheSizes(),
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
getAutomaticTypeDirectiveNames: () => automaticTypeDirectiveNames!,
getAutomaticTypeDirectiveResolutions: () => automaticTypeDirectiveResolutions,
isSourceFileFromExternalLibrary,
Expand All @@ -1980,6 +1980,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
getResolvedModule,
getResolvedModuleFromModuleSpecifier,
getResolvedTypeReferenceDirective,
getResolvedTypeReferenceDirectiveFromTypeReferenceDirective,
forEachResolvedModule,
forEachResolvedTypeReferenceDirective,
getCurrentPackagesMap: () => packageMap,
Expand Down Expand Up @@ -2076,8 +2077,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return resolvedModules?.get(file.path)?.get(moduleName, mode);
}

function getResolvedModuleFromModuleSpecifier(moduleSpecifier: StringLiteralLike): ResolvedModuleWithFailedLookupLocations | undefined {
const sourceFile = getSourceFileOfNode(moduleSpecifier);
function getResolvedModuleFromModuleSpecifier(moduleSpecifier: StringLiteralLike, sourceFile?: SourceFile): ResolvedModuleWithFailedLookupLocations | undefined {
sourceFile ??= getSourceFileOfNode(moduleSpecifier);
Debug.assertIsDefined(sourceFile, "`moduleSpecifier` must have a `SourceFile` ancestor. Use `program.getResolvedModule` instead to provide the containing file and resolution mode.");
return getResolvedModule(sourceFile, moduleSpecifier.text, getModeForUsageLocation(sourceFile, moduleSpecifier));
}
Expand All @@ -2086,6 +2087,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return resolvedTypeReferenceDirectiveNames?.get(file.path)?.get(typeDirectiveName, mode);
}

function getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typeRef: FileReference, sourceFile: SourceFile) {
return getResolvedTypeReferenceDirective(sourceFile, toFileNameLowerCase(typeRef.fileName), typeRef.resolutionMode || sourceFile.impliedNodeFormat);
}

function forEachResolvedModule(
callback: (resolution: ResolvedModuleWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
file?: SourceFile,
Expand Down Expand Up @@ -2718,7 +2723,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
files = newSourceFiles;
fileReasons = oldProgram.getFileIncludeReasons();
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
automaticTypeDirectiveNames = oldProgram.getAutomaticTypeDirectiveNames();
automaticTypeDirectiveResolutions = oldProgram.getAutomaticTypeDirectiveResolutions();

Expand Down
5 changes: 3 additions & 2 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4679,10 +4679,12 @@ export interface Program extends ScriptReferenceHost {
/** @internal */
getResolvedModule(f: SourceFile, moduleName: string, mode: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined;
/** @internal */
getResolvedModuleFromModuleSpecifier(moduleSpecifier: StringLiteralLike): ResolvedModuleWithFailedLookupLocations | undefined;
getResolvedModuleFromModuleSpecifier(moduleSpecifier: StringLiteralLike, sourceFile?: SourceFile): ResolvedModuleWithFailedLookupLocations | undefined;
/** @internal */
getResolvedTypeReferenceDirective(f: SourceFile, typeDirectiveName: string, mode: ResolutionMode): ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined;
/** @internal */
getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typedRef: FileReference, sourceFile: SourceFile): ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined;
/** @internal */
forEachResolvedModule(
callback: (resolution: ResolvedModuleWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
file?: SourceFile,
Expand Down Expand Up @@ -4738,7 +4740,6 @@ export interface Program extends ScriptReferenceHost {
getRelationCacheSizes(): { assignable: number; identity: number; subtype: number; strictSubtype: number; };

/** @internal */ getFileProcessingDiagnostics(): FilePreprocessingDiagnostics[] | undefined;
/** @internal */ getResolvedTypeReferenceDirectives(): ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>;
/** @internal */ getAutomaticTypeDirectiveNames(): string[];
/** @internal */ getAutomaticTypeDirectiveResolutions(): ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>;
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/services/codefixes/convertToEsModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function fixImportOfModuleExports(
quotePreference: QuotePreference,
) {
for (const moduleSpecifier of importingFile.imports) {
const imported = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier)?.resolvedModule;
const imported = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier, importingFile)?.resolvedModule;
if (!imported || imported.resolvedFileName !== exportingFile.fileName) {
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/codefixes/fixImportNonExportedMember.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function getInfo(sourceFile: SourceFile, pos: number, program: Program): Info |
const moduleSpecifier = isStringLiteral(importDeclaration.moduleSpecifier) ? importDeclaration.moduleSpecifier : undefined;
if (moduleSpecifier === undefined) return undefined;

const resolvedModule = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier)?.resolvedModule;
const resolvedModule = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile)?.resolvedModule;
if (resolvedModule === undefined) return undefined;

const moduleSourceFile = program.getSourceFile(resolvedModule.resolvedFileName);
Expand Down
6 changes: 3 additions & 3 deletions src/services/codefixes/fixSpelling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ function getInfo(sourceFile: SourceFile, pos: number, context: CodeFixContextBas
else if (isImportSpecifier(parent) && parent.name === node) {
Debug.assertNode(node, isIdentifier, "Expected an identifier for spelling (import)");
const importDeclaration = findAncestor(node, isImportDeclaration)!;
const resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(context, importDeclaration);
const resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(context, importDeclaration, sourceFile);
if (resolvedSourceFile && resolvedSourceFile.symbol) {
suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(node, resolvedSourceFile.symbol);
}
Expand Down Expand Up @@ -177,10 +177,10 @@ function convertSemanticMeaningToSymbolFlags(meaning: SemanticMeaning): SymbolFl
return flags;
}

function getResolvedSourceFileFromImportDeclaration(context: CodeFixContextBase, importDeclaration: ImportDeclaration): SourceFile | undefined {
function getResolvedSourceFileFromImportDeclaration(context: CodeFixContextBase, importDeclaration: ImportDeclaration, importingFile: SourceFile): SourceFile | undefined {
if (!importDeclaration || !isStringLiteralLike(importDeclaration.moduleSpecifier)) return undefined;

const resolvedModule = context.program.getResolvedModuleFromModuleSpecifier(importDeclaration.moduleSpecifier)?.resolvedModule;
const resolvedModule = context.program.getResolvedModuleFromModuleSpecifier(importDeclaration.moduleSpecifier, importingFile)?.resolvedModule;
if (!resolvedModule) return undefined;

return context.program.getSourceFile(resolvedModule.resolvedFileName);
Expand Down
2 changes: 1 addition & 1 deletion src/services/codefixes/importFixes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1715,7 +1715,7 @@ function promoteFromTypeOnly(
// Change .ts extension to .js if necessary
if (!compilerOptions.allowImportingTsExtensions) {
const moduleSpecifier = tryGetModuleSpecifierFromDeclaration(importClause.parent);
const resolvedModule = moduleSpecifier && program.getResolvedModuleFromModuleSpecifier(moduleSpecifier)?.resolvedModule;
const resolvedModule = moduleSpecifier && program.getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile)?.resolvedModule;
if (resolvedModule?.resolvedUsingTsExtension) {
const changedExtension = changeAnyExtension(moduleSpecifier!.text, getOutputExtension(moduleSpecifier!.text, compilerOptions));
changes.replaceNode(sourceFile, moduleSpecifier!, factory.createStringLiteral(changedExtension));
Expand Down
2 changes: 1 addition & 1 deletion src/services/getEditsForFileRename.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ function getSourceFileToImport(
else {
const mode = program.getModeForUsageLocation(importingSourceFile, importLiteral);
const resolved = host.resolveModuleNameLiterals || !host.resolveModuleNames ?
program.getResolvedModuleFromModuleSpecifier(importLiteral) :
program.getResolvedModuleFromModuleSpecifier(importLiteral, importingSourceFile) :
host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName, mode);
return getSourceFileToImportFromResolved(importLiteral, resolved, oldToNew, program.getSourceFiles());
}
Expand Down
6 changes: 3 additions & 3 deletions src/services/goToDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
if (!symbol && isModuleSpecifierLike(fallbackNode)) {
// We couldn't resolve the module specifier as an external module, but it could
// be that module resolution succeeded but the target was not a module.
const ref = program.getResolvedModuleFromModuleSpecifier(fallbackNode)?.resolvedModule;
const ref = program.getResolvedModuleFromModuleSpecifier(fallbackNode, sourceFile)?.resolvedModule;
if (ref) {
return [{
name: fallbackNode.text,
Expand Down Expand Up @@ -341,7 +341,7 @@ export function getReferenceAtPosition(sourceFile: SourceFile, position: number,

const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
if (typeReferenceDirective) {
const reference = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName, typeReferenceDirective.resolutionMode || program.getDefaultResolutionModeForFile(sourceFile))?.resolvedTypeReferenceDirective;
const reference = program.getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typeReferenceDirective, sourceFile)?.resolvedTypeReferenceDirective;
const file = reference && program.getSourceFile(reference.resolvedFileName!); // TODO:GH#18217
return file && { reference: typeReferenceDirective, fileName: file.fileName, file, unverified: false };
}
Expand All @@ -355,7 +355,7 @@ export function getReferenceAtPosition(sourceFile: SourceFile, position: number,
if (sourceFile.imports.length || sourceFile.moduleAugmentations.length) {
const node = getTouchingToken(sourceFile, position);
let resolution: ResolvedModuleWithFailedLookupLocations | undefined;
if (isModuleSpecifierLike(node) && isExternalModuleNameRelative(node.text) && (resolution = program.getResolvedModuleFromModuleSpecifier(node))) {
if (isModuleSpecifierLike(node) && isExternalModuleNameRelative(node.text) && (resolution = program.getResolvedModuleFromModuleSpecifier(node, sourceFile))) {
const verifiedFileName = resolution.resolvedModule?.resolvedFileName;
const fileName = verifiedFileName || resolvePath(getDirectoryPath(sourceFile.fileName), node.text);
return {
Expand Down
2 changes: 1 addition & 1 deletion src/services/importTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ export function findModuleReferences(program: Program, sourceFiles: readonly Sou
}
}
for (const ref of referencingFile.typeReferenceDirectives) {
const referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName, ref.resolutionMode || program.getDefaultResolutionModeForFile(referencingFile))?.resolvedTypeReferenceDirective;
const referenced = program.getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(ref, referencingFile)?.resolvedTypeReferenceDirective;
if (referenced !== undefined && referenced.resolvedFileName === (searchSourceFile as SourceFile).fileName) {
refs.push({ kind: "reference", referencingFile, ref });
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/suggestionDiagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Pr
const importNode = importFromModuleSpecifier(moduleSpecifier);
const name = importNameForConvertToDefaultImport(importNode);
if (!name) continue;
const module = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier)?.resolvedModule;
const module = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile)?.resolvedModule;
const resolvedFile = module && program.getSourceFile(module.resolvedFileName);
if (resolvedFile && resolvedFile.externalModuleIndicator && resolvedFile.externalModuleIndicator !== true && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals) {
diags.push(createDiagnosticForNode(name, Diagnostics.Import_may_be_converted_to_a_default_import));
Expand Down