From b332f3805b693b0af32b1c1aa607be56066268f5 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sun, 28 Apr 2024 21:33:33 -0700 Subject: [PATCH] Ensure equal FileIncludeReasons are not duplicitively added --- src/compiler/program.ts | 7 +++- src/compiler/types.ts | 2 + src/compiler/utilities.ts | 37 +++++++++++++++++++ .../external-project-watch-options-errors.js | 1 - ...ect-watch-options-in-host-configuration.js | 1 - .../external-project-watch-options.js | 1 - 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index a89ae1f365f1d..c2ad684946cf9 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -83,6 +83,7 @@ import { fileExtensionIsOneOf, FileIncludeKind, FileIncludeReason, + fileIncludeReasonIsEqual, fileIncludeReasonToDiagnostics, FilePreprocessingDiagnostics, FilePreprocessingDiagnosticsKind, @@ -3797,7 +3798,11 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function addFileIncludeReason(file: SourceFile | undefined, reason: FileIncludeReason) { - if (file) fileReasons.add(file.path, reason); + if (file) { + const existing = fileReasons.get(file.path); + if (some(existing, r => fileIncludeReasonIsEqual(r, reason))) return; + fileReasons.add(file.path, reason); + } } function addFileToFilesByName(file: SourceFile | undefined, path: Path, fileName: string, redirectedPath: Path | undefined) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 78772436ca687..24849ac83855f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4598,6 +4598,8 @@ export interface AutomaticTypeDirectiveFile { packageId: PackageId | undefined; } +// Note: if updating FileIncludeReason, ensure fileIncludeReasonIsEqual is also updated. + /** @internal */ export type FileIncludeReason = | RootFile diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 867a139c5c8c6..22d8f7c33d669 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -24,6 +24,7 @@ import { AssignmentDeclarationKind, AssignmentExpression, AssignmentOperatorToken, + AutomaticTypeDirectiveFile, BarBarEqualsToken, BinaryExpression, binarySearch, @@ -136,6 +137,8 @@ import { FileExtensionInfo, fileExtensionIs, fileExtensionIsOneOf, + FileIncludeKind, + FileIncludeReason, FileWatcher, filter, find, @@ -399,6 +402,7 @@ import { lastOrUndefined, LateVisibilityPaintedStatement, length, + LibFile, LiteralImportTypeNode, LiteralLikeElementAccessExpression, LiteralLikeNode, @@ -466,6 +470,7 @@ import { PrintHandlers, PrivateIdentifier, ProjectReference, + ProjectReferenceFile, PrologueDirective, PropertyAccessEntityNameExpression, PropertyAccessExpression, @@ -481,6 +486,7 @@ import { QuestionQuestionEqualsToken, ReadonlyCollection, ReadonlyTextRange, + ReferencedFile, removeTrailingDirectorySeparator, RequireOrImportCall, RequireVariableStatement, @@ -492,6 +498,7 @@ import { returnFalse, ReturnStatement, returnUndefined, + RootFile, SatisfiesExpression, ScriptKind, ScriptTarget, @@ -852,6 +859,36 @@ export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirec oldResolution.resolvedTypeReferenceDirective.originalPath === newResolution.resolvedTypeReferenceDirective.originalPath; } +/** @internal */ +export function fileIncludeReasonIsEqual(a: FileIncludeReason, b: FileIncludeReason): boolean { + if (a === b) return true; + if (a.kind !== b.kind) return false; + + switch (a.kind) { + case FileIncludeKind.RootFile: + Debug.type(b); + return a.index === b.index; + case FileIncludeKind.LibFile: + Debug.type(b); + return a.index === b.index; + case FileIncludeKind.SourceFromProjectReference: + case FileIncludeKind.OutputFromProjectReference: + Debug.type(b); + return a.index === b.index; + case FileIncludeKind.Import: + case FileIncludeKind.ReferenceFile: + case FileIncludeKind.TypeReferenceDirective: + case FileIncludeKind.LibReferenceDirective: + Debug.type(b); + return a.file === b.file && a.index === b.index; + case FileIncludeKind.AutomaticTypeDirectiveFile: + Debug.type(b); + return a.typeReference === b.typeReference && packageIdIsEqual(a.packageId, b.packageId); + default: + return Debug.assertNever(a); + } +} + /** @internal */ export function hasChangesInResolutions( names: readonly K[], diff --git a/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options-errors.js b/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options-errors.js index fcbcb5243c596..224c41a30ec48 100644 --- a/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options-errors.js +++ b/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options-errors.js @@ -79,7 +79,6 @@ Info seq [hh:mm:ss:mss] Files (4) ../../../../a/lib/lib.d.ts Default library for target 'es5' node_modules/bar/foo.d.ts - Imported via "./foo" from file 'node_modules/bar/index.d.ts' Imported via "./foo" from file 'node_modules/bar/index.d.ts' Root file specified for compilation node_modules/bar/index.d.ts diff --git a/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options-in-host-configuration.js b/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options-in-host-configuration.js index 81d1539aab128..edec9cd7880a5 100644 --- a/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options-in-host-configuration.js +++ b/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options-in-host-configuration.js @@ -106,7 +106,6 @@ Info seq [hh:mm:ss:mss] Files (4) ../../../../a/lib/lib.d.ts Default library for target 'es5' node_modules/bar/foo.d.ts - Imported via "./foo" from file 'node_modules/bar/index.d.ts' Imported via "./foo" from file 'node_modules/bar/index.d.ts' Root file specified for compilation node_modules/bar/index.d.ts diff --git a/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options.js b/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options.js index a933e9eaccc34..e8d5952b5c06a 100644 --- a/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options.js +++ b/tests/baselines/reference/tsserver/watchEnvironment/external-project-watch-options.js @@ -77,7 +77,6 @@ Info seq [hh:mm:ss:mss] Files (4) ../../../../a/lib/lib.d.ts Default library for target 'es5' node_modules/bar/foo.d.ts - Imported via "./foo" from file 'node_modules/bar/index.d.ts' Imported via "./foo" from file 'node_modules/bar/index.d.ts' Root file specified for compilation node_modules/bar/index.d.ts