diff --git a/package-lock.json b/package-lock.json index 8cf91d8ab77..d9342134560 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7674,9 +7674,9 @@ "dev": true }, "uglify-js": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.2.tgz", - "integrity": "sha512-G440NU6fewtnQftSgqRV1r2A5ChKbU1gqFCJ7I8S7MPpY/eZZfLGefaY6gUZYiWebMaO+txgiQ1ZyLDuNWJulg==", + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.3.tgz", + "integrity": "sha512-wDRziHG94mNj2n3R864CvYw/+pc9y/RNImiTyrrf8BzgWn75JgFSwYvXrtZQMnMnOp/4UTrf3iCSQxSStPiByA==", "dev": true, "optional": true }, diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 65cbfed68a6..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); } @@ -15046,9 +15044,10 @@ namespace ts { } function getObjectTypeInstantiation(type: AnonymousType | DeferredTypeReference, mapper: TypeMapper) { - const target = type.objectFlags & ObjectFlags.Instantiated ? type.target! : type; const declaration = type.objectFlags & ObjectFlags.Reference ? (type).node! : type.symbol.declarations[0]; const links = getNodeLinks(declaration); + const target = type.objectFlags & ObjectFlags.Reference ? links.resolvedType! : + type.objectFlags & ObjectFlags.Instantiated ? type.target! : type; let typeParameters = links.outerTypeParameters; if (!typeParameters) { // The first time an anonymous type is instantiated we compute and store a list of the type @@ -15065,10 +15064,6 @@ namespace ts { filter(typeParameters, tp => isTypeParameterPossiblyReferenced(tp, declaration)) : typeParameters; links.outerTypeParameters = typeParameters; - if (typeParameters.length) { - links.instantiations = new Map(); - links.instantiations.set(getTypeListId(typeParameters), target); - } } if (typeParameters.length) { // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the @@ -15077,13 +15072,17 @@ namespace ts { const combinedMapper = combineTypeMappers(type.mapper, mapper); const typeArguments = map(typeParameters, t => getMappedType(t, combinedMapper)); const id = getTypeListId(typeArguments); - let result = links.instantiations!.get(id); + if (!target.instantiations) { + target.instantiations = new Map(); + target.instantiations.set(getTypeListId(typeParameters), target); + } + let result = target.instantiations.get(id); if (!result) { const newMapper = createTypeMapper(typeParameters, typeArguments); result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type).target, (type).node, newMapper) : target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper); - links.instantiations!.set(id, result); + target.instantiations.set(id, result); } return result; } @@ -15826,10 +15825,6 @@ namespace ts { } } - function getSemanticJsxChildren(children: NodeArray) { - return filter(children, i => !isJsxText(i) || !i.containsOnlyTriviaWhiteSpaces); - } - function elaborateJsxComponents( node: JsxAttributes, source: Type, @@ -24986,6 +24981,9 @@ namespace ts { childrenTypes.push(stringType); } } + else if (child.kind === SyntaxKind.JsxExpression && !child.expression) { + continue; // empty jsx expressions don't *really* count as present children + } else { childrenTypes.push(checkExpressionForMutableLocation(child, checkMode)); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 73b036037d1..117410246d9 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1134,7 +1134,11 @@ namespace ts { name: "exclude", type: "string" } - } + }, + { + name: "disableFilenameBasedTypeAcquisition", + type: "boolean", + }, ]; /* @internal */ 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 fb9d16d6b94..bb177d518bb 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -42,7 +42,7 @@ namespace ts { function getImplicitImportForName(name: string) { const importSource = name === "createElement" ? currentFileState.importSpecifier! - : `${currentFileState.importSpecifier}/${compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsx-dev-runtime.js" : "jsx-runtime.js"}`; + : `${currentFileState.importSpecifier}/${compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsx-dev-runtime" : "jsx-runtime"}`; const existing = currentFileState.utilizedImplicitRuntimeImports?.get(importSource)?.get(name); if (existing) { return existing.name; @@ -200,7 +200,7 @@ namespace ts { } function convertJsxChildrenToChildrenPropObject(children: readonly JsxChild[]) { - const nonWhitespaceChildren = filter(children, c => !isJsxText(c) || !c.containsOnlyTriviaWhiteSpaces); + const nonWhitespaceChildren = getSemanticJsxChildren(children); if (length(nonWhitespaceChildren) === 1) { const result = transformJsxChildToExpression(nonWhitespaceChildren[0]); return result && factory.createObjectLiteralExpression([ @@ -253,7 +253,7 @@ namespace ts { objectProperties = singleOrUndefined(segments) || emitHelpers().createAssignHelper(segments); } - return visitJsxOpeningLikeElementOrFragmentJSX(tagName, objectProperties, keyAttr, length(filter(children, c => !isJsxText(c) || !c.containsOnlyTriviaWhiteSpaces)), isChild, location); + return visitJsxOpeningLikeElementOrFragmentJSX(tagName, objectProperties, keyAttr, length(getSemanticJsxChildren(children || emptyArray)), isChild, location); } function visitJsxOpeningLikeElementOrFragmentJSX(tagName: Expression, objectProperties: Expression, keyAttr: JsxAttribute | undefined, childrenLength: number, isChild: boolean, location: TextRange) { @@ -352,7 +352,7 @@ namespace ts { getImplicitJsxFragmentReference(), childrenProps || factory.createObjectLiteralExpression([]), /*keyAttr*/ undefined, - length(filter(children, c => !isJsxText(c) || !c.containsOnlyTriviaWhiteSpaces)), + length(getSemanticJsxChildren(children)), isChild, location ); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0ce9c2afa75..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; @@ -4847,7 +4847,6 @@ namespace ts { deferredNodes?: ESMap; // Set of nodes whose checking has been deferred capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type - instantiations?: ESMap; // Instantiations of generic type alias (undefined if non-generic) isExhaustive?: boolean; // Is node an exhaustive switch statement skipDirectInference?: true; // Flag set by the API `getContextualType` call on a node when `Completions` is passed to force the checker to skip making inferences to a node's type declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. @@ -5141,6 +5140,8 @@ namespace ts { node: TypeReferenceNode | ArrayTypeNode | TupleTypeNode; /* @internal */ mapper?: TypeMapper; + /* @internal */ + instantiations?: ESMap; // Instantiations of generic type alias (undefined if non-generic) } /* @internal */ @@ -5221,6 +5222,7 @@ namespace ts { export interface AnonymousType extends ObjectType { target?: AnonymousType; // Instantiation target mapper?: TypeMapper; // Instantiation mapper + instantiations?: ESMap; // Instantiations of generic type alias (undefined if non-generic) } /* @internal */ @@ -5853,7 +5855,8 @@ namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - [option: string]: string[] | boolean | undefined; + disableFilenameBasedTypeAcquisition?: boolean; + [option: string]: CompilerOptionsValue | undefined; } export enum ModuleKind { @@ -6330,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/compiler/utilities.ts b/src/compiler/utilities.ts index ca8f2d87225..623f0688992 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3621,6 +3621,19 @@ namespace ts { return -1; } + export function getSemanticJsxChildren(children: readonly JsxChild[]) { + return filter(children, i => { + switch (i.kind) { + case SyntaxKind.JsxExpression: + return !!i.expression; + case SyntaxKind.JsxText: + return !i.containsOnlyTriviaWhiteSpaces; + default: + return true; + } + }); + } + export function createDiagnosticCollection(): DiagnosticCollection { let nonFileDiagnostics = [] as Diagnostic[] as SortedArray; // See GH#19873 const filesWithDiagnostics = [] as string[] as SortedArray; diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index ca765bd776f..10ef0cf957a 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -149,8 +149,9 @@ namespace ts.JsTyping { const nodeModulesPath = combinePaths(searchDir, "node_modules"); getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch); }); - getTypingNamesFromSourceFileNames(fileNames); - + if(!typeAcquisition.disableFilenameBasedTypeAcquisition) { + getTypingNamesFromSourceFileNames(fileNames); + } // add typings for unresolved imports if (unresolvedImports) { const module = deduplicate( diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 9c8c198e1b2..2747a6f03f6 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -263,6 +263,16 @@ namespace ts.server { return result; } + export function convertTypeAcquisition(protocolOptions: protocol.InferredProjectCompilerOptions): TypeAcquisition | undefined { + let result: TypeAcquisition | undefined; + typeAcquisitionDeclarations.forEach((option) => { + const propertyValue = protocolOptions[option.name]; + if (propertyValue === undefined) return; + (result || (result = {}))[option.name] = propertyValue; + }); + return result; + } + export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind { return isString(scriptKindName) ? convertScriptKindName(scriptKindName) : scriptKindName; } @@ -434,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( @@ -504,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); @@ -530,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) ); } @@ -642,6 +693,8 @@ namespace ts.server { private compilerOptionsForInferredProjectsPerProjectRoot = new Map(); private watchOptionsForInferredProjects: WatchOptions | undefined; private watchOptionsForInferredProjectsPerProjectRoot = new Map(); + private typeAcquisitionForInferredProjects: TypeAcquisition | undefined; + private typeAcquisitionForInferredProjectsPerProjectRoot = new Map(); /** * Project size for configured or external projects */ @@ -982,11 +1035,12 @@ namespace ts.server { } } - setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions, projectRootPath?: string): void { + setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.InferredProjectCompilerOptions, projectRootPath?: string): void { Debug.assert(projectRootPath === undefined || this.useInferredProjectPerProjectRoot, "Setting compiler options per project root path is only supported when useInferredProjectPerProjectRoot is enabled"); const compilerOptions = convertCompilerOptions(projectCompilerOptions); const watchOptions = convertWatchOptions(projectCompilerOptions); + const typeAcquisition = convertTypeAcquisition(projectCompilerOptions); // always set 'allowNonTsExtensions' for inferred projects since user cannot configure it from the outside // previously we did not expose a way for user to change these settings and this option was enabled by default @@ -995,10 +1049,12 @@ namespace ts.server { if (canonicalProjectRootPath) { this.compilerOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, compilerOptions); this.watchOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, watchOptions || false); + this.typeAcquisitionForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, typeAcquisition); } else { this.compilerOptionsForInferredProjects = compilerOptions; this.watchOptionsForInferredProjects = watchOptions; + this.typeAcquisitionForInferredProjects = typeAcquisition; } for (const project of this.inferredProjects) { @@ -1015,6 +1071,7 @@ namespace ts.server { !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) { project.setCompilerOptions(compilerOptions); project.setWatchOptions(watchOptions); + project.setTypeAcquisition(typeAcquisition); project.compileOnSaveEnabled = compilerOptions.compileOnSave!; project.markAsDirty(); this.delayUpdateProjectGraph(project); @@ -2298,13 +2355,18 @@ namespace ts.server { private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: NormalizedPath): InferredProject { const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects!; // TODO: GH#18217 let watchOptions: WatchOptions | false | undefined; + let typeAcquisition: TypeAcquisition | undefined; if (projectRootPath) { watchOptions = this.watchOptionsForInferredProjectsPerProjectRoot.get(projectRootPath); + typeAcquisition = this.typeAcquisitionForInferredProjectsPerProjectRoot.get(projectRootPath); } if (watchOptions === undefined) { watchOptions = this.watchOptionsForInferredProjects; } - const project = new InferredProject(this, this.documentRegistry, compilerOptions, watchOptions || undefined, projectRootPath, currentDirectory, this.currentPluginConfigOverrides); + if (typeAcquisition === undefined) { + typeAcquisition = this.typeAcquisitionForInferredProjects; + } + const project = new InferredProject(this, this.documentRegistry, compilerOptions, watchOptions || undefined, projectRootPath, currentDirectory, this.currentPluginConfigOverrides, typeAcquisition); if (isSingleInferredProject) { this.inferredProjects.unshift(project); } @@ -2854,6 +2916,7 @@ namespace ts.server { if (!projectContainsInfoDirectly(project, info)) { const referencedProject = forEachResolvedProjectReferenceProject( project, + info.path, child => { reloadChildProject(child); return projectContainsInfoDirectly(child, info); @@ -2864,6 +2927,7 @@ namespace ts.server { // Reload the project's tree that is already present forEachResolvedProjectReferenceProject( project, + /*fileName*/ undefined, reloadChildProject, ProjectReferenceProjectLoadKind.Find ); @@ -2969,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; @@ -3049,6 +3114,7 @@ namespace ts.server { if (!projectContainsInfoDirectly(project, info)) { forEachResolvedProjectReferenceProject( project, + info.path, child => { updateProjectIfDirty(child); // Retain these projects @@ -3163,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) { @@ -3513,8 +3584,8 @@ namespace ts.server { const { rootFiles } = proj; const typeAcquisition = proj.typeAcquisition!; Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now"); - // If type acquisition has been explicitly disabled, do not exclude anything from the project - if (typeAcquisition.enable === false) { + + if (typeAcquisition.enable === false || typeAcquisition.disableFilenameBasedTypeAcquisition) { return []; } diff --git a/src/server/project.ts b/src/server/project.ts index b0dbbb0ef11..ee64647bdee 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -249,6 +249,8 @@ namespace ts.server { private symlinks: SymlinkCache | undefined; /*@internal*/ autoImportProviderHost: AutoImportProviderProject | false | undefined; + /*@internal*/ + protected typeAcquisition: TypeAcquisition | undefined; /*@internal*/ constructor( @@ -703,12 +705,11 @@ namespace ts.server { getProjectName() { return this.projectName; } - abstract getTypeAcquisition(): TypeAcquisition; - protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition): TypeAcquisition { + protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): TypeAcquisition { if (!newTypeAcquisition || !newTypeAcquisition.include) { // Nothing to filter out, so just return as-is - return newTypeAcquisition; + return newTypeAcquisition || {}; } return { ...newTypeAcquisition, include: this.removeExistingTypings(newTypeAcquisition.include) }; } @@ -749,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 @@ -1098,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); } }); @@ -1411,6 +1409,14 @@ namespace ts.server { return this.watchOptions; } + setTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): void { + this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); + } + + getTypeAcquisition() { + return this.typeAcquisition || {}; + } + /* @internal */ getChangesSinceVersion(lastKnownVersion?: number, includeProjectReferenceRedirectInfo?: boolean): ProjectFilesWithTSDiagnostics { const includeProjectReferenceRedirectInfoIfRequested = @@ -1786,7 +1792,8 @@ namespace ts.server { watchOptions: WatchOptions | undefined, projectRootPath: NormalizedPath | undefined, currentDirectory: string | undefined, - pluginConfigOverrides: ESMap | undefined) { + pluginConfigOverrides: ESMap | undefined, + typeAcquisition: TypeAcquisition | undefined) { super(InferredProject.newName(), ProjectKind.Inferred, projectService, @@ -1799,6 +1806,7 @@ namespace ts.server { watchOptions, projectService.host, currentDirectory); + this.typeAcquisition = typeAcquisition; this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath); if (!projectRootPath && !projectService.useSingleInferredProject) { this.canonicalCurrentDirectory = projectService.toCanonicalFileName(this.currentDirectory); @@ -1844,7 +1852,7 @@ namespace ts.server { } getTypeAcquisition(): TypeAcquisition { - return { + return this.typeAcquisition || { enable: allRootFilesAreJsOrDts(this), include: ts.emptyArray, exclude: ts.emptyArray @@ -2026,7 +2034,6 @@ namespace ts.server { * Otherwise it will create an InferredProject. */ export class ConfiguredProject extends Project { - private typeAcquisition: TypeAcquisition | undefined; /* @internal */ configFileWatcher: FileWatcher | undefined; private directoriesWatchedForWildcards: ESMap | undefined; @@ -2191,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; @@ -2238,14 +2252,6 @@ namespace ts.server { this.projectErrors = projectErrors; } - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void { - this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); - } - - getTypeAcquisition() { - return this.typeAcquisition || {}; - } - /*@internal*/ watchWildcards(wildcardDirectories: ESMap) { updateWatchingWildcardDirectories( @@ -2299,6 +2305,7 @@ namespace ts.server { getDefaultChildProjectFromProjectWithReferences(info: ScriptInfo) { return forEachResolvedProjectReferenceProject( this, + info.path, child => projectContainsInfoDirectly(child, info) ? child : undefined, @@ -2336,6 +2343,7 @@ namespace ts.server { return this.containsScriptInfo(info) || !!forEachResolvedProjectReferenceProject( this, + info.path, child => child.containsScriptInfo(info), ProjectReferenceProjectLoadKind.Find ); @@ -2364,7 +2372,6 @@ namespace ts.server { */ export class ExternalProject extends Project { excludedFiles: readonly NormalizedPath[] = []; - private typeAcquisition: TypeAcquisition | undefined; /*@internal*/ constructor(public externalProjectName: string, projectService: ProjectService, @@ -2398,18 +2405,6 @@ namespace ts.server { getExcludedFiles() { return this.excludedFiles; } - - getTypeAcquisition() { - return this.typeAcquisition || {}; - } - - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void { - Debug.assert(!!newTypeAcquisition, "newTypeAcquisition may not be null/undefined"); - Debug.assert(!!newTypeAcquisition.include, "newTypeAcquisition.include may not be null/undefined"); - Debug.assert(!!newTypeAcquisition.exclude, "newTypeAcquisition.exclude may not be null/undefined"); - Debug.assert(typeof newTypeAcquisition.enable === "boolean", "newTypeAcquisition.enable may not be null/undefined"); - this.typeAcquisition = this.removeLocalTypingsFromTypeAcquisition(newTypeAcquisition); - } } /* @internal */ diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 6a52afc8175..3706f5b85ec 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1762,6 +1762,11 @@ namespace ts.server.protocol { closedFiles?: string[]; } + /** + * External projects have a typeAcquisition option so they need to be added separately to compiler options for inferred projects. + */ + export type InferredProjectCompilerOptions = ExternalProjectCompilerOptions & TypeAcquisition; + /** * Request to set compiler options for inferred projects. * External projects are opened / closed explicitly. @@ -1783,7 +1788,7 @@ namespace ts.server.protocol { /** * Compiler options to be used with inferred projects. */ - options: ExternalProjectCompilerOptions; + options: InferredProjectCompilerOptions; /** * Specifies the project root path used to scope compiler options. 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/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index e9c77566b70..26ce8eca6dd 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -207,6 +207,50 @@ namespace ts.projectSystem { checkProjectActualFiles(p, [file1.path, jquery.path]); }); + it("inferred project - type acquisition with disableFilenameBasedTypeAcquisition:true", () => { + // Tests: + // Exclude file with disableFilenameBasedTypeAcquisition:true + const jqueryJs = { + path: "/a/b/jquery.js", + content: "" + }; + + const messages: string[] = []; + const host = createServerHost([jqueryJs]); + const installer = new (class extends Installer { + constructor() { + super(host, { typesRegistry: createTypesRegistry("jquery") }, { isEnabled: () => true, writeLine: msg => messages.push(msg) }); + } + enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray) { + super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports); + } + installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void { + const installedTypings: string[] = []; + const typingFiles: File[] = []; + executeCommand(this, host, installedTypings, typingFiles, cb); + } + })(); + + const projectService = createProjectService(host, { typingsInstaller: installer }); + projectService.setCompilerOptionsForInferredProjects({ + allowJs: true, + enable: true, + disableFilenameBasedTypeAcquisition: true + }); + projectService.openClientFile(jqueryJs.path); + + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + const p = projectService.inferredProjects[0]; + checkProjectActualFiles(p, [jqueryJs.path]); + + installer.installAll(/*expectedCount*/ 0); + host.checkTimeoutQueueLengthAndRun(2); + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + // files should not be removed from project if ATA is skipped + checkProjectActualFiles(p, [jqueryJs.path]); + assert.isTrue(messages.indexOf("No new typings were requested as a result of typings discovery") > 0, "Should not request filename-based typings"); + }); + it("external project - no type acquisition, no .d.ts/js files", () => { const file1 = { path: "/a/b/app.ts", @@ -434,6 +478,51 @@ namespace ts.projectSystem { installer.checkPendingCommands(/*expectedCount*/ 0); }); + + it("external project - type acquisition with disableFilenameBasedTypeAcquisition:true", () => { + // Tests: + // Exclude file with disableFilenameBasedTypeAcquisition:true + const jqueryJs = { + path: "/a/b/jquery.js", + content: "" + }; + + const messages: string[] = []; + const host = createServerHost([jqueryJs]); + const installer = new (class extends Installer { + constructor() { + super(host, { typesRegistry: createTypesRegistry("jquery") }, { isEnabled: () => true, writeLine: msg => messages.push(msg) }); + } + enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray) { + super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports); + } + installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void { + const installedTypings: string[] = []; + const typingFiles: File[] = []; + executeCommand(this, host, installedTypings, typingFiles, cb); + } + })(); + + const projectFileName = "/a/app/test.csproj"; + const projectService = createProjectService(host, { typingsInstaller: installer }); + projectService.openExternalProject({ + projectFileName, + options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs }, + rootFiles: [toExternalFile(jqueryJs.path)], + typeAcquisition: { enable: true, disableFilenameBasedTypeAcquisition: true } + }); + + const p = projectService.externalProjects[0]; + projectService.checkNumberOfProjects({ externalProjects: 1 }); + checkProjectActualFiles(p, [jqueryJs.path]); + + installer.installAll(/*expectedCount*/ 0); + projectService.checkNumberOfProjects({ externalProjects: 1 }); + // files should not be removed from project if ATA is skipped + checkProjectActualFiles(p, [jqueryJs.path]); + assert.isTrue(messages.indexOf("No new typings were requested as a result of typings discovery") > 0, "Should not request filename-based typings"); + }); + it("external project - no type acquisition, with js & ts files", () => { // Tests: // 1. No typings are included for JS projects when the project contains ts files diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 15653ecacf2..f9f821331ba 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2891,7 +2891,8 @@ declare namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - [option: string]: string[] | boolean | undefined; + disableFilenameBasedTypeAcquisition?: boolean; + [option: string]: CompilerOptionsValue | undefined; } export enum ModuleKind { None = 0, @@ -7754,6 +7755,10 @@ declare namespace ts.server.protocol { */ closedFiles?: string[]; } + /** + * External projects have a typeAcquisition option so they need to be added separately to compiler options for inferred projects. + */ + type InferredProjectCompilerOptions = ExternalProjectCompilerOptions & TypeAcquisition; /** * Request to set compiler options for inferred projects. * External projects are opened / closed explicitly. @@ -7774,7 +7779,7 @@ declare namespace ts.server.protocol { /** * Compiler options to be used with inferred projects. */ - options: ExternalProjectCompilerOptions; + options: InferredProjectCompilerOptions; /** * Specifies the project root path used to scope compiler options. * It is an error to provide this property if the server has not been started with @@ -9300,8 +9305,7 @@ declare namespace ts.server { enableLanguageService(): void; disableLanguageService(lastFileExceededProgramSize?: string): void; getProjectName(): string; - abstract getTypeAcquisition(): TypeAcquisition; - protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition): TypeAcquisition; + protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): TypeAcquisition; getExternalFiles(): SortedReadonlyArray; getSourceFile(path: Path): SourceFile | undefined; close(): void; @@ -9339,6 +9343,8 @@ declare namespace ts.server { getScriptInfo(uncheckedFileName: string): ScriptInfo | undefined; filesToString(writeProjectFileNames: boolean): string; setCompilerOptions(compilerOptions: CompilerOptions): void; + setTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): void; + getTypeAcquisition(): TypeAcquisition; protected removeRoot(info: ScriptInfo): void; protected enableGlobalPlugins(options: CompilerOptions, pluginConfigOverrides: Map | undefined): void; protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[], pluginConfigOverrides: Map | undefined): void; @@ -9384,7 +9390,6 @@ declare namespace ts.server { * Otherwise it will create an InferredProject. */ class ConfiguredProject extends Project { - private typeAcquisition; private directoriesWatchedForWildcards; readonly canonicalConfigFilePath: NormalizedPath; /** Ref count to the project when opened from external project */ @@ -9408,8 +9413,6 @@ declare namespace ts.server { */ getAllProjectErrors(): readonly Diagnostic[]; setProjectErrors(projectErrors: Diagnostic[]): void; - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; - getTypeAcquisition(): TypeAcquisition; close(): void; getEffectiveTypeRoots(): string[]; } @@ -9421,11 +9424,8 @@ declare namespace ts.server { externalProjectName: string; compileOnSaveEnabled: boolean; excludedFiles: readonly NormalizedPath[]; - private typeAcquisition; updateGraph(): boolean; getExcludedFiles(): readonly NormalizedPath[]; - getTypeAcquisition(): TypeAcquisition; - setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; } } declare namespace ts.server { @@ -9559,6 +9559,7 @@ declare namespace ts.server { export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings; export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin; export function convertWatchOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): WatchOptions | undefined; + export function convertTypeAcquisition(protocolOptions: protocol.InferredProjectCompilerOptions): TypeAcquisition | undefined; export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind; export function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX; export interface HostConfiguration { @@ -9627,6 +9628,8 @@ declare namespace ts.server { private compilerOptionsForInferredProjectsPerProjectRoot; private watchOptionsForInferredProjects; private watchOptionsForInferredProjectsPerProjectRoot; + private typeAcquisitionForInferredProjects; + private typeAcquisitionForInferredProjectsPerProjectRoot; /** * Project size for configured or external projects */ @@ -9672,7 +9675,7 @@ declare namespace ts.server { updateTypingsForProject(response: SetTypings | InvalidateCachedTypings | PackageInstalledResponse): void; private delayUpdateProjectGraph; private delayUpdateProjectGraphs; - setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions, projectRootPath?: string): void; + setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.InferredProjectCompilerOptions, projectRootPath?: string): void; findProject(projectName: string): Project | undefined; getDefaultProjectForFile(fileName: NormalizedPath, ensureProject: boolean): Project | undefined; private doEnsureDefaultProjectForFile; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 26cdf6ba460..5ae7f935e21 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2891,7 +2891,8 @@ declare namespace ts { enable?: boolean; include?: string[]; exclude?: string[]; - [option: string]: string[] | boolean | undefined; + disableFilenameBasedTypeAcquisition?: boolean; + [option: string]: CompilerOptionsValue | undefined; } export enum ModuleKind { None = 0, diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).js b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).js new file mode 100644 index 00000000000..88593e08d5c --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).js @@ -0,0 +1,29 @@ +//// [jsxEmptyExpressionNotCountedAsChild.tsx] +/// +import * as React from 'react' + +interface Props { + children: React.ReactElement +} + +function Wrapper(props: Props) { + return
{props.children}
+} + +const element = ( + + {/* comment */} +
Hello
+
+) + +//// [jsxEmptyExpressionNotCountedAsChild.js] +"use strict"; +exports.__esModule = true; +/// +var React = require("react"); +function Wrapper(props) { + return React.createElement("div", null, props.children); +} +var element = (React.createElement(Wrapper, null, + React.createElement("div", null, "Hello"))); diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).symbols b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).symbols new file mode 100644 index 00000000000..f8c95e444e2 --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).symbols @@ -0,0 +1,42 @@ +=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx === +/// +import * as React from 'react' +>React : Symbol(React, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 6)) + +interface Props { +>Props : Symbol(Props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 30)) + + children: React.ReactElement +>children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>React : Symbol(React, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 6)) +>ReactElement : Symbol(React.ReactElement, Decl(react16.d.ts, 135, 9)) +} + +function Wrapper(props: Props) { +>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) +>props : Symbol(props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 7, 17)) +>Props : Symbol(Props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 30)) + + return
{props.children}
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>props.children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>props : Symbol(props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 7, 17)) +>children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +} + +const element = ( +>element : Symbol(element, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 11, 5)) + + +>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) + + {/* comment */} +
Hello
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) + +
+>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) + +) diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).types b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).types new file mode 100644 index 00000000000..c53d5e821ea --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react).types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx === +/// +import * as React from 'react' +>React : typeof React + +interface Props { + children: React.ReactElement +>children : React.ReactElement +>React : any +} + +function Wrapper(props: Props) { +>Wrapper : (props: Props) => JSX.Element +>props : Props + + return
{props.children}
+>
{props.children}
: JSX.Element +>div : any +>props.children : React.ReactElement +>props : Props +>children : React.ReactElement +>div : any +} + +const element = ( +>element : JSX.Element +>( {/* comment */}
Hello
) : JSX.Element + + +> {/* comment */}
Hello
: JSX.Element +>Wrapper : (props: Props) => JSX.Element + + {/* comment */} +
Hello
+>
Hello
: JSX.Element +>div : any +>div : any + +
+>Wrapper : (props: Props) => JSX.Element + +) diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).js b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).js new file mode 100644 index 00000000000..3d2aeb4218c --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).js @@ -0,0 +1,29 @@ +//// [jsxEmptyExpressionNotCountedAsChild.tsx] +/// +import * as React from 'react' + +interface Props { + children: React.ReactElement +} + +function Wrapper(props: Props) { + return
{props.children}
+} + +const element = ( + + {/* comment */} +
Hello
+
+) + +//// [jsxEmptyExpressionNotCountedAsChild.js] +"use strict"; +exports.__esModule = true; +var jsx_runtime_1 = require("react/jsx-runtime"); +/// +var React = require("react"); +function Wrapper(props) { + return jsx_runtime_1.jsx("div", { children: props.children }, void 0); +} +var element = (jsx_runtime_1.jsx(Wrapper, { children: jsx_runtime_1.jsx("div", { children: "Hello" }, void 0) }, void 0)); diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).symbols b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).symbols new file mode 100644 index 00000000000..f8c95e444e2 --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).symbols @@ -0,0 +1,42 @@ +=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx === +/// +import * as React from 'react' +>React : Symbol(React, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 6)) + +interface Props { +>Props : Symbol(Props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 30)) + + children: React.ReactElement +>children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>React : Symbol(React, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 6)) +>ReactElement : Symbol(React.ReactElement, Decl(react16.d.ts, 135, 9)) +} + +function Wrapper(props: Props) { +>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) +>props : Symbol(props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 7, 17)) +>Props : Symbol(Props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 30)) + + return
{props.children}
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>props.children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>props : Symbol(props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 7, 17)) +>children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +} + +const element = ( +>element : Symbol(element, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 11, 5)) + + +>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) + + {/* comment */} +
Hello
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) + +
+>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) + +) diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).types b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).types new file mode 100644 index 00000000000..c53d5e821ea --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx === +/// +import * as React from 'react' +>React : typeof React + +interface Props { + children: React.ReactElement +>children : React.ReactElement +>React : any +} + +function Wrapper(props: Props) { +>Wrapper : (props: Props) => JSX.Element +>props : Props + + return
{props.children}
+>
{props.children}
: JSX.Element +>div : any +>props.children : React.ReactElement +>props : Props +>children : React.ReactElement +>div : any +} + +const element = ( +>element : JSX.Element +>( {/* comment */}
Hello
) : JSX.Element + + +> {/* comment */}
Hello
: JSX.Element +>Wrapper : (props: Props) => JSX.Element + + {/* comment */} +
Hello
+>
Hello
: JSX.Element +>div : any +>div : any + +
+>Wrapper : (props: Props) => JSX.Element + +) diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).js b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).js new file mode 100644 index 00000000000..5561b73e454 --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).js @@ -0,0 +1,30 @@ +//// [jsxEmptyExpressionNotCountedAsChild.tsx] +/// +import * as React from 'react' + +interface Props { + children: React.ReactElement +} + +function Wrapper(props: Props) { + return
{props.children}
+} + +const element = ( + + {/* comment */} +
Hello
+
+) + +//// [jsxEmptyExpressionNotCountedAsChild.js] +"use strict"; +exports.__esModule = true; +var jsx_dev_runtime_1 = require("react/jsx-dev-runtime"); +var _jsxFileName = "tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx"; +/// +var React = require("react"); +function Wrapper(props) { + return jsx_dev_runtime_1.jsxDEV("div", { children: props.children }, void 0, false, { fileName: _jsxFileName, lineNumber: 9, columnNumber: 11 }, this); +} +var element = (jsx_dev_runtime_1.jsxDEV(Wrapper, { children: jsx_dev_runtime_1.jsxDEV("div", { children: "Hello" }, void 0, false, { fileName: _jsxFileName, lineNumber: 15, columnNumber: 6 }, this) }, void 0, false, { fileName: _jsxFileName, lineNumber: 12, columnNumber: 18 }, this)); diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).symbols b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).symbols new file mode 100644 index 00000000000..f8c95e444e2 --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).symbols @@ -0,0 +1,42 @@ +=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx === +/// +import * as React from 'react' +>React : Symbol(React, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 6)) + +interface Props { +>Props : Symbol(Props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 30)) + + children: React.ReactElement +>children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>React : Symbol(React, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 6)) +>ReactElement : Symbol(React.ReactElement, Decl(react16.d.ts, 135, 9)) +} + +function Wrapper(props: Props) { +>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) +>props : Symbol(props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 7, 17)) +>Props : Symbol(Props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 1, 30)) + + return
{props.children}
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>props.children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>props : Symbol(props, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 7, 17)) +>children : Symbol(Props.children, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 3, 17)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +} + +const element = ( +>element : Symbol(element, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 11, 5)) + + +>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) + + {/* comment */} +
Hello
+>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114)) + +
+>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1)) + +) diff --git a/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).types b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).types new file mode 100644 index 00000000000..c53d5e821ea --- /dev/null +++ b/tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx === +/// +import * as React from 'react' +>React : typeof React + +interface Props { + children: React.ReactElement +>children : React.ReactElement +>React : any +} + +function Wrapper(props: Props) { +>Wrapper : (props: Props) => JSX.Element +>props : Props + + return
{props.children}
+>
{props.children}
: JSX.Element +>div : any +>props.children : React.ReactElement +>props : Props +>children : React.ReactElement +>div : any +} + +const element = ( +>element : JSX.Element +>( {/* comment */}
Hello
) : JSX.Element + + +> {/* comment */}
Hello
: JSX.Element +>Wrapper : (props: Props) => JSX.Element + + {/* comment */} +
Hello
+>
Hello
: JSX.Element +>div : any +>div : any + +
+>Wrapper : (props: Props) => JSX.Element + +) 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/jsxJsxsCjsTransformKeyProp(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformKeyProp(jsx=react-jsx).js index 4ef773b9111..0a4e9ed38b3 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformKeyProp(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyProp(jsx=react-jsx).js @@ -22,8 +22,8 @@ var __assign = (this && this.__assign) || function () { }; exports.__esModule = true; var react_1 = require("react"); -var jsx_runtime_js_1 = require("react/jsx-runtime.js"); +var jsx_runtime_1 = require("react/jsx-runtime"); /// var props = { answer: 42 }; -var a = jsx_runtime_js_1.jsx("div", __assign({}, props, { children: "text" }), "foo"); +var a = jsx_runtime_1.jsx("div", __assign({}, props, { children: "text" }), "foo"); var b = react_1.createElement("div", __assign({}, props, { key: "bar" }), "text"); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyProp(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformKeyProp(jsx=react-jsxdev).js index fa5bdb38552..fc8b8fb6470 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformKeyProp(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyProp(jsx=react-jsxdev).js @@ -22,9 +22,9 @@ var __assign = (this && this.__assign) || function () { }; exports.__esModule = true; var react_1 = require("react"); -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/jsxJsxsCjsTransformKeyProp.tsx"; /// var props = { answer: 42 }; -var a = jsx_dev_runtime_js_1.jsxDEV("div", __assign({}, props, { children: "text" }), "foo", false, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV("div", __assign({}, props, { children: "text" }), "foo", false, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 10 }, this); var b = react_1.createElement("div", __assign({}, props, { key: "bar" }), "text"); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsx).js index da3771ec312..5183b426630 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsx).js @@ -22,8 +22,8 @@ var __assign = (this && this.__assign) || function () { }; exports.__esModule = true; var preact_1 = require("preact"); -var jsx_runtime_js_1 = require("preact/jsx-runtime.js"); +var jsx_runtime_1 = require("preact/jsx-runtime"); /// var props = { answer: 42 }; -var a = jsx_runtime_js_1.jsx("div", __assign({}, props, { children: "text" }), "foo"); +var a = jsx_runtime_1.jsx("div", __assign({}, props, { children: "text" }), "foo"); var b = preact_1.createElement("div", __assign({}, props, { key: "bar" }), "text"); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsxdev).js index 46cbac3c9fd..ef1e4bd6a99 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImport(jsx=react-jsxdev).js @@ -22,9 +22,9 @@ var __assign = (this && this.__assign) || function () { }; exports.__esModule = true; var preact_1 = require("preact"); -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/jsxJsxsCjsTransformKeyPropCustomImport.tsx"; /// var props = { answer: 42 }; -var a = jsx_dev_runtime_js_1.jsxDEV("div", __assign({}, props, { children: "text" }), "foo", false, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV("div", __assign({}, props, { children: "text" }), "foo", false, { fileName: _jsxFileName, lineNumber: 3, columnNumber: 10 }, this); var b = preact_1.createElement("div", __assign({}, props, { key: "bar" }), "text"); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsx).js b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsx).js index 11600352cd2..2daf68d6ce3 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsx).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsx).js @@ -35,11 +35,11 @@ var __assign = (this && this.__assign) || function () { }; exports.__esModule = true; var preact_1 = require("preact"); -var jsx_runtime_js_1 = require("preact/jsx-runtime.js"); +var jsx_runtime_1 = require("preact/jsx-runtime"); /// /* @jsxImportSource preact */ var props = { answer: 42 }; -var a = jsx_runtime_js_1.jsx("div", __assign({}, props, { children: "text" }), "foo"); +var a = jsx_runtime_1.jsx("div", __assign({}, props, { children: "text" }), "foo"); var b = preact_1.createElement("div", __assign({}, props, { key: "bar" }), "text"); //// [react.js] "use strict"; @@ -56,10 +56,10 @@ var __assign = (this && this.__assign) || function () { }; exports.__esModule = true; var react_1 = require("react"); -var jsx_runtime_js_1 = require("react/jsx-runtime.js"); +var jsx_runtime_1 = require("react/jsx-runtime"); /// /* @jsxImportSource react */ require("./preact"); var props2 = { answer: 42 }; -var a2 = jsx_runtime_js_1.jsx("div", __assign({}, props2, { children: "text" }), "foo"); +var a2 = jsx_runtime_1.jsx("div", __assign({}, props2, { children: "text" }), "foo"); var b2 = react_1.createElement("div", __assign({}, props2, { key: "bar" }), "text"); diff --git a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsxdev).js b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsxdev).js index 672fe8faa10..8aa24328c00 100644 --- a/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsxdev).js +++ b/tests/baselines/reference/jsxJsxsCjsTransformKeyPropCustomImportPragma(jsx=react-jsxdev).js @@ -35,12 +35,12 @@ var __assign = (this && this.__assign) || function () { }; exports.__esModule = true; var preact_1 = require("preact"); -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 props = { answer: 42 }; -var a = jsx_dev_runtime_js_1.jsxDEV("div", __assign({}, props, { children: "text" }), "foo", false, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 10 }, this); +var a = jsx_dev_runtime_1.jsxDEV("div", __assign({}, props, { children: "text" }), "foo", false, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 10 }, this); var b = preact_1.createElement("div", __assign({}, props, { key: "bar" }), "text"); //// [react.js] "use strict"; @@ -57,11 +57,11 @@ var __assign = (this && this.__assign) || function () { }; exports.__esModule = true; var react_1 = require("react"); -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 props2 = { answer: 42 }; -var a2 = jsx_dev_runtime_js_1.jsxDEV("div", __assign({}, props2, { children: "text" }), "foo", false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 11 }, this); +var a2 = jsx_dev_runtime_1.jsxDEV("div", __assign({}, props2, { children: "text" }), "foo", false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 11 }, this); var b2 = react_1.createElement("div", __assign({}, props2, { key: "bar" }), "text"); 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/objectInstantiationFromUnionSpread.js b/tests/baselines/reference/objectInstantiationFromUnionSpread.js new file mode 100644 index 00000000000..2339e0fe840 --- /dev/null +++ b/tests/baselines/reference/objectInstantiationFromUnionSpread.js @@ -0,0 +1,41 @@ +//// [objectInstantiationFromUnionSpread.ts] +// #40995 + +interface Success { + isSuccess: true; +} + +interface Fail { + isSuccess: false; +} + +type Item = Success | Fail; + +function f1(a: Item[]) { + a.map(item => ({ ...item })).filter(value => {}); +} + +function f2(a: Item[]) { + a.map(item => ({ ...item })).filter(value => {}); +} + + +//// [objectInstantiationFromUnionSpread.js] +// #40995 +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +function f1(a) { + a.map(function (item) { return (__assign({}, item)); }).filter(function (value) { }); +} +function f2(a) { + a.map(function (item) { return (__assign({}, item)); }).filter(function (value) { }); +} diff --git a/tests/baselines/reference/objectInstantiationFromUnionSpread.symbols b/tests/baselines/reference/objectInstantiationFromUnionSpread.symbols new file mode 100644 index 00000000000..53127700e01 --- /dev/null +++ b/tests/baselines/reference/objectInstantiationFromUnionSpread.symbols @@ -0,0 +1,55 @@ +=== tests/cases/compiler/objectInstantiationFromUnionSpread.ts === +// #40995 + +interface Success { +>Success : Symbol(Success, Decl(objectInstantiationFromUnionSpread.ts, 0, 0)) + + isSuccess: true; +>isSuccess : Symbol(Success.isSuccess, Decl(objectInstantiationFromUnionSpread.ts, 2, 19)) +} + +interface Fail { +>Fail : Symbol(Fail, Decl(objectInstantiationFromUnionSpread.ts, 4, 1)) + + isSuccess: false; +>isSuccess : Symbol(Fail.isSuccess, Decl(objectInstantiationFromUnionSpread.ts, 6, 16)) +} + +type Item = Success | Fail; +>Item : Symbol(Item, Decl(objectInstantiationFromUnionSpread.ts, 8, 1)) +>Success : Symbol(Success, Decl(objectInstantiationFromUnionSpread.ts, 0, 0)) +>Fail : Symbol(Fail, Decl(objectInstantiationFromUnionSpread.ts, 4, 1)) + +function f1(a: Item[]) { +>f1 : Symbol(f1, Decl(objectInstantiationFromUnionSpread.ts, 10, 27)) +>a : Symbol(a, Decl(objectInstantiationFromUnionSpread.ts, 12, 12)) +>Item : Symbol(Item, Decl(objectInstantiationFromUnionSpread.ts, 8, 1)) + + a.map(item => ({ ...item })).filter(value => {}); +>a.map(item => ({ ...item })).filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>a.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(objectInstantiationFromUnionSpread.ts, 12, 12)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>item : Symbol(item, Decl(objectInstantiationFromUnionSpread.ts, 13, 8)) +>item : Symbol(item, Decl(objectInstantiationFromUnionSpread.ts, 13, 8)) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(objectInstantiationFromUnionSpread.ts, 13, 38)) +} + +function f2(a: Item[]) { +>f2 : Symbol(f2, Decl(objectInstantiationFromUnionSpread.ts, 14, 1)) +>T : Symbol(T, Decl(objectInstantiationFromUnionSpread.ts, 16, 12)) +>a : Symbol(a, Decl(objectInstantiationFromUnionSpread.ts, 16, 15)) +>Item : Symbol(Item, Decl(objectInstantiationFromUnionSpread.ts, 8, 1)) + + a.map(item => ({ ...item })).filter(value => {}); +>a.map(item => ({ ...item })).filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>a.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(objectInstantiationFromUnionSpread.ts, 16, 15)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>item : Symbol(item, Decl(objectInstantiationFromUnionSpread.ts, 17, 8)) +>item : Symbol(item, Decl(objectInstantiationFromUnionSpread.ts, 17, 8)) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(objectInstantiationFromUnionSpread.ts, 17, 38)) +} + diff --git a/tests/baselines/reference/objectInstantiationFromUnionSpread.types b/tests/baselines/reference/objectInstantiationFromUnionSpread.types new file mode 100644 index 00000000000..3061622551c --- /dev/null +++ b/tests/baselines/reference/objectInstantiationFromUnionSpread.types @@ -0,0 +1,60 @@ +=== tests/cases/compiler/objectInstantiationFromUnionSpread.ts === +// #40995 + +interface Success { + isSuccess: true; +>isSuccess : true +>true : true +} + +interface Fail { + isSuccess: false; +>isSuccess : false +>false : false +} + +type Item = Success | Fail; +>Item : Item + +function f1(a: Item[]) { +>f1 : (a: Item[]) => void +>a : Item[] + + a.map(item => ({ ...item })).filter(value => {}); +>a.map(item => ({ ...item })).filter(value => {}) : ({ isSuccess: true; } | { isSuccess: false; })[] +>a.map(item => ({ ...item })).filter : { (predicate: (value: { isSuccess: true; } | { isSuccess: false; }, index: number, array: ({ isSuccess: true; } | { isSuccess: false; })[]) => value is S, thisArg?: any): S[]; (predicate: (value: { isSuccess: true; } | { isSuccess: false; }, index: number, array: ({ isSuccess: true; } | { isSuccess: false; })[]) => unknown, thisArg?: any): ({ isSuccess: true; } | { isSuccess: false; })[]; } +>a.map(item => ({ ...item })) : ({ isSuccess: true; } | { isSuccess: false; })[] +>a.map : (callbackfn: (value: Item, index: number, array: Item[]) => U, thisArg?: any) => U[] +>a : Item[] +>map : (callbackfn: (value: Item, index: number, array: Item[]) => U, thisArg?: any) => U[] +>item => ({ ...item }) : (item: Item) => { isSuccess: true; } | { isSuccess: false; } +>item : Item +>({ ...item }) : { isSuccess: true; } | { isSuccess: false; } +>{ ...item } : { isSuccess: true; } | { isSuccess: false; } +>item : Item +>filter : { (predicate: (value: { isSuccess: true; } | { isSuccess: false; }, index: number, array: ({ isSuccess: true; } | { isSuccess: false; })[]) => value is S, thisArg?: any): S[]; (predicate: (value: { isSuccess: true; } | { isSuccess: false; }, index: number, array: ({ isSuccess: true; } | { isSuccess: false; })[]) => unknown, thisArg?: any): ({ isSuccess: true; } | { isSuccess: false; })[]; } +>value => {} : (value: { isSuccess: true; } | { isSuccess: false; }) => void +>value : { isSuccess: true; } | { isSuccess: false; } +} + +function f2(a: Item[]) { +>f2 : (a: Item[]) => void +>a : Item[] + + a.map(item => ({ ...item })).filter(value => {}); +>a.map(item => ({ ...item })).filter(value => {}) : ({ isSuccess: true; } | { isSuccess: false; })[] +>a.map(item => ({ ...item })).filter : { (predicate: (value: { isSuccess: true; } | { isSuccess: false; }, index: number, array: ({ isSuccess: true; } | { isSuccess: false; })[]) => value is S, thisArg?: any): S[]; (predicate: (value: { isSuccess: true; } | { isSuccess: false; }, index: number, array: ({ isSuccess: true; } | { isSuccess: false; })[]) => unknown, thisArg?: any): ({ isSuccess: true; } | { isSuccess: false; })[]; } +>a.map(item => ({ ...item })) : ({ isSuccess: true; } | { isSuccess: false; })[] +>a.map : (callbackfn: (value: Item, index: number, array: Item[]) => U, thisArg?: any) => U[] +>a : Item[] +>map : (callbackfn: (value: Item, index: number, array: Item[]) => U, thisArg?: any) => U[] +>item => ({ ...item }) : (item: Item) => { isSuccess: true; } | { isSuccess: false; } +>item : Item +>({ ...item }) : { isSuccess: true; } | { isSuccess: false; } +>{ ...item } : { isSuccess: true; } | { isSuccess: false; } +>item : Item +>filter : { (predicate: (value: { isSuccess: true; } | { isSuccess: false; }, index: number, array: ({ isSuccess: true; } | { isSuccess: false; })[]) => value is S, thisArg?: any): S[]; (predicate: (value: { isSuccess: true; } | { isSuccess: false; }, index: number, array: ({ isSuccess: true; } | { isSuccess: false; })[]) => unknown, thisArg?: any): ({ isSuccess: true; } | { isSuccess: false; })[]; } +>value => {} : (value: { isSuccess: true; } | { isSuccess: false; }) => void +>value : { isSuccess: true; } | { isSuccess: false; } +} + 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/compiler/jsxEmptyExpressionNotCountedAsChild.tsx b/tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx new file mode 100644 index 00000000000..91faab11166 --- /dev/null +++ b/tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx @@ -0,0 +1,19 @@ +// @jsx: react,react-jsx,react-jsxdev +// @strict: true +/// +import * as React from 'react' + +interface Props { + children: React.ReactElement +} + +function Wrapper(props: Props) { + return
{props.children}
+} + +const element = ( + + {/* comment */} +
Hello
+
+) \ No newline at end of file diff --git a/tests/cases/compiler/objectInstantiationFromUnionSpread.ts b/tests/cases/compiler/objectInstantiationFromUnionSpread.ts new file mode 100644 index 00000000000..7e5c49bfff3 --- /dev/null +++ b/tests/cases/compiler/objectInstantiationFromUnionSpread.ts @@ -0,0 +1,21 @@ +// @strictFunctionTypes: true + +// #40995 + +interface Success { + isSuccess: true; +} + +interface Fail { + isSuccess: false; +} + +type Item = Success | Fail; + +function f1(a: Item[]) { + a.map(item => ({ ...item })).filter(value => {}); +} + +function f2(a: Item[]) { + a.map(item => ({ ...item })).filter(value => {}); +} 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}`;