Merge branch 'master' into fix/create-element-new-jsx-transform

This commit is contained in:
Wesley Wigham 2020-10-19 15:21:52 -07:00
commit 0ad22de146
No known key found for this signature in database
GPG key ID: D59F87F60C5400C9
52 changed files with 1092 additions and 298 deletions

6
package-lock.json generated
View file

@ -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
},

View file

@ -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 ? (<TypeReference>type).node! : type.symbol.declarations[0];
const links = getNodeLinks(declaration);
const target = type.objectFlags & ObjectFlags.Reference ? <DeferredTypeReference>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<string, Type>();
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<string, Type>();
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((<DeferredTypeReference>type).target, (<DeferredTypeReference>type).node, newMapper) :
target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(<MappedType>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<JsxChild>) {
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));
}

View file

@ -1134,7 +1134,11 @@ namespace ts {
name: "exclude",
type: "string"
}
}
},
{
name: "disableFilenameBasedTypeAcquisition",
type: "boolean",
},
];
/* @internal */

View file

@ -530,6 +530,51 @@ namespace ts {
return resolutions;
}
/* @internal */
export function forEachResolvedProjectReference<T>(
resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined,
cb: (resolvedProjectReference: ResolvedProjectReference, parent: ResolvedProjectReference | undefined) => T | undefined
): T | undefined {
return forEachProjectReference(/*projectReferences*/ undefined, resolvedProjectReferences, (resolvedRef, parent) => resolvedRef && cb(resolvedRef, parent));
}
function forEachProjectReference<T>(
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<Path> | 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<T>(
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<T>(
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<T>(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined;
forEachResolvedProjectReference<T>(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)));

View file

@ -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
);

View file

@ -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<T>(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined;
/*@internal*/ forEachResolvedProjectReference<T>(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<NodeId, Node>; // 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<string, Type>; // 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<string, Type>; // 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<string, Type>; // 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<T>(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined;
forEachResolvedProjectReference<T>(cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined): T | undefined;
}
/* @internal */

View file

@ -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<Diagnostic>; // See GH#19873
const filesWithDiagnostics = [] as string[] as SortedArray<string>;

View file

@ -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<string>(

View file

@ -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<T>(
project: ConfiguredProject,
fileName: string | undefined,
cb: (child: ConfiguredProject) => T | undefined,
projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind.Find | ProjectReferenceProjectLoadKind.FindCreate,
): T | undefined;
/*@internal*/
export function forEachResolvedProjectReferenceProject<T>(
project: ConfiguredProject,
fileName: string | undefined,
cb: (child: ConfiguredProject) => T | undefined,
projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind,
reason: string
): T | undefined;
export function forEachResolvedProjectReferenceProject<T>(
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<string, ProjectReferenceProjectLoadKind> | 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<T>(
project: ConfiguredProject,
cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined
function forEachResolvedProjectReferenceProjectWorker<T>(
resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[],
parentOptions: CompilerOptions,
cb: (resolvedRef: ResolvedProjectReference, loadKind: ProjectReferenceProjectLoadKind) => T | undefined,
projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind,
projectService: ProjectService,
seenResolvedRefs: ESMap<string, ProjectReferenceProjectLoadKind> | 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<T>(
@ -504,12 +555,12 @@ namespace ts.server {
function forEachAnyProjectReferenceKind<T>(
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<string, CompilerOptions>();
private watchOptionsForInferredProjects: WatchOptions | undefined;
private watchOptionsForInferredProjectsPerProjectRoot = new Map<string, WatchOptions | false>();
private typeAcquisitionForInferredProjects: TypeAcquisition | undefined;
private typeAcquisitionForInferredProjectsPerProjectRoot = new Map<string, TypeAcquisition | undefined>();
/**
* 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<NormalizedPath>) {
private ensureProjectChildren(project: ConfiguredProject, forProjects: ReadonlyCollection<string>, seenProjects: Set<NormalizedPath>) {
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 [];
}

View file

@ -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<string, any> | undefined) {
pluginConfigOverrides: ESMap<string, any> | 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<string, WildcardDirectoryWatcher> | undefined;
@ -2191,6 +2198,13 @@ namespace ts.server {
return program && program.getResolvedProjectReferenceToRedirect(fileName);
}
/*@internal*/
forEachResolvedProjectReference<T>(
cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined
): T | undefined {
return this.getCurrentProgram()?.forEachResolvedProjectReference(cb);
}
/*@internal*/
enablePluginsWithOptions(options: CompilerOptions, pluginConfigOverrides: ESMap<string, any> | 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<string, WatchDirectoryFlags>) {
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 */

View file

@ -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.

View file

@ -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<protocol.ReferencesRequest>({
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}`);
}
});
});
}

View file

@ -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<string>) {
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<string>) {
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

View file

@ -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<string>;
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<any> | undefined): void;
protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[], pluginConfigOverrides: Map<any> | 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;

View file

@ -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,

View file

@ -0,0 +1,29 @@
//// [jsxEmptyExpressionNotCountedAsChild.tsx]
/// <reference path="/.lib/react16.d.ts" />
import * as React from 'react'
interface Props {
children: React.ReactElement<any>
}
function Wrapper(props: Props) {
return <div>{props.children}</div>
}
const element = (
<Wrapper>
{/* comment */}
<div>Hello</div>
</Wrapper>
)
//// [jsxEmptyExpressionNotCountedAsChild.js]
"use strict";
exports.__esModule = true;
/// <reference path="react16.d.ts" />
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")));

View file

@ -0,0 +1,42 @@
=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx ===
/// <reference path="react16.d.ts" />
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<any>
>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 <div>{props.children}</div>
>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>
>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1))
{/* comment */}
<div>Hello</div>
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
</Wrapper>
>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1))
)

View file

@ -0,0 +1,42 @@
=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx ===
/// <reference path="react16.d.ts" />
import * as React from 'react'
>React : typeof React
interface Props {
children: React.ReactElement<any>
>children : React.ReactElement<any>
>React : any
}
function Wrapper(props: Props) {
>Wrapper : (props: Props) => JSX.Element
>props : Props
return <div>{props.children}</div>
><div>{props.children}</div> : JSX.Element
>div : any
>props.children : React.ReactElement<any>
>props : Props
>children : React.ReactElement<any>
>div : any
}
const element = (
>element : JSX.Element
>( <Wrapper> {/* comment */} <div>Hello</div> </Wrapper>) : JSX.Element
<Wrapper>
><Wrapper> {/* comment */} <div>Hello</div> </Wrapper> : JSX.Element
>Wrapper : (props: Props) => JSX.Element
{/* comment */}
<div>Hello</div>
><div>Hello</div> : JSX.Element
>div : any
>div : any
</Wrapper>
>Wrapper : (props: Props) => JSX.Element
)

View file

@ -0,0 +1,29 @@
//// [jsxEmptyExpressionNotCountedAsChild.tsx]
/// <reference path="/.lib/react16.d.ts" />
import * as React from 'react'
interface Props {
children: React.ReactElement<any>
}
function Wrapper(props: Props) {
return <div>{props.children}</div>
}
const element = (
<Wrapper>
{/* comment */}
<div>Hello</div>
</Wrapper>
)
//// [jsxEmptyExpressionNotCountedAsChild.js]
"use strict";
exports.__esModule = true;
var jsx_runtime_1 = require("react/jsx-runtime");
/// <reference path="react16.d.ts" />
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));

View file

@ -0,0 +1,42 @@
=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx ===
/// <reference path="react16.d.ts" />
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<any>
>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 <div>{props.children}</div>
>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>
>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1))
{/* comment */}
<div>Hello</div>
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
</Wrapper>
>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1))
)

View file

@ -0,0 +1,42 @@
=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx ===
/// <reference path="react16.d.ts" />
import * as React from 'react'
>React : typeof React
interface Props {
children: React.ReactElement<any>
>children : React.ReactElement<any>
>React : any
}
function Wrapper(props: Props) {
>Wrapper : (props: Props) => JSX.Element
>props : Props
return <div>{props.children}</div>
><div>{props.children}</div> : JSX.Element
>div : any
>props.children : React.ReactElement<any>
>props : Props
>children : React.ReactElement<any>
>div : any
}
const element = (
>element : JSX.Element
>( <Wrapper> {/* comment */} <div>Hello</div> </Wrapper>) : JSX.Element
<Wrapper>
><Wrapper> {/* comment */} <div>Hello</div> </Wrapper> : JSX.Element
>Wrapper : (props: Props) => JSX.Element
{/* comment */}
<div>Hello</div>
><div>Hello</div> : JSX.Element
>div : any
>div : any
</Wrapper>
>Wrapper : (props: Props) => JSX.Element
)

View file

@ -0,0 +1,30 @@
//// [jsxEmptyExpressionNotCountedAsChild.tsx]
/// <reference path="/.lib/react16.d.ts" />
import * as React from 'react'
interface Props {
children: React.ReactElement<any>
}
function Wrapper(props: Props) {
return <div>{props.children}</div>
}
const element = (
<Wrapper>
{/* comment */}
<div>Hello</div>
</Wrapper>
)
//// [jsxEmptyExpressionNotCountedAsChild.js]
"use strict";
exports.__esModule = true;
var jsx_dev_runtime_1 = require("react/jsx-dev-runtime");
var _jsxFileName = "tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx";
/// <reference path="react16.d.ts" />
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));

View file

@ -0,0 +1,42 @@
=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx ===
/// <reference path="react16.d.ts" />
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<any>
>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 <div>{props.children}</div>
>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>
>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1))
{/* comment */}
<div>Hello</div>
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
</Wrapper>
>Wrapper : Symbol(Wrapper, Decl(jsxEmptyExpressionNotCountedAsChild.tsx, 5, 1))
)

View file

@ -0,0 +1,42 @@
=== tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx ===
/// <reference path="react16.d.ts" />
import * as React from 'react'
>React : typeof React
interface Props {
children: React.ReactElement<any>
>children : React.ReactElement<any>
>React : any
}
function Wrapper(props: Props) {
>Wrapper : (props: Props) => JSX.Element
>props : Props
return <div>{props.children}</div>
><div>{props.children}</div> : JSX.Element
>div : any
>props.children : React.ReactElement<any>
>props : Props
>children : React.ReactElement<any>
>div : any
}
const element = (
>element : JSX.Element
>( <Wrapper> {/* comment */} <div>Hello</div> </Wrapper>) : JSX.Element
<Wrapper>
><Wrapper> {/* comment */} <div>Hello</div> </Wrapper> : JSX.Element
>Wrapper : (props: Props) => JSX.Element
{/* comment */}
<div>Hello</div>
><div>Hello</div> : JSX.Element
>div : any
>div : any
</Wrapper>
>Wrapper : (props: Props) => JSX.Element
)

View file

@ -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");
/// <reference path="react16.d.ts" />
var a = jsx_runtime_js_1.jsx("div", { children: "text" }, void 0);
var a = jsx_runtime_1.jsx("div", { children: "text" }, void 0);

View file

@ -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";
/// <reference path="react16.d.ts" />
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);

View file

@ -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");
/// <reference path="react16.d.ts" />
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);

View file

@ -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";
/// <reference path="react16.d.ts" />
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);

View file

@ -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");
/// <reference path="react16.d.ts" />
/* @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");
/// <reference path="react16.d.ts" />
/* @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);

View file

@ -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";
/// <reference path="react16.d.ts" />
/* @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";
/// <reference path="react16.d.ts" />
/* @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);

View file

@ -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");
/// <reference path="react16.d.ts" />
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");

View file

@ -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";
/// <reference path="react16.d.ts" />
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");

View file

@ -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");
/// <reference path="react16.d.ts" />
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");

View file

@ -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";
/// <reference path="react16.d.ts" />
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");

View file

@ -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");
/// <reference path="react16.d.ts" />
/* @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");
/// <reference path="react16.d.ts" />
/* @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");

View file

@ -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";
/// <reference path="react16.d.ts" />
/* @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";
/// <reference path="react16.d.ts" />
/* @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");

View file

@ -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));

View file

@ -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));

View file

@ -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");
/// <reference path="react16.d.ts" />
var a = jsx_runtime_js_1.jsx("div", {}, void 0);
var a = jsx_runtime_1.jsx("div", {}, void 0);

View file

@ -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";
/// <reference path="react16.d.ts" />
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);

View file

@ -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");
/// <reference path="react16.d.ts" />
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);

View file

@ -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";
/// <reference path="react16.d.ts" />
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);

View file

@ -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<T>(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) { });
}

View file

@ -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<T>(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))
}

View file

@ -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 : { <S extends { isSuccess: true; } | { isSuccess: false; }>(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 : <U>(callbackfn: (value: Item, index: number, array: Item[]) => U, thisArg?: any) => U[]
>a : Item[]
>map : <U>(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 : { <S extends { isSuccess: true; } | { isSuccess: false; }>(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<T>(a: Item[]) {
>f2 : <T>(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 : { <S extends { isSuccess: true; } | { isSuccess: false; }>(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 : <U>(callbackfn: (value: Item, index: number, array: Item[]) => U, thisArg?: any) => U[]
>a : Item[]
>map : <U>(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 : { <S extends { isSuccess: true; } | { isSuccess: false; }>(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; }
}

View file

@ -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
const exampleGood: B = "1 2"; // ok
// Repro from #41161
var aa: '0';
var aa: '0' & `${number}`;

View file

@ -159,7 +159,13 @@ const shouldWork2: AGen<string> = null as any as AGen<number>;
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;

View file

@ -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))

View file

@ -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"

View file

@ -0,0 +1,19 @@
// @jsx: react,react-jsx,react-jsxdev
// @strict: true
/// <reference path="/.lib/react16.d.ts" />
import * as React from 'react'
interface Props {
children: React.ReactElement<any>
}
function Wrapper(props: Props) {
return <div>{props.children}</div>
}
const element = (
<Wrapper>
{/* comment */}
<div>Hello</div>
</Wrapper>
)

View file

@ -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<T>(a: Item[]) {
a.map(item => ({ ...item })).filter(value => {});
}

View file

@ -159,4 +159,9 @@ const shouldWork2: AGen<string> = null as any as AGen<number>;
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}`;