Skip to content

Dont open composite projects to determine if script info is part of project #59688

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 11 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Prefer own references over indirect references when searching for res…
…olved references
  • Loading branch information
sheetalkamat committed Sep 12, 2024
commit 0bc84cdca8d155979ef59a0aff91dca983f9348b
104 changes: 66 additions & 38 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,11 @@ export function forEachResolvedProjectReference<T>(
resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined,
cb: (resolvedProjectReference: ResolvedProjectReference, parent: ResolvedProjectReference | undefined) => T | undefined,
): T | undefined {
return forEachProjectReference(/*projectReferences*/ undefined, resolvedProjectReferences, (resolvedRef, parent) => resolvedRef && cb(resolvedRef, parent));
return forEachProjectReference(
/*projectReferences*/ undefined,
resolvedProjectReferences,
(resolvedRef, parent) => resolvedRef && cb(resolvedRef, parent),
);
}

function forEachProjectReference<T>(
Expand All @@ -1149,7 +1153,6 @@ function forEachProjectReference<T>(
cbRef?: (projectReferences: readonly ProjectReference[] | undefined, parent: ResolvedProjectReference | undefined) => T | undefined,
): T | undefined {
let seenResolvedRefs: Set<Path> | undefined;

return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined);

function worker(
Expand All @@ -1162,19 +1165,26 @@ function forEachProjectReference<T>(
const result = cbRef(projectReferences, parent);
if (result) return result;
}

return forEach(resolvedProjectReferences, (resolvedRef, index) => {
if (resolvedRef && seenResolvedRefs?.has(resolvedRef.sourceFile.path)) {
// ignore recursives
return undefined;
}

const result = cbResolvedRef(resolvedRef, parent, index);
if (result || !resolvedRef) return result;

(seenResolvedRefs ||= new Set()).add(resolvedRef.sourceFile.path);
return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef);
});
let skipChildren: Set<ResolvedProjectReference> | undefined;
return forEach(
resolvedProjectReferences,
(resolvedRef, index) => {
if (resolvedRef && seenResolvedRefs?.has(resolvedRef.sourceFile.path)) {
(skipChildren ??= new Set()).add(resolvedRef);
// ignore recursives
return undefined;
}
const result = cbResolvedRef(resolvedRef, parent, index);
if (result || !resolvedRef) return result;
(seenResolvedRefs ||= new Set()).add(resolvedRef.sourceFile.path);
},
) || forEach(
resolvedProjectReferences,
resolvedRef =>
resolvedRef && !skipChildren?.has(resolvedRef) ?
worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef) :
undefined,
);
}
}

Expand Down Expand Up @@ -1356,7 +1366,14 @@ export function isProgramUptoDate(
(seenResolvedRefs || (seenResolvedRefs = [])).push(oldResolvedRef);

// If child project references are upto date, this project reference is uptodate
return !forEach(oldResolvedRef.references, (childResolvedRef, index) => !resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences![index]));
return !forEach(
oldResolvedRef.references,
(childResolvedRef, index) =>
!resolvedProjectReferenceUptoDate(
childResolvedRef,
oldResolvedRef.commandLine.projectReferences![index],
),
);
}

// In old program, not able to resolve project reference path,
Expand Down Expand Up @@ -4894,7 +4911,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
case FileIncludeKind.SourceFromProjectReference:
case FileIncludeKind.OutputFromProjectReference:
const referencedResolvedRef = Debug.checkDefined(resolvedProjectReferences?.[reason.index]);
const referenceInfo = forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, parent, index) => resolvedRef === referencedResolvedRef ? { sourceFile: parent?.sourceFile || options.configFile!, index } : undefined);
const referenceInfo = forEachProjectReference(
projectReferences,
resolvedProjectReferences,
(resolvedRef, parent, index) =>
resolvedRef === referencedResolvedRef ?
{ sourceFile: parent?.sourceFile || options.configFile!, index } :
undefined,
);
if (!referenceInfo) return undefined;
const { sourceFile, index } = referenceInfo;
const referencesSyntax = forEachTsConfigPropArray(sourceFile as TsConfigSourceFile, "references", property => isArrayLiteralExpression(property.initializer) ? property.initializer : undefined);
Expand Down Expand Up @@ -4934,28 +4958,32 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg

