diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 782077aae53..601948a3ea0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13373,6 +13373,9 @@ namespace ts { includes & TypeFlags.VoidLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) { return neverType; } + if (includes & TypeFlags.TemplateLiteral && includes & TypeFlags.StringLiteral && extractRedundantTemplateLiterals(typeSet)) { + return neverType; + } if (includes & TypeFlags.Any) { return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType; } @@ -13424,12 +13427,7 @@ namespace ts { } } else { - if (includes & TypeFlags.TemplateLiteral && includes & TypeFlags.StringLiteral && extractRedundantTemplateLiterals(typeSet)) { - result = neverType; - } - else { - result = createIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); - } + result = createIntersectionType(typeSet, aliasSymbol, aliasTypeArguments); } intersectionTypes.set(id, result); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 1e41cdbf37a..2c8a2709fb7 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -530,6 +530,51 @@ namespace ts { return resolutions; } + /* @internal */ + export function forEachResolvedProjectReference( + 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)); + } + + function forEachProjectReference( + projectReferences: readonly ProjectReference[] | undefined, + resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, + cbResolvedRef: (resolvedRef: ResolvedProjectReference | undefined, parent: ResolvedProjectReference | undefined, index: number) => T | undefined, + cbRef?: (projectReferences: readonly ProjectReference[] | undefined, parent: ResolvedProjectReference | undefined) => T | undefined + ): T | undefined { + let seenResolvedRefs: Set | undefined; + + return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined); + + function worker( + projectReferences: readonly ProjectReference[] | undefined, + resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, + parent: ResolvedProjectReference | undefined, + ): T | undefined { + + // Visit project references first + if (cbRef) { + 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); + }); + } + } + /* @internal */ export const inferredTypesContainingFile = "__inferred type names__.ts"; @@ -914,8 +959,8 @@ namespace ts { host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions(), !!getSourceFileByPath(oldSourceFile.path)); } } - oldProgram.forEachResolvedProjectReference((resolvedProjectReference, resolvedProjectReferencePath) => { - if (resolvedProjectReference && !getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) { + oldProgram.forEachResolvedProjectReference(resolvedProjectReference => { + if (!getResolvedProjectReferenceByPath(resolvedProjectReference.sourceFile.path)) { host.onReleaseOldSourceFile!(resolvedProjectReference.sourceFile, oldProgram!.getCompilerOptions(), /*hasSourceFileByPath*/ false); } }); @@ -1038,7 +1083,6 @@ namespace ts { if (!source) return undefined; // Output of .d.ts file so return resolved ref that matches the out file name return forEachResolvedProjectReference(resolvedRef => { - if (!resolvedRef) return undefined; const out = outFile(resolvedRef.commandLine.options); if (!out) return undefined; return toPath(out) === filePath ? resolvedRef : undefined; @@ -1251,7 +1295,7 @@ namespace ts { return !forEachProjectReference( oldProgram!.getProjectReferences(), oldProgram!.getResolvedProjectReferences(), - (oldResolvedRef, index, parent) => { + (oldResolvedRef, parent, index) => { const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)![index]; const newResolvedRef = parseProjectReferenceConfigFile(newRef); if (oldResolvedRef) { @@ -2115,9 +2159,7 @@ namespace ts { if (!options.configFile) { return emptyArray; } let diagnostics = programDiagnostics.getDiagnostics(options.configFile.fileName); forEachResolvedProjectReference(resolvedRef => { - if (resolvedRef) { - diagnostics = concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName)); - } + diagnostics = concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName)); }); return diagnostics; } @@ -2597,12 +2639,11 @@ namespace ts { function getResolvedProjectReferenceToRedirect(fileName: string) { if (mapFromFileToProjectReferenceRedirects === undefined) { mapFromFileToProjectReferenceRedirects = new Map(); - forEachResolvedProjectReference((referencedProject, referenceProjectPath) => { + forEachResolvedProjectReference(referencedProject => { // not input file from the referenced project, ignore - if (referencedProject && - toPath(options.configFilePath!) !== referenceProjectPath) { + if (toPath(options.configFilePath!) !== referencedProject.sourceFile.path) { referencedProject.commandLine.fileNames.forEach(f => - mapFromFileToProjectReferenceRedirects!.set(toPath(f), referenceProjectPath)); + mapFromFileToProjectReferenceRedirects!.set(toPath(f), referencedProject.sourceFile.path)); } }); } @@ -2612,13 +2653,9 @@ namespace ts { } function forEachResolvedProjectReference( - cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined + cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined ): T | undefined { - return forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => { - const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index]; - const resolvedRefPath = toPath(resolveProjectReferencePath(ref)); - return cb(resolvedRef, resolvedRefPath); - }); + return ts.forEachResolvedProjectReference(resolvedProjectReferences, cb); } function getSourceOfProjectReferenceRedirect(file: string) { @@ -2626,21 +2663,19 @@ namespace ts { if (mapFromToProjectReferenceRedirectSource === undefined) { mapFromToProjectReferenceRedirectSource = new Map(); forEachResolvedProjectReference(resolvedRef => { - if (resolvedRef) { - const out = outFile(resolvedRef.commandLine.options); - if (out) { - // Dont know which source file it means so return true? - const outputDts = changeExtension(out, Extension.Dts); - mapFromToProjectReferenceRedirectSource!.set(toPath(outputDts), true); - } - else { - forEach(resolvedRef.commandLine.fileNames, fileName => { - if (!fileExtensionIs(fileName, Extension.Dts) && !fileExtensionIs(fileName, Extension.Json)) { - const outputDts = getOutputDeclarationFileName(fileName, resolvedRef.commandLine, host.useCaseSensitiveFileNames()); - mapFromToProjectReferenceRedirectSource!.set(toPath(outputDts), fileName); - } - }); - } + const out = outFile(resolvedRef.commandLine.options); + if (out) { + // Dont know which source file it means so return true? + const outputDts = changeExtension(out, Extension.Dts); + mapFromToProjectReferenceRedirectSource!.set(toPath(outputDts), true); + } + else { + forEach(resolvedRef.commandLine.fileNames, fileName => { + if (!fileExtensionIs(fileName, Extension.Dts) && !fileExtensionIs(fileName, Extension.Json)) { + const outputDts = getOutputDeclarationFileName(fileName, resolvedRef.commandLine, host.useCaseSensitiveFileNames()); + mapFromToProjectReferenceRedirectSource!.set(toPath(outputDts), fileName); + } + }); } }); } @@ -2651,49 +2686,6 @@ namespace ts { return useSourceOfProjectReferenceRedirect && !!getResolvedProjectReferenceToRedirect(fileName); } - function forEachProjectReference( - projectReferences: readonly ProjectReference[] | undefined, - resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, - cbResolvedRef: (resolvedRef: ResolvedProjectReference | undefined, index: number, parent: ResolvedProjectReference | undefined) => T | undefined, - cbRef?: (projectReferences: readonly ProjectReference[] | undefined, parent: ResolvedProjectReference | undefined) => T | undefined - ): T | undefined { - let seenResolvedRefs: ResolvedProjectReference[] | undefined; - - return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined, cbResolvedRef, cbRef); - - function worker( - projectReferences: readonly ProjectReference[] | undefined, - resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, - parent: ResolvedProjectReference | undefined, - cbResolvedRef: (resolvedRef: ResolvedProjectReference | undefined, index: number, parent: ResolvedProjectReference | undefined) => T | undefined, - cbRef?: (projectReferences: readonly ProjectReference[] | undefined, parent: ResolvedProjectReference | undefined) => T | undefined, - ): T | undefined { - - // Visit project references first - if (cbRef) { - const result = cbRef(projectReferences, parent); - if (result) { return result; } - } - - return forEach(resolvedProjectReferences, (resolvedRef, index) => { - if (contains(seenResolvedRefs, resolvedRef)) { - // ignore recursives - return undefined; - } - - const result = cbResolvedRef(resolvedRef, index, parent); - if (result) { - return result; - } - - if (!resolvedRef) return undefined; - - (seenResolvedRefs || (seenResolvedRefs = [])).push(resolvedRef); - return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef, cbResolvedRef, cbRef); - }); - } - } - function getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined { if (!projectReferenceRedirects) { return undefined; @@ -3348,7 +3340,7 @@ namespace ts { function verifyProjectReferences() { const buildInfoPath = !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : undefined; - forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => { + forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, parent, index) => { const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index]; const parentFile = parent && parent.sourceFile as JsonSourceFile; if (!resolvedRef) { @@ -3546,7 +3538,7 @@ namespace ts { toPath(fileName: string): Path; getResolvedProjectReferences(): readonly (ResolvedProjectReference | undefined)[] | undefined; getSourceOfProjectReferenceRedirect(fileName: string): SourceOfProjectReferenceRedirect | undefined; - forEachResolvedProjectReference(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined; + forEachResolvedProjectReference(cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined): T | undefined; } function updateHostForUseSourceOfProjectReferenceRedirect(host: HostForUseSourceOfProjectReferenceRedirect) { @@ -3576,7 +3568,6 @@ namespace ts { if (!setOfDeclarationDirectories) { setOfDeclarationDirectories = new Set(); host.forEachResolvedProjectReference(ref => { - if (!ref) return; const out = outFile(ref.commandLine.options); if (out) { setOfDeclarationDirectories!.add(getDirectoryPath(host.toPath(out))); diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 57411a88771..58e1c8ac5fc 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -74,7 +74,7 @@ namespace ts { statements = insertStatementAfterCustomPrologue(statements.slice(), factory.createVariableStatement(/*modifiers*/ undefined, factory.createVariableDeclarationList([currentFileState.filenameDeclaration], NodeFlags.Const))); } if (currentFileState.utilizedImplicitRuntimeImports && currentFileState.utilizedImplicitRuntimeImports.size && currentFileState.importSpecifier !== undefined) { - const specifier = `${currentFileState.importSpecifier}/${compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsx-dev-runtime.js" : "jsx-runtime.js"}`; + const specifier = `${currentFileState.importSpecifier}/${compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsx-dev-runtime" : "jsx-runtime"}`; if (isExternalModule(node)) { // Add `import` statement const importStatement = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, factory.createImportClause(/*typeOnly*/ false, /*name*/ undefined, factory.createNamedImports(arrayFrom(currentFileState.utilizedImplicitRuntimeImports.values()))), factory.createStringLiteral(specifier)); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6ce8b89cca8..d72248ba8d5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3800,7 +3800,7 @@ namespace ts { getResolvedProjectReferences(): readonly (ResolvedProjectReference | undefined)[] | undefined; /*@internal*/ getProjectReferenceRedirect(fileName: string): string | undefined; /*@internal*/ getResolvedProjectReferenceToRedirect(fileName: string): ResolvedProjectReference | undefined; - /*@internal*/ forEachResolvedProjectReference(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined; + /*@internal*/ forEachResolvedProjectReference(cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined): T | undefined; /*@internal*/ getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined; /*@internal*/ isSourceOfProjectReferenceRedirect(fileName: string): boolean; /*@internal*/ getProgramBuildInfo?(): ProgramBuildInfo | undefined; @@ -6333,7 +6333,7 @@ namespace ts { /*@internal*/ export interface ResolvedProjectReferenceCallbacks { getSourceOfProjectReferenceRedirect(fileName: string): SourceOfProjectReferenceRedirect | undefined; - forEachResolvedProjectReference(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined; + forEachResolvedProjectReference(cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined): T | undefined; } /* @internal */ diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 03a7090a8a5..2747a6f03f6 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -444,64 +444,105 @@ namespace ts.server { /*@internal*/ export function forEachResolvedProjectReferenceProject( project: ConfiguredProject, + fileName: string | undefined, cb: (child: ConfiguredProject) => T | undefined, projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind.Find | ProjectReferenceProjectLoadKind.FindCreate, ): T | undefined; /*@internal*/ export function forEachResolvedProjectReferenceProject( project: ConfiguredProject, + fileName: string | undefined, cb: (child: ConfiguredProject) => T | undefined, projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind, reason: string ): T | undefined; export function forEachResolvedProjectReferenceProject( project: ConfiguredProject, + fileName: string | undefined, cb: (child: ConfiguredProject) => T | undefined, projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind, reason?: string ): T | undefined { + const resolvedRefs = project.getCurrentProgram()?.getResolvedProjectReferences(); + if (!resolvedRefs) return undefined; let seenResolvedRefs: ESMap | undefined; - return worker(project.getCurrentProgram()?.getResolvedProjectReferences(), project.getCompilerOptions()); - - function worker(resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, parentOptions: CompilerOptions): T | undefined { - const loadKind = parentOptions.disableReferencedProjectLoad ? ProjectReferenceProjectLoadKind.Find : projectReferenceProjectLoadKind; - return forEach(resolvedProjectReferences, ref => { - if (!ref) return undefined; - - const configFileName = toNormalizedPath(ref.sourceFile.fileName); - const canonicalPath = project.projectService.toCanonicalFileName(configFileName); - const seenValue = seenResolvedRefs?.get(canonicalPath); - if (seenValue !== undefined && seenValue >= loadKind) { - return undefined; - } - const child = project.projectService.findConfiguredProjectByProjectName(configFileName) || ( - loadKind === ProjectReferenceProjectLoadKind.Find ? - undefined : - loadKind === ProjectReferenceProjectLoadKind.FindCreate ? - project.projectService.createConfiguredProject(configFileName) : - loadKind === ProjectReferenceProjectLoadKind.FindCreateLoad ? - project.projectService.createAndLoadConfiguredProject(configFileName, reason!) : - Debug.assertNever(loadKind) + const possibleDefaultRef = fileName ? project.getResolvedProjectReferenceToRedirect(fileName) : undefined; + if (possibleDefaultRef) { + // Try to find the name of the file directly through resolved project references + const configFileName = toNormalizedPath(possibleDefaultRef.sourceFile.fileName); + const child = project.projectService.findConfiguredProjectByProjectName(configFileName); + if (child) { + const result = cb(child); + if (result) return result; + } + else if (projectReferenceProjectLoadKind !== ProjectReferenceProjectLoadKind.Find) { + seenResolvedRefs = new Map(); + // Try to see if this project can be loaded + const result = forEachResolvedProjectReferenceProjectWorker( + resolvedRefs, + project.getCompilerOptions(), + (ref, loadKind) => possibleDefaultRef === ref ? callback(ref, loadKind) : undefined, + projectReferenceProjectLoadKind, + project.projectService, + seenResolvedRefs ); + if (result) return result; + // Cleanup seenResolvedRefs + seenResolvedRefs.clear(); + } + } - const result = child && cb(child); - if (result) { - return result; - } + return forEachResolvedProjectReferenceProjectWorker( + resolvedRefs, + project.getCompilerOptions(), + (ref, loadKind) => possibleDefaultRef !== ref ? callback(ref, loadKind) : undefined, + projectReferenceProjectLoadKind, + project.projectService, + seenResolvedRefs + ); - (seenResolvedRefs || (seenResolvedRefs = new Map())).set(canonicalPath, loadKind); - return worker(ref.references, ref.commandLine.options); - }); + function callback(ref: ResolvedProjectReference, loadKind: ProjectReferenceProjectLoadKind) { + const configFileName = toNormalizedPath(ref.sourceFile.fileName); + const child = project.projectService.findConfiguredProjectByProjectName(configFileName) || ( + loadKind === ProjectReferenceProjectLoadKind.Find ? + undefined : + loadKind === ProjectReferenceProjectLoadKind.FindCreate ? + project.projectService.createConfiguredProject(configFileName) : + loadKind === ProjectReferenceProjectLoadKind.FindCreateLoad ? + project.projectService.createAndLoadConfiguredProject(configFileName, reason!) : + Debug.assertNever(loadKind) + ); + + return child && cb(child); } } - /*@internal*/ - export function forEachResolvedProjectReference( - project: ConfiguredProject, - cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined + function forEachResolvedProjectReferenceProjectWorker( + resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[], + parentOptions: CompilerOptions, + cb: (resolvedRef: ResolvedProjectReference, loadKind: ProjectReferenceProjectLoadKind) => T | undefined, + projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind, + projectService: ProjectService, + seenResolvedRefs: ESMap | undefined, ): T | undefined { - const program = project.getCurrentProgram(); - return program && program.forEachResolvedProjectReference(cb); + const loadKind = parentOptions.disableReferencedProjectLoad ? ProjectReferenceProjectLoadKind.Find : projectReferenceProjectLoadKind; + 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); + }); } function forEachPotentialProjectReference( @@ -514,12 +555,12 @@ namespace ts.server { function forEachAnyProjectReferenceKind( project: ConfiguredProject, - cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined, + cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined, cbProjectRef: (projectReference: ProjectReference) => T | undefined, cbPotentialProjectRef: (potentialProjectReference: Path) => T | undefined ): T | undefined { return project.getCurrentProgram() ? - forEachResolvedProjectReference(project, cb) : + project.forEachResolvedProjectReference(cb) : project.isInitialLoadPending() ? forEachPotentialProjectReference(project, cbPotentialProjectRef) : forEach(project.getProjectReferences(), cbProjectRef); @@ -540,8 +581,8 @@ namespace ts.server { ): T | undefined { return forEachAnyProjectReferenceKind( project, - resolvedRef => callbackRefProject(project, cb, resolvedRef && resolvedRef.sourceFile.path), - projectRef => callbackRefProject(project, cb, project.toPath(projectRef.path)), + resolvedRef => callbackRefProject(project, cb, resolvedRef.sourceFile.path), + projectRef => callbackRefProject(project, cb, project.toPath(resolveProjectReferencePath(projectRef))), potentialProjectRef => callbackRefProject(project, cb, potentialProjectRef) ); } @@ -2875,6 +2916,7 @@ namespace ts.server { if (!projectContainsInfoDirectly(project, info)) { const referencedProject = forEachResolvedProjectReferenceProject( project, + info.path, child => { reloadChildProject(child); return projectContainsInfoDirectly(child, info); @@ -2885,6 +2927,7 @@ namespace ts.server { // Reload the project's tree that is already present forEachResolvedProjectReferenceProject( project, + /*fileName*/ undefined, reloadChildProject, ProjectReferenceProjectLoadKind.Find ); @@ -2990,11 +3033,12 @@ namespace ts.server { // Find the project that is referenced from this solution that contains the script info directly configuredProject = forEachResolvedProjectReferenceProject( configuredProject, + fileName, child => { updateProjectIfDirty(child); return projectContainsOriginalInfo(child) ? child : undefined; }, - configuredProject.getCompilerOptions().disableReferencedProjectLoad ? ProjectReferenceProjectLoadKind.Find : ProjectReferenceProjectLoadKind.FindCreateLoad, + ProjectReferenceProjectLoadKind.FindCreateLoad, `Creating project referenced in solution ${configuredProject.projectName} to find possible configured project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}` ); if (!configuredProject) return undefined; @@ -3070,6 +3114,7 @@ namespace ts.server { if (!projectContainsInfoDirectly(project, info)) { forEachResolvedProjectReferenceProject( project, + info.path, child => { updateProjectIfDirty(child); // Retain these projects @@ -3184,32 +3229,37 @@ namespace ts.server { // Work on array copy as we could add more projects as part of callback for (const project of arrayFrom(this.configuredProjects.values())) { // If this project has potential project reference for any of the project we are loading ancestor tree for - // we need to load this project tree - if (forEachPotentialProjectReference( - project, - potentialRefPath => forProjects!.has(potentialRefPath) - ) || forEachResolvedProjectReference( - project, - (_ref, resolvedPath) => forProjects!.has(resolvedPath) - )) { - // Load children - this.ensureProjectChildren(project, seenProjects); + // load this project first + if (forEachPotentialProjectReference(project, potentialRefPath => forProjects!.has(potentialRefPath))) { + updateProjectIfDirty(project); } + this.ensureProjectChildren(project, forProjects, seenProjects); } } - private ensureProjectChildren(project: ConfiguredProject, seenProjects: Set) { + private ensureProjectChildren(project: ConfiguredProject, forProjects: ReadonlyCollection, seenProjects: Set) { if (!tryAddToSet(seenProjects, project.canonicalConfigFilePath)) return; - // Update the project - updateProjectIfDirty(project); - // Create tree because project is uptodate we only care of resolved references - forEachResolvedProjectReferenceProject( - project, - child => this.ensureProjectChildren(child, seenProjects), - ProjectReferenceProjectLoadKind.FindCreateLoad, - `Creating project for reference of project: ${project.projectName}` - ); + // If this project disables child load ignore it + if (project.getCompilerOptions().disableReferencedProjectLoad) return; + + const children = project.getCurrentProgram()?.getResolvedProjectReferences(); + if (!children) return; + + for (const child of children) { + if (!child) continue; + const referencedProject = forEachResolvedProjectReference(child.references, ref => forProjects.has(ref.sourceFile.path) ? ref : undefined); + if (!referencedProject) continue; + + // Load this project, + const configFileName = toNormalizedPath(child.sourceFile.fileName); + const childProject = project.projectService.findConfiguredProjectByProjectName(configFileName) || + project.projectService.createAndLoadConfiguredProject(configFileName, `Creating project referenced by : ${project.projectName} as it references project ${referencedProject.sourceFile.fileName}`); + updateProjectIfDirty(childProject); + + // Ensure children for this project + this.ensureProjectChildren(childProject, forProjects, seenProjects); + } } private cleanupAfterOpeningFile(toRetainConfigProjects: readonly ConfiguredProject[] | ConfiguredProject | undefined) { diff --git a/src/server/project.ts b/src/server/project.ts index d95e9e266dd..ee64647bdee 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -750,11 +750,8 @@ namespace ts.server { for (const f of this.program.getSourceFiles()) { this.detachScriptInfoIfNotRoot(f.fileName); } - this.program.forEachResolvedProjectReference(ref => { - if (ref) { - this.detachScriptInfoFromProject(ref.sourceFile.fileName); - } - }); + this.program.forEachResolvedProjectReference(ref => + this.detachScriptInfoFromProject(ref.sourceFile.fileName)); } // Release external files @@ -1099,8 +1096,8 @@ namespace ts.server { } } - oldProgram.forEachResolvedProjectReference((resolvedProjectReference, resolvedProjectReferencePath) => { - if (resolvedProjectReference && !this.program!.getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) { + oldProgram.forEachResolvedProjectReference(resolvedProjectReference => { + if (!this.program!.getResolvedProjectReferenceByPath(resolvedProjectReference.sourceFile.path)) { this.detachScriptInfoFromProject(resolvedProjectReference.sourceFile.fileName); } }); @@ -2201,6 +2198,13 @@ namespace ts.server { return program && program.getResolvedProjectReferenceToRedirect(fileName); } + /*@internal*/ + forEachResolvedProjectReference( + cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined + ): T | undefined { + return this.getCurrentProgram()?.forEachResolvedProjectReference(cb); + } + /*@internal*/ enablePluginsWithOptions(options: CompilerOptions, pluginConfigOverrides: ESMap | undefined) { const host = this.projectService.host; @@ -2301,6 +2305,7 @@ namespace ts.server { getDefaultChildProjectFromProjectWithReferences(info: ScriptInfo) { return forEachResolvedProjectReferenceProject( this, + info.path, child => projectContainsInfoDirectly(child, info) ? child : undefined, @@ -2338,6 +2343,7 @@ namespace ts.server { return this.containsScriptInfo(info) || !!forEachResolvedProjectReferenceProject( this, + info.path, child => child.containsScriptInfo(info), ProjectReferenceProjectLoadKind.Find ); diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index 44ba7911a97..103143390fc 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -2189,19 +2189,14 @@ export function bar() {}` verifySolutionScenario({ configRefs: ["./tsconfig-indirect1.json", "./tsconfig-indirect2.json"], additionalFiles: [tsconfigIndirect, indirect, tsconfigIndirect2, indirect2], - additionalProjects: [{ - projectName: tsconfigIndirect.path, - files: [tsconfigIndirect.path, main.path, helper.path, indirect.path, libFile.path] - }], + additionalProjects: emptyArray, expectedOpenEvents: [ ...expectedSolutionLoadAndTelemetry(), - ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect.path), ...expectedProjectReferenceLoadAndTelemetry(tsconfigSrcPath), configFileDiagEvent(main.path, tsconfigSrcPath, []) ], expectedReloadEvents: [ ...expectedReloadEvent(tsconfigPath), - ...expectedReloadEvent(tsconfigIndirect.path), ...expectedReloadEvent(tsconfigSrcPath), ], expectedReferences: { @@ -2217,8 +2212,8 @@ export function bar() {}` refs: [ ...expectedIndirectRefs(fileResolvingToMainDts), ...refs, - ...expectedIndirectRefs(indirect2), ...expectedIndirectRefs(indirect), + ...expectedIndirectRefs(indirect2), ], symbolDisplayString: "(alias) const foo: 1\nimport foo", } @@ -2296,8 +2291,6 @@ export function bar() {}` const expectedProjectsOnOpen: VerifyProjects = { configuredProjects: [ { projectName: tsconfigPath, files: [tsconfigPath] }, - { projectName: tsconfigIndirect.path, files: [tsconfigIndirect.path, main.path, helper.path, indirect.path, libFile.path] }, - { projectName: tsconfigIndirect2.path, files: [tsconfigIndirect2.path, main.path, helper.path, indirect2.path, libFile.path] }, { projectName: tsconfigSrcPath, files: [tsconfigSrcPath, main.path, helper.path, libFile.path] }, ], inferredProjects: emptyArray @@ -2307,8 +2300,6 @@ export function bar() {}` additionalFiles: [tsconfigIndirect, indirect, tsconfigIndirect2, indirect2], expectedOpenEvents: [ ...expectedSolutionLoadAndTelemetry(), - ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect.path), - ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect2.path), ...expectedProjectReferenceLoadAndTelemetry(tsconfigSrcPath), configFileDiagEvent(main.path, tsconfigSrcPath, []) ], @@ -2317,9 +2308,7 @@ export function bar() {}` expectedProjectsOnOpen, expectedReloadEvents: [ ...expectedReloadEvent(tsconfigPath), - ...expectedReloadEvent(tsconfigIndirect.path), ...expectedReloadEvent(tsconfigSrcPath), - ...expectedReloadEvent(tsconfigIndirect2.path), ] }); }); @@ -2387,19 +2376,14 @@ bar;` solutionProject: [tsconfigPath, indirect.path, ownMain.path, main.path, libFile.path, helper.path], configRefs: ["./tsconfig-indirect1.json", "./tsconfig-indirect2.json"], additionalFiles: [tsconfigIndirect, indirect, tsconfigIndirect2, indirect2, ownMain], - additionalProjects: [{ - projectName: tsconfigIndirect.path, - files: [tsconfigIndirect.path, main.path, helper.path, indirect.path, libFile.path] - }], + additionalProjects: emptyArray, expectedOpenEvents: [ ...expectedSolutionLoadAndTelemetry(), - ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect.path), ...expectedProjectReferenceLoadAndTelemetry(tsconfigSrcPath), configFileDiagEvent(main.path, tsconfigSrcPath, []) ], expectedReloadEvents: [ ...expectedReloadEvent(tsconfigPath), - ...expectedReloadEvent(tsconfigIndirect.path), ...expectedReloadEvent(tsconfigSrcPath), ], expectedReferences: { @@ -2415,8 +2399,8 @@ bar;` refs: [ ...expectedIndirectRefs(fileResolvingToMainDts), ...refs, - ...expectedIndirectRefs(indirect2), ...expectedIndirectRefs(indirect), + ...expectedIndirectRefs(indirect2), ], symbolDisplayString: "(alias) const foo: 1\nimport foo", } @@ -2502,8 +2486,6 @@ bar;` const expectedProjectsOnOpen: VerifyProjects = { configuredProjects: [ { projectName: tsconfigPath, files: [tsconfigPath, indirect.path, ownMain.path, main.path, libFile.path, helper.path] }, - { projectName: tsconfigIndirect.path, files: [tsconfigIndirect.path, main.path, helper.path, indirect.path, libFile.path] }, - { projectName: tsconfigIndirect2.path, files: [tsconfigIndirect2.path, main.path, helper.path, indirect2.path, libFile.path] }, { projectName: tsconfigSrcPath, files: [tsconfigSrcPath, main.path, helper.path, libFile.path] }, ], inferredProjects: emptyArray @@ -2518,8 +2500,6 @@ bar;` additionalFiles: [tsconfigIndirect, indirect, tsconfigIndirect2, indirect2, ownMain], expectedOpenEvents: [ ...expectedSolutionLoadAndTelemetry(), - ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect.path), - ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect2.path), ...expectedProjectReferenceLoadAndTelemetry(tsconfigSrcPath), configFileDiagEvent(main.path, tsconfigSrcPath, []) ], @@ -2528,9 +2508,7 @@ bar;` expectedProjectsOnOpen, expectedReloadEvents: [ ...expectedReloadEvent(tsconfigPath), - ...expectedReloadEvent(tsconfigIndirect.path), ...expectedReloadEvent(tsconfigSrcPath), - ...expectedReloadEvent(tsconfigIndirect2.path), ] }); }); @@ -2645,5 +2623,75 @@ bar;` verifyAutoImport(/*built*/ true, /*disableSourceOfProjectReferenceRedirect*/ true); }); }); + + it("when files from two projects are open and one project references", () => { + function getPackageAndFile(packageName: string, references?: string[], optionsToExtend?: CompilerOptions): [file: File, config: File] { + const file: File = { + path: `${tscWatch.projectRoot}/${packageName}/src/file1.ts`, + content: `export const ${packageName}Const = 10;` + }; + const config: File = { + path: `${tscWatch.projectRoot}/${packageName}/tsconfig.json`, + content: JSON.stringify({ + compilerOptions: { composite: true, ...optionsToExtend || {} }, + references: references?.map(path => ({ path: `../${path}` })) + }) + }; + return [file, config]; + } + const [mainFile, mainConfig] = getPackageAndFile("main", ["core", "indirect", "noCoreRef1", "indirectDisabledChildLoad1", "indirectDisabledChildLoad2", "refToCoreRef3", "indirectNoCoreRef"]); + const [coreFile, coreConfig] = getPackageAndFile("core"); + const [noCoreRef1File, noCoreRef1Config] = getPackageAndFile("noCoreRef1"); + const [indirectFile, indirectConfig] = getPackageAndFile("indirect", ["coreRef1"]); + const [coreRef1File, coreRef1Config] = getPackageAndFile("coreRef1", ["core"]); + const [indirectDisabledChildLoad1File, indirectDisabledChildLoad1Config] = getPackageAndFile("indirectDisabledChildLoad1", ["coreRef2"], { disableReferencedProjectLoad: true }); + const [coreRef2File, coreRef2Config] = getPackageAndFile("coreRef2", ["core"]); + const [indirectDisabledChildLoad2File, indirectDisabledChildLoad2Config] = getPackageAndFile("indirectDisabledChildLoad2", ["coreRef3"], { disableReferencedProjectLoad: true }); + const [coreRef3File, coreRef3Config] = getPackageAndFile("coreRef3", ["core"]); + const [refToCoreRef3File, refToCoreRef3Config] = getPackageAndFile("refToCoreRef3", ["coreRef3"]); + const [indirectNoCoreRefFile, indirectNoCoreRefConfig] = getPackageAndFile("indirectNoCoreRef", ["noCoreRef2"]); + const [noCoreRef2File, noCoreRef2Config] = getPackageAndFile("noCoreRef2"); + + const host = createServerHost([ + libFile, mainFile, mainConfig, coreFile, coreConfig, noCoreRef1File, noCoreRef1Config, + indirectFile, indirectConfig, coreRef1File, coreRef1Config, + indirectDisabledChildLoad1File, indirectDisabledChildLoad1Config, coreRef2File, coreRef2Config, + indirectDisabledChildLoad2File, indirectDisabledChildLoad2Config, coreRef3File, coreRef3Config, + refToCoreRef3File, refToCoreRef3Config, + indirectNoCoreRefFile, indirectNoCoreRefConfig, noCoreRef2File, noCoreRef2Config + ], { useCaseSensitiveFileNames: true }); + const session = createSession(host); + const service = session.getProjectService(); + openFilesForSession([mainFile, coreFile], session); + + verifyProject(mainConfig); + verifyProject(coreConfig); + + // Find all refs in coreFile + session.executeCommandSeq({ + command: protocol.CommandTypes.References, + arguments: protocolFileLocationFromSubstring(coreFile, `coreConst`) + }); + verifyProject(mainConfig); + verifyProject(coreConfig); + verifyNoProject(noCoreRef1Config); // Should not be loaded + verifyProject(indirectConfig); + verifyProject(coreRef1Config); + verifyProject(indirectDisabledChildLoad1Config); + verifyNoProject(coreRef2Config); // Should not be loaded + verifyProject(indirectDisabledChildLoad2Config); + verifyProject(coreRef3Config); + verifyProject(refToCoreRef3Config); + verifyNoProject(indirectNoCoreRefConfig); // Should not be loaded + verifyNoProject(noCoreRef2Config); // Should not be loaded + + function verifyProject(config: File) { + assert.isDefined(service.configuredProjects.get(config.path), `Expected to find ${config.path}`); + } + + function verifyNoProject(config: File) { + assert.isUndefined(service.configuredProjects.get(config.path), `Expected to not find ${config.path}`); + } + }); }); } diff --git a/tests/baselines/reference/jsxJsxsCjsTransformChildren(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformChildren(jsx=react-jsx).js index a16b0ff2e23..bb94546b6f3 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformChildren(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformChildren(jsx=react-jsx).js @@ -8,6 +8,6 @@ export {}; //// [jsxJsxsCjsTransformChildren.js] "use strict"; exports.__esModule = true; -var jsx_runtime_js_1 = require("react/jsx-runtime.js"); +var jsx_runtime_1 = require("react/jsx-runtime"); /// -var a = jsx_runtime_js_1.jsx("div", { children: "text" }, void 0); +var a = jsx_runtime_1.jsx("div", { children: "text" }, void 0); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformChildren(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformChildren(jsx=react-jsxdev).js index 6194703f861..227e714da14 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformChildren(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformChildren(jsx=react-jsxdev).js @@ -8,7 +8,7 @@ export {}; //// [jsxJsxsCjsTransformChildren.js] "use strict"; exports.__esModule = true; -var jsx_dev_runtime_js_1 = require("react/jsx-dev-runtime.js"); +var jsx_dev_runtime_1 = require("react/jsx-dev-runtime"); var _jsxFileName = "tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformChildren.tsx"; /// -var a = jsx_dev_runtime_js_1.jsxDEV("div", { children: "text" }, void 0, false, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV("div", { children: "text" }, void 0, false, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).js index 2e0f2e9ca9a..2c38153a249 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsx).js @@ -11,6 +11,6 @@ export {}; //// [jsxJsxsCjsTransformCustomImport.js] "use strict"; exports.__esModule = true; -var jsx_runtime_js_1 = require("preact/jsx-runtime.js"); +var jsx_runtime_1 = require("preact/jsx-runtime"); /// -var a = jsx_runtime_js_1.jsxs(jsx_runtime_js_1.Fragment, { children: [jsx_runtime_js_1.jsx("p", {}, void 0), "text", jsx_runtime_js_1.jsx("div", { className: "foo" }, void 0)] }, void 0); +var a = jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx("p", {}, void 0), "text", jsx_runtime_1.jsx("div", { className: "foo" }, void 0)] }, void 0); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).js index 70cc50133dc..5ab5e659850 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImport(jsx=react-jsxdev).js @@ -11,7 +11,7 @@ export {}; //// [jsxJsxsCjsTransformCustomImport.js] "use strict"; exports.__esModule = true; -var jsx_dev_runtime_js_1 = require("preact/jsx-dev-runtime.js"); +var jsx_dev_runtime_1 = require("preact/jsx-dev-runtime"); var _jsxFileName = "tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformCustomImport.tsx"; /// -var a = jsx_dev_runtime_js_1.jsxDEV(jsx_dev_runtime_js_1.Fragment, { children: [jsx_dev_runtime_js_1.jsxDEV("p", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 3 }, this), "text", jsx_dev_runtime_js_1.jsxDEV("div", { className: "foo" }, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 3 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV(jsx_dev_runtime_1.Fragment, { children: [jsx_dev_runtime_1.jsxDEV("p", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 3 }, this), "text", jsx_dev_runtime_1.jsxDEV("div", { className: "foo" }, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 3 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).js index 1b2fcc278e7..200b3923f58 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsx).js @@ -25,15 +25,15 @@ export {}; //// [preact.js] "use strict"; exports.__esModule = true; -var jsx_runtime_js_1 = require("preact/jsx-runtime.js"); +var jsx_runtime_1 = require("preact/jsx-runtime"); /// /* @jsxImportSource preact */ -var a = jsx_runtime_js_1.jsxs(jsx_runtime_js_1.Fragment, { children: [jsx_runtime_js_1.jsx("p", {}, void 0), "text", jsx_runtime_js_1.jsx("div", { className: "foo" }, void 0)] }, void 0); +var a = jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx("p", {}, void 0), "text", jsx_runtime_1.jsx("div", { className: "foo" }, void 0)] }, void 0); //// [react.js] "use strict"; exports.__esModule = true; -var jsx_runtime_js_1 = require("react/jsx-runtime.js"); +var jsx_runtime_1 = require("react/jsx-runtime"); /// /* @jsxImportSource react */ require("./preact"); -var a = jsx_runtime_js_1.jsxs(jsx_runtime_js_1.Fragment, { children: [jsx_runtime_js_1.jsx("p", {}, void 0), "text", jsx_runtime_js_1.jsx("div", { className: "foo" }, void 0)] }, void 0); +var a = jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx("p", {}, void 0), "text", jsx_runtime_1.jsx("div", { className: "foo" }, void 0)] }, void 0); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).js index 35bb2ad0c20..136a67f48a5 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformCustomImportPragma(jsx=react-jsxdev).js @@ -25,17 +25,17 @@ export {}; //// [preact.js] "use strict"; exports.__esModule = true; -var jsx_dev_runtime_js_1 = require("preact/jsx-dev-runtime.js"); +var jsx_dev_runtime_1 = require("preact/jsx-dev-runtime"); var _jsxFileName = "tests/cases/conformance/jsx/jsxs/preact.tsx"; /// /* @jsxImportSource preact */ -var a = jsx_dev_runtime_js_1.jsxDEV(jsx_dev_runtime_js_1.Fragment, { children: [jsx_dev_runtime_js_1.jsxDEV("p", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 3 }, this), "text", jsx_dev_runtime_js_1.jsxDEV("div", { className: "foo" }, void 0, false, { fileName: _jsxFileName, lineNumber: 6, columnNumber: 3 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV(jsx_dev_runtime_1.Fragment, { children: [jsx_dev_runtime_1.jsxDEV("p", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 3 }, this), "text", jsx_dev_runtime_1.jsxDEV("div", { className: "foo" }, void 0, false, { fileName: _jsxFileName, lineNumber: 6, columnNumber: 3 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 10 }, this); //// [react.js] "use strict"; exports.__esModule = true; -var jsx_dev_runtime_js_1 = require("react/jsx-dev-runtime.js"); +var jsx_dev_runtime_1 = require("react/jsx-dev-runtime"); var _jsxFileName = "tests/cases/conformance/jsx/jsxs/react.tsx"; /// /* @jsxImportSource react */ require("./preact"); -var a = jsx_dev_runtime_js_1.jsxDEV(jsx_dev_runtime_js_1.Fragment, { children: [jsx_dev_runtime_js_1.jsxDEV("p", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 3 }, this), "text", jsx_dev_runtime_js_1.jsxDEV("div", { className: "foo" }, void 0, false, { fileName: _jsxFileName, lineNumber: 7, columnNumber: 3 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV(jsx_dev_runtime_1.Fragment, { children: [jsx_dev_runtime_1.jsxDEV("p", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 3 }, this), "text", jsx_dev_runtime_1.jsxDEV("div", { className: "foo" }, void 0, false, { fileName: _jsxFileName, lineNumber: 7, columnNumber: 3 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 10 }, this); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformNestedSelfClosingChild(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformNestedSelfClosingChild(jsx=react-jsx).js index fd5ce7fede7..b7d0e0d6a94 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformNestedSelfClosingChild(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformNestedSelfClosingChild(jsx=react-jsx).js @@ -24,8 +24,8 @@ console.log( //// [jsxJsxsCjsTransformNestedSelfClosingChild.js] "use strict"; exports.__esModule = true; -var jsx_runtime_js_1 = require("react/jsx-runtime.js"); -console.log(jsx_runtime_js_1.jsx("div", { children: jsx_runtime_js_1.jsx("div", {}, void 0) }, void 0)); -console.log(jsx_runtime_js_1.jsxs("div", { children: [jsx_runtime_js_1.jsx("div", {}, void 0), - jsx_runtime_js_1.jsx("div", {}, void 0)] }, void 0)); -console.log(jsx_runtime_js_1.jsx("div", { children: [1, 2].map(function (i) { return jsx_runtime_js_1.jsx("div", { children: i }, i); }) }, void 0)); +var jsx_runtime_1 = require("react/jsx-runtime"); +console.log(jsx_runtime_1.jsx("div", { children: jsx_runtime_1.jsx("div", {}, void 0) }, void 0)); +console.log(jsx_runtime_1.jsxs("div", { children: [jsx_runtime_1.jsx("div", {}, void 0), + jsx_runtime_1.jsx("div", {}, void 0)] }, void 0)); +console.log(jsx_runtime_1.jsx("div", { children: [1, 2].map(function (i) { return jsx_runtime_1.jsx("div", { children: i }, i); }) }, void 0)); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformNestedSelfClosingChild(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformNestedSelfClosingChild(jsx=react-jsxdev).js index 0e91bf32b15..6ddbbb35817 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformNestedSelfClosingChild(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformNestedSelfClosingChild(jsx=react-jsxdev).js @@ -25,9 +25,9 @@ console.log( "use strict"; var _this = this; exports.__esModule = true; -var jsx_dev_runtime_js_1 = require("react/jsx-dev-runtime.js"); +var jsx_dev_runtime_1 = require("react/jsx-dev-runtime"); var _jsxFileName = "tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformNestedSelfClosingChild.tsx"; -console.log(jsx_dev_runtime_js_1.jsxDEV("div", { children: jsx_dev_runtime_js_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 6, columnNumber: 5 }, this) }, void 0, false, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 13 }, this)); -console.log(jsx_dev_runtime_js_1.jsxDEV("div", { children: [jsx_dev_runtime_js_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 12, columnNumber: 5 }, this), - jsx_dev_runtime_js_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 13, columnNumber: 5 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 10, columnNumber: 13 }, this)); -console.log(jsx_dev_runtime_js_1.jsxDEV("div", { children: [1, 2].map(function (i) { return jsx_dev_runtime_js_1.jsxDEV("div", { children: i }, i, false, { fileName: _jsxFileName, lineNumber: 19, columnNumber: 21 }, _this); }) }, void 0, false, { fileName: _jsxFileName, lineNumber: 17, columnNumber: 13 }, this)); +console.log(jsx_dev_runtime_1.jsxDEV("div", { children: jsx_dev_runtime_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 6, columnNumber: 5 }, this) }, void 0, false, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 13 }, this)); +console.log(jsx_dev_runtime_1.jsxDEV("div", { children: [jsx_dev_runtime_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 12, columnNumber: 5 }, this), + jsx_dev_runtime_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 13, columnNumber: 5 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 10, columnNumber: 13 }, this)); +console.log(jsx_dev_runtime_1.jsxDEV("div", { children: [1, 2].map(function (i) { return jsx_dev_runtime_1.jsxDEV("div", { children: i }, i, false, { fileName: _jsxFileName, lineNumber: 19, columnNumber: 21 }, _this); }) }, void 0, false, { fileName: _jsxFileName, lineNumber: 17, columnNumber: 13 }, this)); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNames(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNames(jsx=react-jsx).js index e041154fb45..1c239af6274 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNames(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNames(jsx=react-jsx).js @@ -7,6 +7,6 @@ export {}; //// [jsxJsxsCjsTransformSubstitutesNames.js] "use strict"; exports.__esModule = true; -var jsx_runtime_js_1 = require("react/jsx-runtime.js"); +var jsx_runtime_1 = require("react/jsx-runtime"); /// -var a = jsx_runtime_js_1.jsx("div", {}, void 0); +var a = jsx_runtime_1.jsx("div", {}, void 0); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNames(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNames(jsx=react-jsxdev).js index 4d6375efe89..8f7a10afefb 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNames(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNames(jsx=react-jsxdev).js @@ -7,7 +7,7 @@ export {}; //// [jsxJsxsCjsTransformSubstitutesNames.js] "use strict"; exports.__esModule = true; -var jsx_dev_runtime_js_1 = require("react/jsx-dev-runtime.js"); +var jsx_dev_runtime_1 = require("react/jsx-dev-runtime"); var _jsxFileName = "tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformSubstitutesNames.tsx"; /// -var a = jsx_dev_runtime_js_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNamesFragment(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNamesFragment(jsx=react-jsx).js index b1a9f9b1b1e..74944d20d7c 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNamesFragment(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNamesFragment(jsx=react-jsx).js @@ -11,6 +11,6 @@ export {}; //// [jsxJsxsCjsTransformSubstitutesNamesFragment.js] "use strict"; exports.__esModule = true; -var jsx_runtime_js_1 = require("react/jsx-runtime.js"); +var jsx_runtime_1 = require("react/jsx-runtime"); /// -var a = jsx_runtime_js_1.jsxs(jsx_runtime_js_1.Fragment, { children: [jsx_runtime_js_1.jsx("p", {}, void 0), "text", jsx_runtime_js_1.jsx("div", {}, void 0)] }, void 0); +var a = jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [jsx_runtime_1.jsx("p", {}, void 0), "text", jsx_runtime_1.jsx("div", {}, void 0)] }, void 0); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNamesFragment(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNamesFragment(jsx=react-jsxdev).js index 6f3e36c7a81..810e1941eb9 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNamesFragment(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformSubstitutesNamesFragment(jsx=react-jsxdev).js @@ -11,7 +11,7 @@ export {}; //// [jsxJsxsCjsTransformSubstitutesNamesFragment.js] "use strict"; exports.__esModule = true; -var jsx_dev_runtime_js_1 = require("react/jsx-dev-runtime.js"); +var jsx_dev_runtime_1 = require("react/jsx-dev-runtime"); var _jsxFileName = "tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformSubstitutesNamesFragment.tsx"; /// -var a = jsx_dev_runtime_js_1.jsxDEV(jsx_dev_runtime_js_1.Fragment, { children: [jsx_dev_runtime_js_1.jsxDEV("p", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 3 }, this), "text", jsx_dev_runtime_js_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 3 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV(jsx_dev_runtime_1.Fragment, { children: [jsx_dev_runtime_1.jsxDEV("p", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 3 }, this), "text", jsx_dev_runtime_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 3 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this); diff --git a/tests/baselines/reference/templateLiteralTypesPatterns.errors.txt b/tests/baselines/reference/templateLiteralTypesPatterns.errors.txt index de5efa3fe13..652eee291b6 100644 --- a/tests/baselines/reference/templateLiteralTypesPatterns.errors.txt +++ b/tests/baselines/reference/templateLiteralTypesPatterns.errors.txt @@ -332,4 +332,10 @@ tests/cases/conformance/types/literal/templateLiteralTypesPatterns.ts(160,7): er const exampleBad: B = "anything"; // fails ~~~~~~~~~~ !!! error TS2322: Type '"anything"' is not assignable to type '`${number} ${number}`'. - const exampleGood: B = "1 2"; // ok \ No newline at end of file + const exampleGood: B = "1 2"; // ok + + // Repro from #41161 + + var aa: '0'; + var aa: '0' & `${number}`; + \ No newline at end of file diff --git a/tests/baselines/reference/templateLiteralTypesPatterns.js b/tests/baselines/reference/templateLiteralTypesPatterns.js index 51fdba1113c..09df226a97b 100644 --- a/tests/baselines/reference/templateLiteralTypesPatterns.js +++ b/tests/baselines/reference/templateLiteralTypesPatterns.js @@ -159,7 +159,13 @@ const shouldWork2: AGen = null as any as AGen; type A = `${number}`; type B = `${A} ${A}`; const exampleBad: B = "anything"; // fails -const exampleGood: B = "1 2"; // ok +const exampleGood: B = "1 2"; // ok + +// Repro from #41161 + +var aa: '0'; +var aa: '0' & `${number}`; + //// [templateLiteralTypesPatterns.js] "use strict"; @@ -280,3 +286,6 @@ var shouldWork1 = null; var shouldWork2 = null; var exampleBad = "anything"; // fails var exampleGood = "1 2"; // ok +// Repro from #41161 +var aa; +var aa; diff --git a/tests/baselines/reference/templateLiteralTypesPatterns.symbols b/tests/baselines/reference/templateLiteralTypesPatterns.symbols index 51810c9959e..8c1f1739fae 100644 --- a/tests/baselines/reference/templateLiteralTypesPatterns.symbols +++ b/tests/baselines/reference/templateLiteralTypesPatterns.symbols @@ -393,3 +393,11 @@ const exampleGood: B = "1 2"; // ok >exampleGood : Symbol(exampleGood, Decl(templateLiteralTypesPatterns.ts, 160, 5)) >B : Symbol(B, Decl(templateLiteralTypesPatterns.ts, 157, 21)) +// Repro from #41161 + +var aa: '0'; +>aa : Symbol(aa, Decl(templateLiteralTypesPatterns.ts, 164, 3), Decl(templateLiteralTypesPatterns.ts, 165, 3)) + +var aa: '0' & `${number}`; +>aa : Symbol(aa, Decl(templateLiteralTypesPatterns.ts, 164, 3), Decl(templateLiteralTypesPatterns.ts, 165, 3)) + diff --git a/tests/baselines/reference/templateLiteralTypesPatterns.types b/tests/baselines/reference/templateLiteralTypesPatterns.types index 02dc985ee5b..ad27b431f4b 100644 --- a/tests/baselines/reference/templateLiteralTypesPatterns.types +++ b/tests/baselines/reference/templateLiteralTypesPatterns.types @@ -552,3 +552,11 @@ const exampleGood: B = "1 2"; // ok >exampleGood : `${number} ${number}` >"1 2" : "1 2" +// Repro from #41161 + +var aa: '0'; +>aa : "0" + +var aa: '0' & `${number}`; +>aa : "0" + diff --git a/tests/cases/conformance/types/literal/templateLiteralTypesPatterns.ts b/tests/cases/conformance/types/literal/templateLiteralTypesPatterns.ts index 064fb5b06d6..494fff17680 100644 --- a/tests/cases/conformance/types/literal/templateLiteralTypesPatterns.ts +++ b/tests/cases/conformance/types/literal/templateLiteralTypesPatterns.ts @@ -159,4 +159,9 @@ const shouldWork2: AGen = null as any as AGen; type A = `${number}`; type B = `${A} ${A}`; const exampleBad: B = "anything"; // fails -const exampleGood: B = "1 2"; // ok \ No newline at end of file +const exampleGood: B = "1 2"; // ok + +// Repro from #41161 + +var aa: '0'; +var aa: '0' & `${number}`;