function verifyProjectReferences() {
const buildInfoPath = !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : undefined;
forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, parent, index) => {
const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
const parentFile = parent && parent.sourceFile as JsonSourceFile;
verifyDeprecatedProjectReference(ref, parentFile, index);
if (!resolvedRef) {
createDiagnosticForReference(parentFile, index, Diagnostics.File_0_not_found, ref.path);
return;
}
const options = resolvedRef.commandLine.options;
if (!options.composite || options.noEmit) {
// ok to not have composite if the current program is container only
const inputs = parent ? parent.commandLine.fileNames : rootNames;
if (inputs.length) {
if (!options.composite) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
if (options.noEmit) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_may_not_disable_emit, ref.path);
forEachProjectReference(
projectReferences,
resolvedProjectReferences,
(resolvedRef, parent, index) => {
const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
const parentFile = parent && parent.sourceFile as JsonSourceFile;
verifyDeprecatedProjectReference(ref, parentFile, index);
if (!resolvedRef) {
createDiagnosticForReference(parentFile, index, Diagnostics.File_0_not_found, ref.path);
return;
}
}
if (!parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath(options)) {
createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path);
hasEmitBlockingDiagnostics.set(toPath(buildInfoPath), true);
}
});
const options = resolvedRef.commandLine.options;
if (!options.composite || options.noEmit) {
// ok to not have composite if the current program is container only
const inputs = parent ? parent.commandLine.fileNames : rootNames;
if (inputs.length) {
if (!options.composite) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
if (options.noEmit) createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_may_not_disable_emit, ref.path);
}
}
if (!parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath(options)) {
createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path);
hasEmitBlockingDiagnostics.set(toPath(buildInfoPath), true);
}
},
);
}

function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, ...args: DiagnosticArguments) {
Expand Down
47 changes: 30 additions & 17 deletions src/server/editorServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -861,23 +861,36 @@ function forEachResolvedProjectReferenceProjectWorker<T>(
seenResolvedRefs?: Map<string, ConfiguredProjectLoadKind>,
): T | undefined {
const loadKind = parentOptions.disableReferencedProjectLoad ? ConfiguredProjectLoadKind.Find : kind;
return forEach(resolvedProjectReferences, ref => {
if (!ref) return undefined;

const configFileName = toNormalizedPath(ref.sourceFile.fileName);
const canonicalPath = projectService.toCanonicalFileName(configFileName);
const seenValue = seenResolvedRefs?.get(canonicalPath);
if (seenValue !== undefined && seenValue >= loadKind) {
return undefined;
}
const result = cb(ref, loadKind);
if (result) {
return result;
}

(seenResolvedRefs || (seenResolvedRefs = new Map())).set(canonicalPath, loadKind);
return ref.references && forEachResolvedProjectReferenceProjectWorker(ref.references, ref.commandLine.options, cb, loadKind, projectService, seenResolvedRefs);
});
let skipChildren: Set<ResolvedProjectReference> | undefined;
return forEach(
resolvedProjectReferences,
ref => {
if (!ref) return undefined;
const configFileName = toNormalizedPath(ref.sourceFile.fileName);
const canonicalPath = projectService.toCanonicalFileName(configFileName);
const seenValue = seenResolvedRefs?.get(canonicalPath);
if (seenValue !== undefined && seenValue >= loadKind) {
(skipChildren ??= new Set()).add(ref);
return undefined;
}
const result = cb(ref, loadKind);
if (result) return result;
(seenResolvedRefs ??= new Map()).set(canonicalPath, loadKind);
},
) || forEach(
resolvedProjectReferences,
ref =>
ref?.references && !skipChildren?.has(ref) ?
forEachResolvedProjectReferenceProjectWorker(
ref.references,
ref.commandLine.options,
cb,
loadKind,
projectService,
seenResolvedRefs,
) :
undefined,
);
}

function forEachPotentialProjectReference<T>(
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy