Merge branch 'master' into add-codefix-cannot-find-name-in-for-loop

This commit is contained in:
rflorian
2019-05-31 15:06:39 +02:00
committed by GitHub
441 changed files with 37190 additions and 1615 deletions
+4 -2
View File
@@ -1,11 +1,13 @@
# TypeScript
[![Join the chat at https://gitter.im/Microsoft/TypeScript](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/microsoft/TypeScript.svg?branch=master)](https://travis-ci.org/Microsoft/TypeScript)
[![VSTS Build Status](https://dev.azure.com/typescript/TypeScript/_apis/build/status/Typescript/node10)](https://dev.azure.com/typescript/TypeScript/_build/latest?definitionId=4&view=logs)
[![npm version](https://badge.fury.io/js/typescript.svg)](https://www.npmjs.com/package/typescript)
[![Downloads](https://img.shields.io/npm/dm/typescript.svg)](https://www.npmjs.com/package/typescript)
# TypeScript
[![Join the chat at https://gitter.im/Microsoft/TypeScript](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[TypeScript](https://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](https://www.typescriptlang.org/play/), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescript).
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "typescript",
"author": "Microsoft Corp.",
"homepage": "https://www.typescriptlang.org/",
"version": "3.5.0",
"version": "3.6.0",
"license": "Apache-2.0",
"description": "TypeScript is a language for application scale JavaScript development",
"keywords": [
+4 -4
View File
@@ -9,7 +9,7 @@ function padNum(number: number) {
}
const userName = process.env.GH_USERNAME;
const reviewers = process.env.requesting_user ? [process.env.requesting_user] : ["weswigham", "sandersn", "RyanCavanaugh"];
const reviewers = process.env.REQUESTING_USER ? [process.env.REQUESTING_USER] : ["weswigham", "sandersn", "RyanCavanaugh"];
const now = new Date();
const branchName = `user-update-${process.env.TARGET_FORK}-${now.getFullYear()}${padNum(now.getMonth())}${padNum(now.getDay())}${process.env.TARGET_BRANCH ? "-" + process.env.TARGET_BRANCH : ""}`;
const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`;
@@ -36,14 +36,14 @@ gh.pulls.create({
head: `${userName}:${branchName}`,
base: process.env.TARGET_BRANCH || "master",
body:
`${process.env.source_issue ? `This test run was triggerd by a request on https://github.com/Microsoft/TypeScript/pull/${process.env.source_issue} `+"\n" : ""}Please review the diff and merge if no changes are unexpected.
`${process.env.SOURCE_ISSUE ? `This test run was triggerd by a request on https://github.com/Microsoft/TypeScript/pull/${process.env.SOURCE_ISSUE} `+"\n" : ""}Please review the diff and merge if no changes are unexpected.
You can view the build log [here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary).
cc ${reviewers.map(r => "@" + r).join(" ")}`,
}).then(async r => {
const num = r.data.number;
console.log(`Pull request ${num} created.`);
if (!process.env.source_issue) {
if (!process.env.SOURCE_ISSUE) {
await gh.pulls.createReviewRequest({
owner: process.env.TARGET_FORK,
repo: "TypeScript",
@@ -53,7 +53,7 @@ cc ${reviewers.map(r => "@" + r).join(" ")}`,
}
else {
await gh.issues.createComment({
number: +process.env.source_issue,
number: +process.env.SOURCE_ISSUE,
owner: "Microsoft",
repo: "TypeScript",
body: `The user suite test run you requested has finished and _failed_. I've opened a [PR with the baseline diff from master](${r.data.html_url}).`
+23 -17
View File
@@ -2515,7 +2515,7 @@ namespace ts {
break;
default:
Debug.fail(Debug.showSyntaxKind(thisContainer));
Debug.failBadSyntaxKind(thisContainer);
}
}
@@ -2581,7 +2581,7 @@ namespace ts {
// Fix up parent pointers since we're going to use these nodes before we bind into them
node.left.parent = node;
node.right.parent = node;
if (isIdentifier(lhs.expression) && container === file && isNameOfExportsOrModuleExportsAliasDeclaration(file, lhs.expression)) {
if (isIdentifier(lhs.expression) && container === file && isExportsOrModuleExportsOrAlias(file, lhs.expression)) {
// This can be an alias for the 'exports' or 'module.exports' names, e.g.
// var util = module.exports;
// util.property = function ...
@@ -2975,21 +2975,27 @@ namespace ts {
}
export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean {
return isExportsIdentifier(node) ||
isModuleExportsPropertyAccessExpression(node) ||
isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile, node);
}
function isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile: SourceFile, node: Identifier): boolean {
const symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText);
return !!symbol && !!symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
!!symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, symbol.valueDeclaration.initializer);
}
function isExportsOrModuleExportsOrAliasOrAssignment(sourceFile: SourceFile, node: Expression): boolean {
return isExportsOrModuleExportsOrAlias(sourceFile, node) ||
(isAssignmentExpression(node, /*excludeCompoundAssignment*/ true) && (
isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.left) || isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.right)));
let i = 0;
const q = [node];
while (q.length && i < 100) {
i++;
node = q.shift()!;
if (isExportsIdentifier(node) || isModuleExportsPropertyAccessExpression(node)) {
return true;
}
else if (isIdentifier(node)) {
const symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText);
if (!!symbol && !!symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) && !!symbol.valueDeclaration.initializer) {
const init = symbol.valueDeclaration.initializer;
q.push(init);
if (isAssignmentExpression(init, /*excludeCompoundAssignment*/ true)) {
q.push(init.left);
q.push(init.right);
}
}
}
}
return false;
}
function lookupSymbolForNameWorker(container: Node, name: __String): Symbol | undefined {
+404 -241
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -2361,7 +2361,7 @@ namespace ts {
if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, Extension.Json)) {
extendedConfigPath = `${extendedConfigPath}.json`;
if (!host.fileExists(extendedConfigPath)) {
errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig));
errors.push(createDiagnostic(Diagnostics.File_0_not_found, extendedConfig));
return undefined;
}
}
@@ -2372,7 +2372,7 @@ namespace ts {
if (resolved.resolvedModule) {
return resolved.resolvedModule.resolvedFileName;
}
errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig));
errors.push(createDiagnostic(Diagnostics.File_0_not_found, extendedConfig));
return undefined;
}
+1 -84
View File
@@ -1,7 +1,7 @@
namespace ts {
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
// If changing the text in this section, be sure to test `configureNightly` too.
export const versionMajorMinor = "3.5";
export const versionMajorMinor = "3.6";
/** The version of the TypeScript compiler release */
export const version = `${versionMajorMinor}.0-dev`;
}
@@ -1686,89 +1686,6 @@ namespace ts {
export type AnyFunction = (...args: never[]) => void;
export type AnyConstructor = new (...args: unknown[]) => unknown;
export namespace Debug {
export let currentAssertionLevel = AssertionLevel.None;
export let isDebugging = false;
export function shouldAssert(level: AssertionLevel): boolean {
return currentAssertionLevel >= level;
}
export function assert(expression: boolean, message?: string, verboseDebugInfo?: string | (() => string), stackCrawlMark?: AnyFunction): void {
if (!expression) {
if (verboseDebugInfo) {
message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo());
}
fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert);
}
}
export function assertEqual<T>(a: T, b: T, msg?: string, msg2?: string): void {
if (a !== b) {
const message = msg ? msg2 ? `${msg} ${msg2}` : msg : "";
fail(`Expected ${a} === ${b}. ${message}`);
}
}
export function assertLessThan(a: number, b: number, msg?: string): void {
if (a >= b) {
fail(`Expected ${a} < ${b}. ${msg || ""}`);
}
}
export function assertLessThanOrEqual(a: number, b: number): void {
if (a > b) {
fail(`Expected ${a} <= ${b}`);
}
}
export function assertGreaterThanOrEqual(a: number, b: number): void {
if (a < b) {
fail(`Expected ${a} >= ${b}`);
}
}
export function fail(message?: string, stackCrawlMark?: AnyFunction): never {
debugger;
const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure.");
if ((<any>Error).captureStackTrace) {
(<any>Error).captureStackTrace(e, stackCrawlMark || fail);
}
throw e;
}
export function assertDefined<T>(value: T | null | undefined, message?: string): T {
if (value === undefined || value === null) return fail(message);
return value;
}
export function assertEachDefined<T, A extends ReadonlyArray<T>>(value: A, message?: string): A {
for (const v of value) {
assertDefined(v, message);
}
return value;
}
export function assertNever(member: never, message = "Illegal value:", stackCrawlMark?: AnyFunction): never {
const detail = typeof member === "object" && "kind" in member && "pos" in member ? "SyntaxKind: " + showSyntaxKind(member as Node) : JSON.stringify(member);
return fail(`${message} ${detail}`, stackCrawlMark || assertNever);
}
export function getFunctionName(func: AnyFunction) {
if (typeof func !== "function") {
return "";
}
else if (func.hasOwnProperty("name")) {
return (<any>func).name;
}
else {
const text = Function.prototype.toString.call(func);
const match = /^function\s+([\w\$]+)\s*\(/.exec(text);
return match ? match[1] : "";
}
}
}
export function equateValues<T>(a: T, b: T) {
return a === b;
}
+261
View File
@@ -0,0 +1,261 @@
/* @internal */
namespace ts {
export namespace Debug {
export let currentAssertionLevel = AssertionLevel.None;
export let isDebugging = false;
export function shouldAssert(level: AssertionLevel): boolean {
return currentAssertionLevel >= level;
}
export function assert(expression: boolean, message?: string, verboseDebugInfo?: string | (() => string), stackCrawlMark?: AnyFunction): void {
if (!expression) {
if (verboseDebugInfo) {
message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo());
}
fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert);
}
}
export function assertEqual<T>(a: T, b: T, msg?: string, msg2?: string): void {
if (a !== b) {
const message = msg ? msg2 ? `${msg} ${msg2}` : msg : "";
fail(`Expected ${a} === ${b}. ${message}`);
}
}
export function assertLessThan(a: number, b: number, msg?: string): void {
if (a >= b) {
fail(`Expected ${a} < ${b}. ${msg || ""}`);
}
}
export function assertLessThanOrEqual(a: number, b: number): void {
if (a > b) {
fail(`Expected ${a} <= ${b}`);
}
}
export function assertGreaterThanOrEqual(a: number, b: number): void {
if (a < b) {
fail(`Expected ${a} >= ${b}`);
}
}
export function fail(message?: string, stackCrawlMark?: AnyFunction): never {
debugger;
const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure.");
if ((<any>Error).captureStackTrace) {
(<any>Error).captureStackTrace(e, stackCrawlMark || fail);
}
throw e;
}
export function assertDefined<T>(value: T | null | undefined, message?: string): T {
if (value === undefined || value === null) return fail(message);
return value;
}
export function assertEachDefined<T, A extends ReadonlyArray<T>>(value: A, message?: string): A {
for (const v of value) {
assertDefined(v, message);
}
return value;
}
export function assertNever(member: never, message = "Illegal value:", stackCrawlMark?: AnyFunction): never {
const detail = typeof member === "object" && "kind" in member && "pos" in member && formatSyntaxKind ? "SyntaxKind: " + formatSyntaxKind((member as Node).kind) : JSON.stringify(member);
return fail(`${message} ${detail}`, stackCrawlMark || assertNever);
}
export function getFunctionName(func: AnyFunction) {
if (typeof func !== "function") {
return "";
}
else if (func.hasOwnProperty("name")) {
return (<any>func).name;
}
else {
const text = Function.prototype.toString.call(func);
const match = /^function\s+([\w\$]+)\s*\(/.exec(text);
return match ? match[1] : "";
}
}
export function formatSymbol(symbol: Symbol): string {
return `{ name: ${unescapeLeadingUnderscores(symbol.escapedName)}; flags: ${formatSymbolFlags(symbol.flags)}; declarations: ${map(symbol.declarations, node => formatSyntaxKind(node.kind))} }`;
}
/**
* Formats an enum value as a string for debugging and debug assertions.
*/
export function formatEnum(value = 0, enumObject: any, isFlags?: boolean) {
const members = getEnumMembers(enumObject);
if (value === 0) {
return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0";
}
if (isFlags) {
let result = "";
let remainingFlags = value;
for (let i = members.length - 1; i >= 0 && remainingFlags !== 0; i--) {
const [enumValue, enumName] = members[i];
if (enumValue !== 0 && (remainingFlags & enumValue) === enumValue) {
remainingFlags &= ~enumValue;
result = `${enumName}${result ? "|" : ""}${result}`;
}
}
if (remainingFlags === 0) {
return result;
}
}
else {
for (const [enumValue, enumName] of members) {
if (enumValue === value) {
return enumName;
}
}
}
return value.toString();
}
function getEnumMembers(enumObject: any) {
const result: [number, string][] = [];
for (const name in enumObject) {
const value = enumObject[name];
if (typeof value === "number") {
result.push([value, name]);
}
}
return stableSort<[number, string]>(result, (x, y) => compareValues(x[0], y[0]));
}
export function formatSyntaxKind(kind: SyntaxKind | undefined): string {
return formatEnum(kind, (<any>ts).SyntaxKind, /*isFlags*/ false);
}
export function formatNodeFlags(flags: NodeFlags | undefined): string {
return formatEnum(flags, (<any>ts).NodeFlags, /*isFlags*/ true);
}
export function formatModifierFlags(flags: ModifierFlags | undefined): string {
return formatEnum(flags, (<any>ts).ModifierFlags, /*isFlags*/ true);
}
export function formatTransformFlags(flags: TransformFlags | undefined): string {
return formatEnum(flags, (<any>ts).TransformFlags, /*isFlags*/ true);
}
export function formatEmitFlags(flags: EmitFlags | undefined): string {
return formatEnum(flags, (<any>ts).EmitFlags, /*isFlags*/ true);
}
export function formatSymbolFlags(flags: SymbolFlags | undefined): string {
return formatEnum(flags, (<any>ts).SymbolFlags, /*isFlags*/ true);
}
export function formatTypeFlags(flags: TypeFlags | undefined): string {
return formatEnum(flags, (<any>ts).TypeFlags, /*isFlags*/ true);
}
export function formatObjectFlags(flags: ObjectFlags | undefined): string {
return formatEnum(flags, (<any>ts).ObjectFlags, /*isFlags*/ true);
}
export function failBadSyntaxKind(node: Node, message?: string): never {
return fail(
`${message || "Unexpected node."}\r\nNode ${formatSyntaxKind(node.kind)} was unexpected.`,
failBadSyntaxKind);
}
export const assertEachNode = shouldAssert(AssertionLevel.Normal)
? (nodes: Node[], test: (node: Node) => boolean, message?: string): void => assert(
test === undefined || every(nodes, test),
message || "Unexpected node.",
() => `Node array did not pass test '${getFunctionName(test)}'.`,
assertEachNode)
: noop;
export const assertNode = shouldAssert(AssertionLevel.Normal)
? (node: Node | undefined, test: ((node: Node | undefined) => boolean) | undefined, message?: string): void => assert(
test === undefined || test(node),
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node!.kind)} did not pass test '${getFunctionName(test!)}'.`,
assertNode)
: noop;
export const assertOptionalNode = shouldAssert(AssertionLevel.Normal)
? (node: Node, test: (node: Node) => boolean, message?: string): void => assert(
test === undefined || node === undefined || test(node),
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`,
assertOptionalNode)
: noop;
export const assertOptionalToken = shouldAssert(AssertionLevel.Normal)
? (node: Node, kind: SyntaxKind, message?: string): void => assert(
kind === undefined || node === undefined || node.kind === kind,
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} was not a '${formatSyntaxKind(kind)}' token.`,
assertOptionalToken)
: noop;
export const assertMissingNode = shouldAssert(AssertionLevel.Normal)
? (node: Node, message?: string): void => assert(
node === undefined,
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} was unexpected'.`,
assertMissingNode)
: noop;
let isDebugInfoEnabled = false;
/**
* Injects debug information into frequently used types.
*/
export function enableDebugInfo() {
if (isDebugInfoEnabled) return;
// Add additional properties in debug mode to assist with debugging.
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
__debugFlags: { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
});
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
__debugFlags: { get(this: Type) { return formatTypeFlags(this.flags); } },
__debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
__debugTypeToString: { value(this: Type) { return this.checker.typeToString(this); } },
});
const nodeConstructors = [
objectAllocator.getNodeConstructor(),
objectAllocator.getIdentifierConstructor(),
objectAllocator.getTokenConstructor(),
objectAllocator.getSourceFileConstructor()
];
for (const ctor of nodeConstructors) {
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
Object.defineProperties(ctor.prototype, {
__debugKind: { get(this: Node) { return formatSyntaxKind(this.kind); } },
__debugNodeFlags: { get(this: Node) { return formatNodeFlags(this.flags); } },
__debugModifierFlags: { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } },
__debugTransformFlags: { get(this: Node) { return formatTransformFlags(this.transformFlags); } },
__debugIsParseTreeNode: { get(this: Node) { return isParseTreeNode(this); } },
__debugEmitFlags: { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } },
__debugGetText: {
value(this: Node, includeTrivia?: boolean) {
if (nodeIsSynthesized(this)) return "";
const parseNode = getParseTreeNode(this);
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
}
}
});
}
}
isDebugInfoEnabled = true;
}
}
}
+22 -5
View File
@@ -655,7 +655,7 @@
"category": "Error",
"code": 1207
},
"Cannot compile namespaces when the '--isolatedModules' flag is provided.": {
"All files must be modules when the '--isolatedModules' flag is provided.": {
"category": "Error",
"code": 1208
},
@@ -3811,10 +3811,6 @@
"category": "Error",
"code": 6189
},
"Found 'package.json' at '{0}'. Package ID is '{1}'.": {
"category": "Message",
"code": 6190
},
"Whether to keep outdated console output in watch mode instead of clearing the screen.": {
"category": "Message",
"code": 6191
@@ -3923,6 +3919,18 @@
"category": "Message",
"code": 6217
},
"======== Module name '{0}' was successfully resolved to '{1}' with Package ID '{2}'. ========": {
"category": "Message",
"code": 6218
},
"======== Type reference directive '{0}' was successfully resolved to '{1}' with Package ID '{2}', primary: {3}. ========": {
"category": "Message",
"code": 6219
},
"'package.json' had a falsy '{0}' field.": {
"category": "Message",
"code": 6220
},
"Projects to reference": {
"category": "Message",
@@ -4284,6 +4292,14 @@
"category": "Error",
"code": 7052
},
"Element implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'.": {
"category": "Error",
"code": 7053
},
"No index signature with a parameter of type '{0}' was found on type '{1}'.": {
"category": "Error",
"code": 7054
},
"You cannot rename this element.": {
"category": "Error",
"code": 8000
@@ -4982,6 +4998,7 @@
"category": "Message",
"code": 95081
},
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
"category": "Error",
"code": 18004
+2
View File
@@ -4527,6 +4527,8 @@ namespace ts {
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return generateNameForMethodOrAccessor(<MethodDeclaration | AccessorDeclaration>node);
case SyntaxKind.ComputedPropertyName:
return makeTempVariableName(TempFlags.Auto, /*reserveInNestedScopes*/ true);
default:
return makeTempVariableName(TempFlags.Auto);
}
+74 -86
View File
@@ -16,12 +16,23 @@ namespace ts {
push(value: T): void;
}
function withPackageId(packageId: PackageId | undefined, r: PathAndExtension | undefined): Resolved | undefined {
function withPackageId(packageInfo: PackageJsonInfo | undefined, r: PathAndExtension | undefined): Resolved | undefined {
let packageId: PackageId | undefined;
if (r && packageInfo) {
const packageJsonContent = packageInfo.packageJsonContent as PackageJson;
if (typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string") {
packageId = {
name: packageJsonContent.name,
subModuleName: r.path.slice(packageInfo.packageDirectory.length + directorySeparator.length),
version: packageJsonContent.version
};
}
}
return r && { path: r.path, extension: r.ext, packageId };
}
function noPackageId(r: PathAndExtension | undefined): Resolved | undefined {
return withPackageId(/*packageId*/ undefined, r);
return withPackageId(/*packageInfo*/ undefined, r);
}
function removeIgnoredPackageId(r: Resolved | undefined): PathAndExtension | undefined {
@@ -130,7 +141,15 @@ namespace ts {
function readPackageJsonPathField<K extends "typings" | "types" | "main" | "tsconfig">(jsonContent: PackageJson, fieldName: K, baseDirectory: string, state: ModuleResolutionState): PackageJson[K] | undefined {
const fileName = readPackageJsonField(jsonContent, fieldName, "string", state);
if (fileName === undefined) return;
if (fileName === undefined) {
return;
}
if (!fileName) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_had_a_falsy_0_field, fieldName);
}
return;
}
const path = normalizePath(combinePaths(baseDirectory, fileName));
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
@@ -307,7 +326,12 @@ namespace ts {
const { fileName, packageId } = resolved;
const resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
if (traceEnabled) {
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
if (packageId) {
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, resolvedFileName, packageIdToString(packageId), primary);
}
else {
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
}
}
resolvedTypeReferenceDirective = { primary, resolvedFileName, packageId, isExternalLibraryImport: pathContainsNodeModules(fileName) };
}
@@ -663,7 +687,12 @@ namespace ts {
if (traceEnabled) {
if (result.resolvedModule) {
trace(host, Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
if (result.resolvedModule.packageId) {
trace(host, Diagnostics.Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2, moduleName, result.resolvedModule.resolvedFileName, packageIdToString(result.resolvedModule.packageId));
}
else {
trace(host, Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
}
}
else {
trace(host, Diagnostics.Module_name_0_was_not_resolved, moduleName);
@@ -968,10 +997,9 @@ namespace ts {
}
const resolvedFromFile = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state);
if (resolvedFromFile) {
const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined;
const packageInfo = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, /*onlyRecordFailures*/ false, state);
const packageId = packageInfo && packageInfo.packageId;
return withPackageId(packageId, resolvedFromFile);
const packageDirectory = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined;
const packageInfo = packageDirectory ? getPackageJsonInfo(packageDirectory, /*onlyRecordFailures*/ false, state) : undefined;
return withPackageId(packageInfo, resolvedFromFile);
}
}
if (!onlyRecordFailures) {
@@ -998,13 +1026,12 @@ namespace ts {
* (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.)
*
* packageDirectory is the directory of the package itself.
* subModuleName is the path within the package.
* For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "index.d.ts" }. (Part before "/node_modules/" is ignored.)
* For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar/index.d.ts" }.
* For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar/index.d.ts" }.
* For `/node_modules/foo/bar/index.d.ts` this is { packageDirectory: "foo", subModuleName": "bar/index.d.ts" }.
* For `blah/node_modules/foo/index.d.ts` this is packageDirectory: "foo"
* For `/node_modules/foo/bar.d.ts` this is packageDirectory: "foo"
* For `/node_modules/@types/foo/bar/index.d.ts` this is packageDirectory: "@types/foo"
* For `/node_modules/foo/bar/index.d.ts` this is packageDirectory: "foo"
*/
function parseNodeModuleFromPath(resolved: PathAndExtension): { packageDirectory: string, subModuleName: string } | undefined {
function parseNodeModuleFromPath(resolved: PathAndExtension): string | undefined {
const path = normalizePath(resolved.path);
const idx = path.lastIndexOf(nodeModulesPathPart);
if (idx === -1) {
@@ -1016,9 +1043,7 @@ namespace ts {
if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) {
indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName);
}
const packageDirectory = path.slice(0, indexAfterPackageName);
const subModuleName = removeExtension(path.slice(indexAfterPackageName + 1), resolved.ext) + Extension.Dts;
return { packageDirectory, subModuleName };
return path.slice(0, indexAfterPackageName);
}
function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number {
@@ -1026,19 +1051,6 @@ namespace ts {
return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex;
}
function addExtensionAndIndex(path: string): string {
if (path === "") {
return "index.d.ts";
}
if (endsWith(path, ".d.ts")) {
return path;
}
if (path === "index" || endsWith(path, "/index")) {
return path + ".d.ts";
}
return path + "/index.d.ts";
}
function loadModuleFromFileNoPackageId(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
return noPackageId(loadModuleFromFile(extensions, candidate, onlyRecordFailures, state));
}
@@ -1119,61 +1131,29 @@ namespace ts {
}
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) {
const packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, "", onlyRecordFailures, state) : undefined;
const packageId = packageInfo && packageInfo.packageId;
const packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, onlyRecordFailures, state) : undefined;
const packageJsonContent = packageInfo && packageInfo.packageJsonContent;
const versionPaths = packageInfo && packageInfo.versionPaths;
return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
return withPackageId(packageInfo, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
}
interface PackageJsonInfo {
packageJsonContent: PackageJsonPathFields | undefined;
packageId: PackageId | undefined;
packageDirectory: string;
packageJsonContent: PackageJsonPathFields;
versionPaths: VersionPaths | undefined;
}
function getPackageJsonInfo(packageDirectory: string, subModuleName: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined {
function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined {
const { host, traceEnabled } = state;
const directoryExists = !onlyRecordFailures && directoryProbablyExists(packageDirectory, host);
const packageJsonPath = combinePaths(packageDirectory, "package.json");
if (directoryExists && host.fileExists(packageJsonPath)) {
const packageJsonContent = readJson(packageJsonPath, host) as PackageJson;
if (subModuleName === "") { // looking up the root - need to handle types/typings/main redirects for subModuleName
const path = readPackageJsonTypesFields(packageJsonContent, packageDirectory, state);
if (typeof path === "string") {
subModuleName = addExtensionAndIndex(path.substring(packageDirectory.length + 1));
}
else {
const jsPath = readPackageJsonMainField(packageJsonContent, packageDirectory, state);
if (typeof jsPath === "string" && jsPath.length > packageDirectory.length) {
const potentialSubModule = jsPath.substring(packageDirectory.length + 1);
subModuleName = (forEach(supportedJSExtensions, extension =>
tryRemoveExtension(potentialSubModule, extension)) || potentialSubModule) + Extension.Dts;
}
else {
subModuleName = "index.d.ts";
}
}
}
if (!endsWith(subModuleName, Extension.Dts)) {
subModuleName = addExtensionAndIndex(subModuleName);
}
const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
const packageId: PackageId | undefined = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string"
? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version }
: undefined;
if (traceEnabled) {
if (packageId) {
trace(host, Diagnostics.Found_package_json_at_0_Package_ID_is_1, packageJsonPath, packageIdToString(packageId));
}
else {
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
}
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
}
return { packageJsonContent, packageId, versionPaths };
const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
return { packageDirectory, packageJsonContent, versionPaths };
}
else {
if (directoryExists && traceEnabled) {
@@ -1328,27 +1308,36 @@ namespace ts {
const candidate = normalizePath(combinePaths(nodeModulesDirectory, moduleName));
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
let packageJsonContent: PackageJsonPathFields | undefined;
let packageId: PackageId | undefined;
let versionPaths: VersionPaths | undefined;
const packageInfo = getPackageJsonInfo(candidate, "", !nodeModulesDirectoryExists, state);
let packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
if (packageInfo) {
({ packageJsonContent, packageId, versionPaths } = packageInfo);
const fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
if (fromFile) {
return noPackageId(fromFile);
}
const fromDirectory = loadNodeModuleFromDirectoryWorker(extensions, candidate, !nodeModulesDirectoryExists, state, packageJsonContent, versionPaths);
return withPackageId(packageId, fromDirectory);
const fromDirectory = loadNodeModuleFromDirectoryWorker(
extensions,
candidate,
!nodeModulesDirectoryExists,
state,
packageInfo.packageJsonContent,
packageInfo.versionPaths
);
return withPackageId(packageInfo, fromDirectory);
}
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => {
const pathAndExtension =
loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths);
return withPackageId(packageId, pathAndExtension);
loadNodeModuleFromDirectoryWorker(
extensions,
candidate,
onlyRecordFailures,
state,
packageInfo && packageInfo.packageJsonContent,
packageInfo && packageInfo.versionPaths
);
return withPackageId(packageInfo, pathAndExtension);
};
const { packageName, rest } = parsePackageName(moduleName);
@@ -1356,14 +1345,13 @@ namespace ts {
const packageDirectory = combinePaths(nodeModulesDirectory, packageName);
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
const packageInfo = getPackageJsonInfo(packageDirectory, rest, !nodeModulesDirectoryExists, state);
if (packageInfo) ({ packageId, versionPaths } = packageInfo);
if (versionPaths) {
packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
if (packageInfo && packageInfo.versionPaths) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, version, rest);
trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.versionPaths.version, version, rest);
}
const packageDirectoryExists = nodeModulesDirectoryExists && directoryProbablyExists(packageDirectory, state.host);
const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, versionPaths.paths, loader, !packageDirectoryExists, state);
const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, packageInfo.versionPaths.paths, loader, !packageDirectoryExists, state);
if (fromPaths) {
return fromPaths.value;
}
+3 -3
View File
@@ -175,9 +175,9 @@ namespace ts.moduleSpecifiers {
function discoverProbableSymlinks(files: ReadonlyArray<SourceFile>, getCanonicalFileName: GetCanonicalFileName, cwd: string): ReadonlyMap<string> {
const result = createMap<string>();
const symlinks = mapDefined(files, sf =>
sf.resolvedModules && firstDefinedIterator(sf.resolvedModules.values(), res =>
res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined));
const symlinks = flatten<readonly [string, string]>(mapDefined(files, sf =>
sf.resolvedModules && compact(arrayFrom(mapIterator(sf.resolvedModules.values(), res =>
res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] as const : undefined)))));
for (const [resolvedPath, originalPath] of symlinks) {
const [commonResolved, commonOriginal] = guessDirectorySymlink(resolvedPath, originalPath, cwd, getCanonicalFileName);
result.set(commonOriginal, commonResolved);
+6 -3
View File
@@ -2232,7 +2232,10 @@ namespace ts {
if (isRedirect) {
inputName = getProjectReferenceRedirect(fileName) || fileName;
}
if (getNormalizedAbsolutePath(checkedName, currentDirectory) !== getNormalizedAbsolutePath(inputName, currentDirectory)) {
// Check if it differs only in drive letters its ok to ignore that error:
const checkedAbsolutePath = getNormalizedAbsolutePathWithoutRoot(checkedName, currentDirectory);
const inputAbsolutePath = getNormalizedAbsolutePathWithoutRoot(inputName, currentDirectory);
if (checkedAbsolutePath !== inputAbsolutePath) {
reportFileNamesDifferOnlyInCasingError(inputName, checkedName, refFile, refPos, refEnd);
}
}
@@ -2855,10 +2858,10 @@ namespace ts {
createDiagnosticForOptionName(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
}
const firstNonExternalModuleSourceFile = find(files, f => !isExternalModule(f) && !f.isDeclarationFile && f.scriptKind !== ScriptKind.JSON);
const firstNonExternalModuleSourceFile = find(files, f => !isExternalModule(f) && !isSourceFileJS(f) && !f.isDeclarationFile && f.scriptKind !== ScriptKind.JSON);
if (firstNonExternalModuleSourceFile) {
const span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.All_files_must_be_modules_when_the_isolatedModules_flag_is_provided));
}
}
else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES2015 && options.module === ModuleKind.None) {
+24 -18
View File
@@ -145,7 +145,7 @@ namespace ts {
loopOutParameters: LoopOutParameter[];
}
type LoopConverter = (node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined) => Statement;
type LoopConverter = (node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts) => Statement;
// Facts we track as we traverse the tree
const enum HierarchyFacts {
@@ -163,11 +163,12 @@ namespace ts {
ExportedVariableStatement = 1 << 5, // Enclosed in an exported variable statement in the current scope
TopLevel = 1 << 6, // Enclosing block-scoped container is a top-level container
Block = 1 << 7, // Enclosing block-scoped container is a Block
IterationStatement = 1 << 8, // Enclosed in an IterationStatement
IterationStatement = 1 << 8, // Immediately enclosed in an IterationStatement
IterationStatementBlock = 1 << 9, // Enclosing Block is enclosed in an IterationStatement
ForStatement = 1 << 10, // Enclosing block-scoped container is a ForStatement
ForInOrForOfStatement = 1 << 11, // Enclosing block-scoped container is a ForInStatement or ForOfStatement
ConstructorWithCapturedSuper = 1 << 12, // Enclosed in a constructor that captures 'this' for use with 'super'
IterationContainer = 1 << 10, // Enclosed in an outer IterationStatement
ForStatement = 1 << 11, // Enclosing block-scoped container is a ForStatement
ForInOrForOfStatement = 1 << 12, // Enclosing block-scoped container is a ForInStatement or ForOfStatement
ConstructorWithCapturedSuper = 1 << 13, // Enclosed in a constructor that captures 'this' for use with 'super'
// NOTE: do not add more ancestor flags without also updating AncestorFactsMask below.
// NOTE: when adding a new ancestor flag, be sure to update the subtree flags below.
@@ -184,11 +185,11 @@ namespace ts {
// A source file is a top-level block scope.
SourceFileIncludes = TopLevel,
SourceFileExcludes = BlockScopeExcludes & ~TopLevel,
SourceFileExcludes = BlockScopeExcludes & ~TopLevel | IterationContainer,
// Functions, methods, and accessors are both new lexical scopes and new block scopes.
FunctionIncludes = Function | TopLevel,
FunctionExcludes = BlockScopeExcludes & ~TopLevel | ArrowFunction | AsyncFunctionBody | CapturesThis | NonStaticClassElement | ConstructorWithCapturedSuper,
FunctionExcludes = BlockScopeExcludes & ~TopLevel | ArrowFunction | AsyncFunctionBody | CapturesThis | NonStaticClassElement | ConstructorWithCapturedSuper | IterationContainer,
AsyncFunctionBodyIncludes = FunctionIncludes | AsyncFunctionBody,
AsyncFunctionBodyExcludes = FunctionExcludes & ~NonStaticClassElement,
@@ -205,16 +206,16 @@ namespace ts {
// 'do' and 'while' statements are not block scopes. We track that the subtree is contained
// within an IterationStatement to indicate whether the embedded statement is an
// IterationStatementBlock.
DoOrWhileStatementIncludes = IterationStatement,
DoOrWhileStatementIncludes = IterationStatement | IterationContainer,
DoOrWhileStatementExcludes = None,
// 'for' statements are new block scopes and have special handling for 'let' declarations.
ForStatementIncludes = IterationStatement | ForStatement,
ForStatementIncludes = IterationStatement | ForStatement | IterationContainer,
ForStatementExcludes = BlockScopeExcludes & ~ForStatement,
// 'for-in' and 'for-of' statements are new block scopes and have special handling for
// 'let' declarations.
ForInOrForOfStatementIncludes = IterationStatement | ForInOrForOfStatement,
ForInOrForOfStatementIncludes = IterationStatement | ForInOrForOfStatement | IterationContainer,
ForInOrForOfStatementExcludes = BlockScopeExcludes & ~ForInOrForOfStatement,
// Blocks (other than function bodies) are new block scopes.
@@ -228,8 +229,8 @@ namespace ts {
// Subtree facts
//
NewTarget = 1 << 13, // Contains a 'new.target' meta-property
CapturedLexicalThis = 1 << 14, // Contains a lexical `this` reference captured by an arrow function.
NewTarget = 1 << 14, // Contains a 'new.target' meta-property
CapturedLexicalThis = 1 << 15, // Contains a lexical `this` reference captured by an arrow function.
//
// Subtree masks
@@ -2227,7 +2228,7 @@ namespace ts {
function visitIterationStatementWithFacts(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter) {
const ancestorFacts = enterSubtree(excludeFacts, includeFacts);
const updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert);
const updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert);
exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None);
return updated;
}
@@ -2434,7 +2435,7 @@ namespace ts {
return restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
}
function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement {
function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[], ancestorFacts: HierarchyFacts): Statement {
const expression = visitNode(node.expression, visitor, isExpression);
const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined);
const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined);
@@ -2447,13 +2448,18 @@ namespace ts {
hoistVariableDeclaration(errorRecord);
hoistVariableDeclaration(returnMethod);
// if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration
const initializer = ancestorFacts & HierarchyFacts.IterationContainer
? inlineExpressions([createAssignment(errorRecord, createVoidZero()), values])
: values;
const forStatement = setEmitFlags(
setTextRange(
createFor(
/*initializer*/ setEmitFlags(
setTextRange(
createVariableDeclarationList([
setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, values), node.expression),
setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression),
createVariableDeclaration(result, /*type*/ undefined, next)
]),
node.expression
@@ -2665,7 +2671,7 @@ namespace ts {
}
}
function convertIterationStatementBodyIfNecessary(node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter): VisitResult<Statement> {
function convertIterationStatementBodyIfNecessary(node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, ancestorFacts: HierarchyFacts, convert?: LoopConverter): VisitResult<Statement> {
if (!shouldConvertIterationStatement(node)) {
let saveAllowedNonLabeledJumps: Jump | undefined;
if (convertedLoopState) {
@@ -2676,7 +2682,7 @@ namespace ts {
}
const result = convert
? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined)
? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined, ancestorFacts)
: restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel);
if (convertedLoopState) {
@@ -2708,7 +2714,7 @@ namespace ts {
let loop: Statement;
if (bodyFunction) {
if (convert) {
loop = convert(node, outermostLabeledStatement, bodyFunction.part);
loop = convert(node, outermostLabeledStatement, bodyFunction.part, ancestorFacts);
}
else {
const clone = convertIterationStatementCore(node, initializerFunction, createBlock(bodyFunction.part, /*multiLine*/ true));
+24
View File
@@ -77,6 +77,8 @@ namespace ts {
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
case SyntaxKind.BinaryExpression:
return visitBinaryExpression(node as BinaryExpression, noDestructuringValue);
case SyntaxKind.CatchClause:
return visitCatchClause(node as CatchClause);
case SyntaxKind.VariableDeclaration:
return visitVariableDeclaration(node as VariableDeclaration);
case SyntaxKind.ForOfStatement:
@@ -272,6 +274,28 @@ namespace ts {
return visitEachChild(node, visitor, context);
}
function visitCatchClause(node: CatchClause) {
if (node.variableDeclaration &&
isBindingPattern(node.variableDeclaration.name) &&
node.variableDeclaration.name.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
const name = getGeneratedNameForNode(node.variableDeclaration.name);
const updatedDecl = updateVariableDeclaration(node.variableDeclaration, node.variableDeclaration.name, /*type*/ undefined, name);
const visitedBindings = flattenDestructuringBinding(updatedDecl, visitor, context, FlattenLevel.ObjectRest);
let block = visitNode(node.block, visitor, isBlock);
if (some(visitedBindings)) {
block = updateBlock(block, [
createVariableStatement(/*modifiers*/ undefined, visitedBindings),
...block.statements,
]);
}
return updateCatchClause(
node,
updateVariableDeclaration(node.variableDeclaration, name, /*type*/ undefined, /*initializer*/ undefined),
block);
}
return visitEachChild(node, visitor, context);
}
/**
* Visits a VariableDeclaration node with a binding pattern.
*
+1
View File
@@ -8,6 +8,7 @@
"files": [
"core.ts",
"debug.ts",
"performance.ts",
"semver.ts",
+21 -10
View File
@@ -2546,6 +2546,8 @@ namespace ts {
Shared = 1 << 10, // Referenced as antecedent more than once
PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow
AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph
/** @internal */
Cached = 1 << 13, // Indicates that at least one cross-call cache entry exists for this node, even if not a loop participant
Label = BranchLabel | LoopLabel,
Condition = TrueCondition | FalseCondition
}
@@ -3152,6 +3154,7 @@ namespace ts {
*/
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
getTypeOfAssignmentPattern(pattern: AssignmentPattern): Type;
getTypeAtLocation(node: Node): Type;
getTypeFromTypeNode(node: TypeNode): Type;
@@ -3749,6 +3752,8 @@ namespace ts {
extendedContainers?: Symbol[]; // Containers (other than the parent) which this symbol is aliased in
extendedContainersByFile?: Map<Symbol[]>; // Containers (other than the parent) which this symbol is aliased in
variances?: VarianceFlags[]; // Alias symbol type argument variance cache
deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type
deferralParent?: Type; // Source union/intersection of a deferred type
}
/* @internal */
@@ -3775,6 +3780,7 @@ namespace ts {
ReverseMapped = 1 << 13, // Property of reverse-inferred homomorphic mapped type
OptionalParameter = 1 << 14, // Optional parameter
RestParameter = 1 << 15, // Rest parameter
DeferredType = 1 << 16, // Calculation of the type of this symbol is deferred due to processing costs, should be fetched with `getTypeOfSymbolWithDeferredType`
Synthetic = SyntheticProperty | SyntheticMethod,
Discriminant = HasNonUniformType | HasLiteralType,
Partial = ReadPartial | WritePartial
@@ -3964,6 +3970,8 @@ namespace ts {
StructuredOrInstantiable = StructuredType | Instantiable,
/* @internal */
ObjectFlagsType = Nullable | Never | Object | Union | Intersection,
/* @internal */
Simplifiable = IndexedAccess | Conditional,
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
@@ -4005,6 +4013,8 @@ namespace ts {
restrictiveInstantiation?: Type; // Instantiation with type parameters mapped to unconstrained form
/* @internal */
immediateBaseConstraint?: Type; // Immediate base constraint cache
/* @internal */
widened?: Type; // Cached widened form of the type
}
/* @internal */
@@ -4336,8 +4346,8 @@ namespace ts {
root: ConditionalRoot;
checkType: Type;
extendsType: Type;
trueType: Type;
falseType: Type;
resolvedTrueType: Type;
resolvedFalseType: Type;
/* @internal */
resolvedInferredTrueType?: Type; // The `trueType` instantiated with the `combinedMapper`, if present
/* @internal */
@@ -4422,15 +4432,16 @@ namespace ts {
export type TypeMapper = (t: TypeParameter) => Type;
export const enum InferencePriority {
NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type
HomomorphicMappedType = 1 << 1, // Reverse inference for homomorphic mapped type
MappedTypeConstraint = 1 << 2, // Reverse inference for mapped type
ReturnType = 1 << 3, // Inference made from return type of generic function
LiteralKeyof = 1 << 4, // Inference made from a string literal to a keyof T
NoConstraints = 1 << 5, // Don't infer from constraints of instantiable types
AlwaysStrict = 1 << 6, // Always use strict rules for contravariant inferences
NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type
HomomorphicMappedType = 1 << 1, // Reverse inference for homomorphic mapped type
PartialHomomorphicMappedType = 1 << 2, // Partial reverse inference for homomorphic mapped type
MappedTypeConstraint = 1 << 3, // Reverse inference for mapped type
ReturnType = 1 << 4, // Inference made from return type of generic function
LiteralKeyof = 1 << 5, // Inference made from a string literal to a keyof T
NoConstraints = 1 << 6, // Don't infer from constraints of instantiable types
AlwaysStrict = 1 << 7, // Always use strict rules for contravariant inferences
PriorityImpliesCombination = ReturnType | MappedTypeConstraint | LiteralKeyof, // These priorities imply that the resulting type should be a combination of all candidates
PriorityImpliesCombination = ReturnType | MappedTypeConstraint | LiteralKeyof, // These priorities imply that the resulting type should be a combination of all candidates
}
/* @internal */
+9 -96
View File
@@ -2073,7 +2073,7 @@ namespace ts {
}
export function importFromModuleSpecifier(node: StringLiteralLike): AnyValidImportOrReExport {
return tryGetImportFromModuleSpecifier(node) || Debug.fail(Debug.showSyntaxKind(node.parent));
return tryGetImportFromModuleSpecifier(node) || Debug.failBadSyntaxKind(node.parent);
}
export function tryGetImportFromModuleSpecifier(node: StringLiteralLike): AnyValidImportOrReExport | undefined {
@@ -4186,78 +4186,6 @@ namespace ts {
return getNewLine ? getNewLine() : sys ? sys.newLine : carriageReturnLineFeed;
}
/**
* Formats an enum value as a string for debugging and debug assertions.
*/
function formatEnum(value = 0, enumObject: any, isFlags?: boolean) {
const members = getEnumMembers(enumObject);
if (value === 0) {
return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0";
}
if (isFlags) {
let result = "";
let remainingFlags = value;
for (let i = members.length - 1; i >= 0 && remainingFlags !== 0; i--) {
const [enumValue, enumName] = members[i];
if (enumValue !== 0 && (remainingFlags & enumValue) === enumValue) {
remainingFlags &= ~enumValue;
result = `${enumName}${result ? ", " : ""}${result}`;
}
}
if (remainingFlags === 0) {
return result;
}
}
else {
for (const [enumValue, enumName] of members) {
if (enumValue === value) {
return enumName;
}
}
}
return value.toString();
}
function getEnumMembers(enumObject: any) {
const result: [number, string][] = [];
for (const name in enumObject) {
const value = enumObject[name];
if (typeof value === "number") {
result.push([value, name]);
}
}
return stableSort<[number, string]>(result, (x, y) => compareValues(x[0], y[0]));
}
export function formatSyntaxKind(kind: SyntaxKind | undefined): string {
return formatEnum(kind, (<any>ts).SyntaxKind, /*isFlags*/ false);
}
export function formatModifierFlags(flags: ModifierFlags | undefined): string {
return formatEnum(flags, (<any>ts).ModifierFlags, /*isFlags*/ true);
}
export function formatTransformFlags(flags: TransformFlags | undefined): string {
return formatEnum(flags, (<any>ts).TransformFlags, /*isFlags*/ true);
}
export function formatEmitFlags(flags: EmitFlags | undefined): string {
return formatEnum(flags, (<any>ts).EmitFlags, /*isFlags*/ true);
}
export function formatSymbolFlags(flags: SymbolFlags | undefined): string {
return formatEnum(flags, (<any>ts).SymbolFlags, /*isFlags*/ true);
}
export function formatTypeFlags(flags: TypeFlags | undefined): string {
return formatEnum(flags, (<any>ts).TypeFlags, /*isFlags*/ true);
}
export function formatObjectFlags(flags: ObjectFlags | undefined): string {
return formatEnum(flags, (<any>ts).ObjectFlags, /*isFlags*/ true);
}
/**
* Creates a new TextRange from the provided pos and end.
*
@@ -7646,6 +7574,14 @@ namespace ts {
return root + pathComponents.slice(1).join(directorySeparator);
}
export function getNormalizedAbsolutePathWithoutRoot(fileName: string, currentDirectory: string | undefined) {
return getPathWithoutRoot(getNormalizedPathComponents(fileName, currentDirectory));
}
function getPathWithoutRoot(pathComponents: ReadonlyArray<string>) {
if (pathComponents.length === 0) return "";
return pathComponents.slice(1).join(directorySeparator);
}
}
/* @internal */
@@ -8420,29 +8356,6 @@ namespace ts {
return pathext ? path.slice(0, path.length - pathext.length) + (startsWith(ext, ".") ? ext : "." + ext) : path;
}
export namespace Debug {
export function showSymbol(symbol: Symbol): string {
const symbolFlags = (ts as any).SymbolFlags;
return `{ flags: ${symbolFlags ? showFlags(symbol.flags, symbolFlags) : symbol.flags}; declarations: ${map(symbol.declarations, showSyntaxKind)} }`;
}
function showFlags(flags: number, flagsEnum: { [flag: number]: string }): string {
const out: string[] = [];
for (let pow = 0; pow <= 30; pow++) {
const n = 1 << pow;
if (flags & n) {
out.push(flagsEnum[n]);
}
}
return out.join("|");
}
export function showSyntaxKind(node: Node): string {
const syntaxKind = (ts as any).SyntaxKind;
return syntaxKind ? syntaxKind[node.kind] : node.kind.toString();
}
}
export function tryParsePattern(pattern: string): Pattern | undefined {
// This should be verified outside of here and a proper error thrown.
Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
-96
View File
@@ -1558,100 +1558,4 @@ namespace ts {
function aggregateTransformFlagsForChildNodes(transformFlags: TransformFlags, nodes: NodeArray<Node>): TransformFlags {
return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
}
export namespace Debug {
let isDebugInfoEnabled = false;
export function failBadSyntaxKind(node: Node, message?: string): never {
return fail(
`${message || "Unexpected node."}\r\nNode ${formatSyntaxKind(node.kind)} was unexpected.`,
failBadSyntaxKind);
}
export const assertEachNode = shouldAssert(AssertionLevel.Normal)
? (nodes: Node[], test: (node: Node) => boolean, message?: string): void => assert(
test === undefined || every(nodes, test),
message || "Unexpected node.",
() => `Node array did not pass test '${getFunctionName(test)}'.`,
assertEachNode)
: noop;
export const assertNode = shouldAssert(AssertionLevel.Normal)
? (node: Node | undefined, test: ((node: Node | undefined) => boolean) | undefined, message?: string): void => assert(
test === undefined || test(node),
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node!.kind)} did not pass test '${getFunctionName(test!)}'.`,
assertNode)
: noop;
export const assertOptionalNode = shouldAssert(AssertionLevel.Normal)
? (node: Node, test: (node: Node) => boolean, message?: string): void => assert(
test === undefined || node === undefined || test(node),
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`,
assertOptionalNode)
: noop;
export const assertOptionalToken = shouldAssert(AssertionLevel.Normal)
? (node: Node, kind: SyntaxKind, message?: string): void => assert(
kind === undefined || node === undefined || node.kind === kind,
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} was not a '${formatSyntaxKind(kind)}' token.`,
assertOptionalToken)
: noop;
export const assertMissingNode = shouldAssert(AssertionLevel.Normal)
? (node: Node, message?: string): void => assert(
node === undefined,
message || "Unexpected node.",
() => `Node ${formatSyntaxKind(node.kind)} was unexpected'.`,
assertMissingNode)
: noop;
/**
* Injects debug information into frequently used types.
*/
export function enableDebugInfo() {
if (isDebugInfoEnabled) return;
// Add additional properties in debug mode to assist with debugging.
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
__debugFlags: { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
});
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
__debugFlags: { get(this: Type) { return formatTypeFlags(this.flags); } },
__debugObjectFlags: { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
__debugTypeToString: { value(this: Type) { return this.checker.typeToString(this); } },
});
const nodeConstructors = [
objectAllocator.getNodeConstructor(),
objectAllocator.getIdentifierConstructor(),
objectAllocator.getTokenConstructor(),
objectAllocator.getSourceFileConstructor()
];
for (const ctor of nodeConstructors) {
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
Object.defineProperties(ctor.prototype, {
__debugKind: { get(this: Node) { return formatSyntaxKind(this.kind); } },
__debugModifierFlags: { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } },
__debugTransformFlags: { get(this: Node) { return formatTransformFlags(this.transformFlags); } },
__debugEmitFlags: { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } },
__debugGetText: {
value(this: Node, includeTrivia?: boolean) {
if (nodeIsSynthesized(this)) return "";
const parseNode = getParseTreeNode(this);
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
}
}
});
}
}
isDebugInfoEnabled = true;
}
}
}
+4
View File
@@ -424,6 +424,10 @@ namespace ts.server {
return renameInfo;
}
getSmartSelectionRange() {
return notImplemented();
}
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] {
if (!this.lastRenameEntry ||
this.lastRenameEntry.inputs.fileName !== fileName ||
+135 -39
View File
@@ -798,8 +798,8 @@ namespace FourSlash {
}
private verifyCompletionEntry(actual: ts.CompletionEntry, expected: FourSlashInterface.ExpectedCompletionEntry) {
const { insertText, replacementSpan, hasAction, isRecommended, kind, kindModifiers, text, documentation, tags, source, sourceDisplay } = typeof expected === "string"
? { insertText: undefined, replacementSpan: undefined, hasAction: undefined, isRecommended: undefined, kind: undefined, kindModifiers: undefined, text: undefined, documentation: undefined, tags: undefined, source: undefined, sourceDisplay: undefined }
const { insertText, replacementSpan, hasAction, isRecommended, kind, kindModifiers, text, documentation, tags, source, sourceDisplay, sortText } = typeof expected === "string"
? { insertText: undefined, replacementSpan: undefined, hasAction: undefined, isRecommended: undefined, kind: undefined, kindModifiers: undefined, text: undefined, documentation: undefined, tags: undefined, source: undefined, sourceDisplay: undefined, sortText: undefined }
: expected;
if (actual.insertText !== insertText) {
@@ -825,6 +825,7 @@ namespace FourSlash {
assert.equal(actual.hasAction, hasAction);
assert.equal(actual.isRecommended, isRecommended);
assert.equal(actual.source, source);
assert.equal(actual.sortText, sortText || ts.Completions.SortText.LocationPriority, this.messageAtLastKnownMarker(`Actual entry: ${JSON.stringify(actual)}`));
if (text !== undefined) {
const actualDetails = this.getCompletionEntryDetails(actual.name, actual.source)!;
@@ -1207,7 +1208,7 @@ Actual: ${stringify(fullActual)}`);
}
}
public verifySignatureHelpPresence(expectPresent: boolean, triggerReason: ts.SignatureHelpTriggerReason | undefined, markers: ReadonlyArray<string>) {
public verifySignatureHelpPresence(expectPresent: boolean, triggerReason: ts.SignatureHelpTriggerReason | undefined, markers: ReadonlyArray<string | Marker>) {
if (markers.length) {
for (const marker of markers) {
this.goToMarker(marker);
@@ -1417,12 +1418,7 @@ Actual: ${stringify(fullActual)}`);
}
public baselineCurrentFileBreakpointLocations() {
let baselineFile = this.testData.globalOptions[MetadataOptionNames.baselineFile];
if (!baselineFile) {
baselineFile = this.activeFile.fileName.replace(this.basePath + "/breakpointValidation", "bpSpan");
baselineFile = baselineFile.replace(ts.Extension.Ts, ".baseline");
}
const baselineFile = this.getBaselineFileName().replace("breakpointValidation", "bpSpan");
Harness.Baseline.runBaseline(baselineFile, this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos)!));
}
@@ -1497,8 +1493,7 @@ Actual: ${stringify(fullActual)}`);
}
public baselineQuickInfo() {
const baselineFile = this.testData.globalOptions[MetadataOptionNames.baselineFile] ||
ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline");
const baselineFile = this.getBaselineFileName();
Harness.Baseline.runBaseline(
baselineFile,
stringify(
@@ -1508,6 +1503,39 @@ Actual: ${stringify(fullActual)}`);
}))));
}
public baselineSmartSelection() {
const n = "\n";
const baselineFile = this.getBaselineFileName();
const markers = this.getMarkers();
const fileContent = this.activeFile.content;
const text = markers.map(marker => {
const baselineContent = [fileContent.slice(0, marker.position) + "/**/" + fileContent.slice(marker.position) + n];
let selectionRange: ts.SelectionRange | undefined = this.languageService.getSmartSelectionRange(this.activeFile.fileName, marker.position);
while (selectionRange) {
const { textSpan } = selectionRange;
let masked = Array.from(fileContent).map((char, index) => {
const charCode = char.charCodeAt(0);
if (index >= textSpan.start && index < ts.textSpanEnd(textSpan)) {
return char === " " ? "•" : ts.isLineBreak(charCode) ? `${n}` : char;
}
return ts.isLineBreak(charCode) ? char : " ";
}).join("");
masked = masked.replace(/^\s*$\r?\n?/gm, ""); // Remove blank lines
const isRealCharacter = (char: string) => char !== "•" && char !== "↲" && !ts.isWhiteSpaceLike(char.charCodeAt(0));
const leadingWidth = Array.from(masked).findIndex(isRealCharacter);
const trailingWidth = ts.findLastIndex(Array.from(masked), isRealCharacter);
masked = masked.slice(0, leadingWidth)
+ masked.slice(leadingWidth, trailingWidth).replace(/•/g, " ").replace(/↲/g, "")
+ masked.slice(trailingWidth);
baselineContent.push(masked);
selectionRange = selectionRange.parent;
}
return baselineContent.join(fileContent.includes("\n") ? n + n : n);
}).join(n.repeat(2) + "=".repeat(80) + n.repeat(2));
Harness.Baseline.runBaseline(baselineFile, text);
}
public printBreakpointLocation(pos: number) {
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(this.getBreakpointStatementLocation(pos)!, " "));
}
@@ -1562,6 +1590,11 @@ Actual: ${stringify(fullActual)}`);
Harness.IO.log(stringify(help.items[help.selectedItemIndex]));
}
private getBaselineFileName() {
return this.testData.globalOptions[MetadataOptionNames.baselineFile] ||
ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline");
}
private getSignatureHelp({ triggerReason }: FourSlashInterface.VerifySignatureHelpOptions): ts.SignatureHelpItems | undefined {
return this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition, {
triggerReason
@@ -3735,15 +3768,15 @@ namespace FourSlashInterface {
assert(ranges.length !== 0, "Array of ranges is expected to be non-empty");
}
public noSignatureHelp(...markers: string[]): void {
public noSignatureHelp(...markers: (string | FourSlash.Marker)[]): void {
this.state.verifySignatureHelpPresence(/*expectPresent*/ false, /*triggerReason*/ undefined, markers);
}
public noSignatureHelpForTriggerReason(reason: ts.SignatureHelpTriggerReason, ...markers: string[]): void {
public noSignatureHelpForTriggerReason(reason: ts.SignatureHelpTriggerReason, ...markers: (string | FourSlash.Marker)[]): void {
this.state.verifySignatureHelpPresence(/*expectPresent*/ false, reason, markers);
}
public signatureHelpPresentForTriggerReason(reason: ts.SignatureHelpTriggerReason, ...markers: string[]): void {
public signatureHelpPresentForTriggerReason(reason: ts.SignatureHelpTriggerReason, ...markers: (string | FourSlash.Marker)[]): void {
this.state.verifySignatureHelpPresence(/*expectPresent*/ true, reason, markers);
}
@@ -3960,6 +3993,10 @@ namespace FourSlashInterface {
this.state.baselineQuickInfo();
}
public baselineSmartSelection() {
this.state.baselineSmartSelection();
}
public nameOrDottedNameSpanTextIs(text: string) {
this.state.verifyCurrentNameOrDottedNameSpanText(text);
}
@@ -4398,18 +4435,63 @@ namespace FourSlashInterface {
}
}
export namespace Completion {
const functionEntry = (name: string): ExpectedCompletionEntryObject => ({ name, kind: "function", kindModifiers: "declare" });
const varEntry = (name: string): ExpectedCompletionEntryObject => ({ name, kind: "var", kindModifiers: "declare" });
const moduleEntry = (name: string): ExpectedCompletionEntryObject => ({ name, kind: "module", kindModifiers: "declare" });
const keywordEntry = (name: string): ExpectedCompletionEntryObject => ({ name, kind: "keyword" });
const methodEntry = (name: string): ExpectedCompletionEntryObject => ({ name, kind: "method", kindModifiers: "declare" });
const propertyEntry = (name: string): ExpectedCompletionEntryObject => ({ name, kind: "property", kindModifiers: "declare" });
const interfaceEntry = (name: string): ExpectedCompletionEntryObject => ({ name, kind: "interface", kindModifiers: "declare" });
const typeEntry = (name: string): ExpectedCompletionEntryObject => ({ name, kind: "type", kindModifiers: "declare" });
export import SortText = ts.Completions.SortText;
const functionEntry = (name: string): ExpectedCompletionEntryObject => ({
name,
kind: "function",
kindModifiers: "declare",
sortText: SortText.GlobalsOrKeywords
});
const varEntry = (name: string): ExpectedCompletionEntryObject => ({
name,
kind: "var",
kindModifiers: "declare",
sortText: SortText.GlobalsOrKeywords
});
const moduleEntry = (name: string): ExpectedCompletionEntryObject => ({
name,
kind: "module",
kindModifiers: "declare",
sortText: SortText.GlobalsOrKeywords
});
const keywordEntry = (name: string): ExpectedCompletionEntryObject => ({
name,
kind: "keyword",
sortText: SortText.GlobalsOrKeywords
});
const methodEntry = (name: string): ExpectedCompletionEntryObject => ({
name,
kind: "method",
kindModifiers: "declare",
sortText: SortText.LocationPriority
});
const propertyEntry = (name: string): ExpectedCompletionEntryObject => ({
name,
kind: "property",
kindModifiers: "declare",
sortText: SortText.LocationPriority
});
const interfaceEntry = (name: string): ExpectedCompletionEntryObject => ({
name,
kind: "interface",
kindModifiers: "declare",
sortText: SortText.GlobalsOrKeywords
});
const typeEntry = (name: string): ExpectedCompletionEntryObject => ({
name,
kind: "type",
kindModifiers: "declare",
sortText: SortText.GlobalsOrKeywords
});
const res: ExpectedCompletionEntryObject[] = [];
for (let i = ts.SyntaxKind.FirstKeyword; i <= ts.SyntaxKind.LastKeyword; i++) {
res.push({ name: ts.Debug.assertDefined(ts.tokenToString(i)), kind: "keyword" });
res.push({
name: ts.Debug.assertDefined(ts.tokenToString(i)),
kind: "keyword",
sortText: SortText.GlobalsOrKeywords
});
}
export const keywordsWithUndefined: ReadonlyArray<ExpectedCompletionEntryObject> = res;
export const keywords: ReadonlyArray<ExpectedCompletionEntryObject> = keywordsWithUndefined.filter(k => k.name !== "undefined");
@@ -4516,11 +4598,15 @@ namespace FourSlashInterface {
moduleEntry("Intl"),
];
export const globalThisEntry: ExpectedCompletionEntry = {
name: "globalThis",
kind: "module",
sortText: SortText.GlobalsOrKeywords
};
export const globalTypes = globalTypesPlus([]);
export function globalTypesPlus(plus: ReadonlyArray<ExpectedCompletionEntry>): ReadonlyArray<ExpectedCompletionEntry> {
return [
{ name: "globalThis", kind: "module" },
globalThisEntry,
...globalTypeDecls,
...plus,
...typeKeywords,
@@ -4569,7 +4655,11 @@ namespace FourSlashInterface {
export const classElementInJsKeywords = getInJsKeywords(classElementKeywords);
export const constructorParameterKeywords: ReadonlyArray<ExpectedCompletionEntryObject> =
["private", "protected", "public", "readonly"].map((name): ExpectedCompletionEntryObject => ({ name, kind: "keyword" }));
["private", "protected", "public", "readonly"].map((name): ExpectedCompletionEntryObject => ({
name,
kind: "keyword",
sortText: SortText.GlobalsOrKeywords
}));
export const functionMembers: ReadonlyArray<ExpectedCompletionEntryObject> = [
methodEntry("apply"),
@@ -4798,13 +4888,18 @@ namespace FourSlashInterface {
"await",
].map(keywordEntry);
export const undefinedVarEntry: ExpectedCompletionEntry = {
name: "undefined",
kind: "var",
sortText: SortText.GlobalsOrKeywords
};
// TODO: many of these are inappropriate to always provide
export const globalsInsideFunction = (plus: ReadonlyArray<ExpectedCompletionEntry>): ReadonlyArray<ExpectedCompletionEntry> => [
{ name: "arguments", kind: "local var" },
...plus,
{ name: "globalThis", kind: "module" },
globalThisEntry,
...globalsVars,
{ name: "undefined", kind: "var" },
undefinedVarEntry,
...globalKeywordsInsideFunction,
];
@@ -4813,10 +4908,10 @@ namespace FourSlashInterface {
// TODO: many of these are inappropriate to always provide
export const globalsInJsInsideFunction = (plus: ReadonlyArray<ExpectedCompletionEntry>): ReadonlyArray<ExpectedCompletionEntry> => [
{ name: "arguments", kind: "local var" },
{ name: "globalThis", kind: "module" },
globalThisEntry,
...globalsVars,
...plus,
{ name: "undefined", kind: "var" },
undefinedVarEntry,
...globalInJsKeywordsInsideFunction,
];
@@ -4954,34 +5049,34 @@ namespace FourSlashInterface {
})();
export const globals: ReadonlyArray<ExpectedCompletionEntryObject> = [
{ name: "globalThis", kind: "module" },
globalThisEntry,
...globalsVars,
{ name: "undefined", kind: "var" },
undefinedVarEntry,
...globalKeywords
];
export const globalsInJs: ReadonlyArray<ExpectedCompletionEntryObject> = [
{ name: "globalThis", kind: "module" },
globalThisEntry,
...globalsVars,
{ name: "undefined", kind: "var" },
undefinedVarEntry,
...globalInJsKeywords
];
export function globalsPlus(plus: ReadonlyArray<ExpectedCompletionEntry>): ReadonlyArray<ExpectedCompletionEntry> {
return [
{ name: "globalThis", kind: "module" },
globalThisEntry,
...globalsVars,
...plus,
{ name: "undefined", kind: "var" },
undefinedVarEntry,
...globalKeywords];
}
export function globalsInJsPlus(plus: ReadonlyArray<ExpectedCompletionEntry>): ReadonlyArray<ExpectedCompletionEntry> {
return [
{ name: "globalThis", kind: "module" },
globalThisEntry,
...globalsVars,
...plus,
{ name: "undefined", kind: "var" },
undefinedVarEntry,
...globalInJsKeywords];
}
}
@@ -5014,6 +5109,7 @@ namespace FourSlashInterface {
readonly documentation?: string;
readonly sourceDisplay?: string;
readonly tags?: ReadonlyArray<ts.JSDocTagInfo>;
readonly sortText?: ts.Completions.SortText;
}
export interface VerifyCompletionsOptions {
@@ -5028,7 +5124,7 @@ namespace FourSlashInterface {
}
export interface VerifySignatureHelpOptions {
readonly marker?: ArrayOrSingle<string>;
readonly marker?: ArrayOrSingle<string | FourSlash.Marker>;
/** @default 1 */
readonly overloadsCount?: number;
/** @default undefined */
+3
View File
@@ -472,6 +472,9 @@ namespace Harness.LanguageService {
getRenameInfo(fileName: string, position: number, options?: ts.RenameInfoOptions): ts.RenameInfo {
return unwrapJSONCallResult(this.shim.getRenameInfo(fileName, position, options));
}
getSmartSelectionRange(fileName: string, position: number): ts.SelectionRange {
return unwrapJSONCallResult(this.shim.getSmartSelectionRange(fileName, position));
}
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): ts.RenameLocation[] {
return unwrapJSONCallResult(this.shim.findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename));
}
+2 -1
View File
@@ -17328,7 +17328,8 @@ interface WorkerEventMap extends AbstractWorkerEventMap {
/** An interface of the Web Workers API represents a background task that can be easily created and can send messages back to its creator. Creating a worker is as simple as calling the Worker() constructor and specifying a script to be run in the worker thread. */
interface Worker extends EventTarget, AbstractWorker {
onmessage: ((this: Worker, ev: MessageEvent) => any) | null;
postMessage(message: any, transfer?: Transferable[]): void;
postMessage(message: any, transfer: Transferable[]): void;
postMessage(message: any, options?: PostMessageOptions): void;
terminate(): void;
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
+2 -4
View File
@@ -513,7 +513,7 @@ interface Boolean {
interface BooleanConstructor {
new(value?: any): Boolean;
<T>(value?: T): value is Exclude<T, false | null | undefined | '' | 0>;
<T>(value?: T): boolean;
readonly prototype: Boolean;
}
@@ -1446,9 +1446,7 @@ type Extract<T, U> = T extends U ? T : never;
/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit<T, K extends keyof any> = {
[P in Exclude<keyof T, K>]: T[P]
};
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
/**
* Exclude null and undefined from T
+2 -1
View File
@@ -4231,7 +4231,8 @@ interface WorkerEventMap extends AbstractWorkerEventMap {
/** An interface of the Web Workers API represents a background task that can be easily created and can send messages back to its creator. Creating a worker is as simple as calling the Worker() constructor and specifying a script to be run in the worker thread. */
interface Worker extends EventTarget, AbstractWorker {
onmessage: ((this: Worker, ev: MessageEvent) => any) | null;
postMessage(message: any, transfer?: Transferable[]): void;
postMessage(message: any, transfer: Transferable[]): void;
postMessage(message: any, options?: PostMessageOptions): void;
terminate(): void;
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
+7 -7
View File
@@ -198,13 +198,13 @@ namespace ts.server {
return hasOneOrMoreJsAndNoTsFiles(this);
}
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} | undefined {
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void, logErrors?: (message: string) => void): {} | undefined {
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
const result = host.require!(resolvedPath, moduleName); // TODO: GH#18217
if (result.error) {
const err = result.error.stack || result.error.message || JSON.stringify(result.error);
log(`Failed to load module '${moduleName}': ${err}`);
(logErrors || log)(`Failed to load module '${moduleName}' from ${resolvedPath}: ${err}`);
return undefined;
}
return result.module;
@@ -1142,12 +1142,11 @@ namespace ts.server {
protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[], pluginConfigOverrides: Map<any> | undefined) {
this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`);
const log = (message: string) => {
this.projectService.logger.info(message);
};
const log = (message: string) => this.projectService.logger.info(message);
let errorLogs: string[] | undefined;
const logError = (message: string) => { (errorLogs || (errorLogs = [])).push(message); };
const resolvedModule = firstDefined(searchPaths, searchPath =>
<PluginModuleFactory | undefined>Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log));
<PluginModuleFactory | undefined>Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log, logError));
if (resolvedModule) {
const configurationOverride = pluginConfigOverrides && pluginConfigOverrides.get(pluginConfigEntry.name);
if (configurationOverride) {
@@ -1160,6 +1159,7 @@ namespace ts.server {
this.enableProxy(resolvedModule, pluginConfigEntry);
}
else {
forEach(errorLogs, log);
this.projectService.logger.info(`Couldn't find ${pluginConfigEntry.name}`);
}
}
+22 -1
View File
@@ -130,7 +130,10 @@ namespace ts.server.protocol {
GetEditsForFileRename = "getEditsForFileRename",
/* @internal */
GetEditsForFileRenameFull = "getEditsForFileRename-full",
ConfigurePlugin = "configurePlugin"
ConfigurePlugin = "configurePlugin",
SelectionRange = "selectionRange",
/* @internal */
SelectionRangeFull = "selectionRange-full",
// NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`.
}
@@ -1395,6 +1398,24 @@ namespace ts.server.protocol {
export interface ConfigurePluginResponse extends Response {
}
export interface SelectionRangeRequest extends FileRequest {
command: CommandTypes.SelectionRange;
arguments: SelectionRangeRequestArgs;
}
export interface SelectionRangeRequestArgs extends FileRequestArgs {
locations: Location[];
}
export interface SelectionRangeResponse extends Response {
body?: SelectionRange[];
}
export interface SelectionRange {
textSpan: TextSpan;
parent?: SelectionRange;
}
/**
* Information found in an "open" request.
*/
+31 -3
View File
@@ -1318,11 +1318,11 @@ namespace ts.server {
this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath);
}
private getPosition(args: protocol.FileLocationRequestArgs, scriptInfo: ScriptInfo): number {
private getPosition(args: protocol.Location & { position?: number }, scriptInfo: ScriptInfo): number {
return args.position !== undefined ? args.position : scriptInfo.lineOffsetToPosition(args.line, args.offset);
}
private getPositionInFile(args: protocol.FileLocationRequestArgs, file: NormalizedPath): number {
private getPositionInFile(args: protocol.Location & { position?: number }, file: NormalizedPath): number {
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
return this.getPosition(args, scriptInfo);
}
@@ -2059,6 +2059,28 @@ namespace ts.server {
this.projectService.configurePlugin(args);
}
private getSmartSelectionRange(args: protocol.SelectionRangeRequestArgs, simplifiedResult: boolean) {
const { locations } = args;
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
const scriptInfo = Debug.assertDefined(this.projectService.getScriptInfo(file));
return map(locations, location => {
const pos = this.getPosition(location, scriptInfo);
const selectionRange = languageService.getSmartSelectionRange(file, pos);
return simplifiedResult ? this.mapSelectionRange(selectionRange, scriptInfo) : selectionRange;
});
}
private mapSelectionRange(selectionRange: SelectionRange, scriptInfo: ScriptInfo): protocol.SelectionRange {
const result: protocol.SelectionRange = {
textSpan: this.toLocationTextSpan(selectionRange.textSpan, scriptInfo),
};
if (selectionRange.parent) {
result.parent = this.mapSelectionRange(selectionRange.parent, scriptInfo);
}
return result;
}
getCanonicalFileName(fileName: string) {
const name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
return normalizePath(name);
@@ -2414,7 +2436,13 @@ namespace ts.server {
this.configurePlugin(request.arguments);
this.doOutput(/*info*/ undefined, CommandNames.ConfigurePlugin, request.seq, /*success*/ true);
return this.notRequired();
}
},
[CommandNames.SelectionRange]: (request: protocol.SelectionRangeRequest) => {
return this.requiredResponse(this.getSmartSelectionRange(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.SelectionRangeFull]: (request: protocol.SelectionRangeRequest) => {
return this.requiredResponse(this.getSmartSelectionRange(request.arguments, /*simplifiedResult*/ false));
},
});
public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) {
@@ -15,11 +15,11 @@ namespace ts.codefix {
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
const token = getTokenAtPosition(sourceFile, pos);
if (!isIdentifier(token)) {
return Debug.fail("add-name-to-nameless-parameter operates on identifiers, but got a " + formatSyntaxKind(token.kind));
return Debug.fail("add-name-to-nameless-parameter operates on identifiers, but got a " + Debug.formatSyntaxKind(token.kind));
}
const param = token.parent;
if (!isParameter(param)) {
return Debug.fail("Tried to add a parameter name to a non-parameter: " + formatSyntaxKind(token.kind));
return Debug.fail("Tried to add a parameter name to a non-parameter: " + Debug.formatSyntaxKind(token.kind));
}
const i = param.parent.parameters.indexOf(param);
Debug.assert(!param.type, "Tried to add a parameter name to a parameter that already had one.");
+104 -24
View File
@@ -1,5 +1,12 @@
/* @internal */
namespace ts.Completions {
export enum SortText {
LocationPriority = "0",
SuggestedClassMembers = "1",
GlobalsOrKeywords = "2",
AutoImportSuggestions = "3",
JavascriptIdentifiers = "4"
}
export type Log = (message: string) => void;
const enum SymbolOriginInfoKind { ThisType, SymbolMemberNoExport, SymbolMemberExport, Export }
@@ -22,6 +29,8 @@ namespace ts.Completions {
*/
type SymbolOriginInfoMap = (SymbolOriginInfo | undefined)[];
type SymbolSortTextMap = (SortText | undefined)[];
const enum KeywordCompletionFilters {
None, // No keywords
All, // Every possible keyword (TODO: This is never appropriate)
@@ -40,7 +49,9 @@ namespace ts.Completions {
const compilerOptions = program.getCompilerOptions();
const contextToken = findPrecedingToken(position, sourceFile);
if (triggerCharacter && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) return undefined;
if (triggerCharacter && !isInString(sourceFile, position, contextToken) && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) {
return undefined;
}
const stringCompletions = StringCompletions.getStringLiteralCompletions(sourceFile, position, contextToken, typeChecker, compilerOptions, host, log, preferences);
if (stringCompletions) {
@@ -78,7 +89,21 @@ namespace ts.Completions {
}
function completionInfoFromData(sourceFile: SourceFile, typeChecker: TypeChecker, compilerOptions: CompilerOptions, log: Log, completionData: CompletionData, preferences: UserPreferences): CompletionInfo | undefined {
const { symbols, completionKind, isInSnippetScope, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, literals, symbolToOriginInfoMap, recommendedCompletion, isJsxInitializer, insideJsDocTagTypeExpression } = completionData;
const {
symbols,
completionKind,
isInSnippetScope,
isNewIdentifierLocation,
location,
propertyAccessToConvert,
keywordFilters,
literals,
symbolToOriginInfoMap,
recommendedCompletion,
isJsxInitializer,
insideJsDocTagTypeExpression,
symbolToSortTextMap,
} = completionData;
if (location && location.parent && isJsxClosingElement(location.parent)) {
// In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag,
@@ -93,7 +118,7 @@ namespace ts.Completions {
name: tagName.getFullText(sourceFile) + (hasClosingAngleBracket ? "" : ">"),
kind: ScriptElementKind.classElement,
kindModifiers: undefined,
sortText: "0",
sortText: SortText.LocationPriority,
};
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [entry] };
}
@@ -101,7 +126,22 @@ namespace ts.Completions {
const entries: CompletionEntry[] = [];
if (isUncheckedFile(sourceFile, compilerOptions)) {
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target!, log, completionKind, preferences, propertyAccessToConvert, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap);
const uniqueNames = getCompletionEntriesFromSymbols(
symbols,
entries,
location,
sourceFile,
typeChecker,
compilerOptions.target!,
log,
completionKind,
preferences,
propertyAccessToConvert,
isJsxInitializer,
recommendedCompletion,
symbolToOriginInfoMap,
symbolToSortTextMap
);
getJSCompletionEntries(sourceFile, location!.pos, uniqueNames, compilerOptions.target!, entries); // TODO: GH#18217
}
else {
@@ -109,7 +149,22 @@ namespace ts.Completions {
return undefined;
}
getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target!, log, completionKind, preferences, propertyAccessToConvert, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap);
getCompletionEntriesFromSymbols(
symbols,
entries,
location,
sourceFile,
typeChecker,
compilerOptions.target!,
log,
completionKind,
preferences,
propertyAccessToConvert,
isJsxInitializer,
recommendedCompletion,
symbolToOriginInfoMap,
symbolToSortTextMap
);
}
if (keywordFilters !== KeywordCompletionFilters.None) {
@@ -160,7 +215,7 @@ namespace ts.Completions {
name: realName,
kind: ScriptElementKind.warning,
kindModifiers: "",
sortText: "1"
sortText: SortText.JavascriptIdentifiers
});
}
});
@@ -169,28 +224,23 @@ namespace ts.Completions {
const completionNameForLiteral = (literal: string | number | PseudoBigInt) =>
typeof literal === "object" ? pseudoBigIntToString(literal) + "n" : JSON.stringify(literal);
function createCompletionEntryForLiteral(literal: string | number | PseudoBigInt): CompletionEntry {
return { name: completionNameForLiteral(literal), kind: ScriptElementKind.string, kindModifiers: ScriptElementKindModifier.none, sortText: "0" };
return { name: completionNameForLiteral(literal), kind: ScriptElementKind.string, kindModifiers: ScriptElementKindModifier.none, sortText: SortText.LocationPriority };
}
function createCompletionEntry(
symbol: Symbol,
sortText: SortText,
location: Node | undefined,
sourceFile: SourceFile,
typeChecker: TypeChecker,
target: ScriptTarget,
kind: CompletionKind,
name: string,
needsConvertPropertyAccess: boolean,
origin: SymbolOriginInfo | undefined,
recommendedCompletion: Symbol | undefined,
propertyAccessToConvert: PropertyAccessExpression | undefined,
isJsxInitializer: IsJsxInitializer | undefined,
preferences: UserPreferences,
): CompletionEntry | undefined {
const info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind);
if (!info) {
return undefined;
}
const { name, needsConvertPropertyAccess } = info;
let insertText: string | undefined;
let replacementSpan: TextSpan | undefined;
if (origin && origin.kind === SymbolOriginInfoKind.ThisType) {
@@ -230,7 +280,7 @@ namespace ts.Completions {
name,
kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location!), // TODO: GH#18217
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
sortText: "0",
sortText,
source: getSourceFromOrigin(origin),
hasAction: trueOrUndefined(!!origin && originIsExport(origin)),
isRecommended: trueOrUndefined(isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker)),
@@ -266,6 +316,7 @@ namespace ts.Completions {
isJsxInitializer?: IsJsxInitializer,
recommendedCompletion?: Symbol,
symbolToOriginInfoMap?: SymbolOriginInfoMap,
symbolToSortTextMap?: SymbolSortTextMap,
): Map<true> {
const start = timestamp();
// Tracks unique names.
@@ -275,13 +326,30 @@ namespace ts.Completions {
const uniques = createMap<true>();
for (const symbol of symbols) {
const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined;
const entry = createCompletionEntry(symbol, location, sourceFile, typeChecker, target, kind, origin, recommendedCompletion, propertyAccessToConvert, isJsxInitializer, preferences);
if (!entry) {
const info = getCompletionEntryDisplayNameForSymbol(symbol, target, origin, kind);
if (!info) {
continue;
}
const { name, needsConvertPropertyAccess } = info;
if (uniques.has(name)) {
continue;
}
const { name } = entry;
if (uniques.has(name)) {
const entry = createCompletionEntry(
symbol,
symbolToSortTextMap && symbolToSortTextMap[getSymbolId(symbol)] || SortText.LocationPriority,
location,
sourceFile,
typeChecker,
name,
needsConvertPropertyAccess,
origin,
recommendedCompletion,
propertyAccessToConvert,
isJsxInitializer,
preferences
);
if (!entry) {
continue;
}
@@ -321,7 +389,7 @@ namespace ts.Completions {
name,
kindModifiers: ScriptElementKindModifier.none,
kind: ScriptElementKind.label,
sortText: "0"
sortText: SortText.LocationPriority
});
}
}
@@ -358,7 +426,7 @@ namespace ts.Completions {
// We don't need to perform character checks here because we're only comparing the
// name against 'entryName' (which is known to be good), not building a new
// completion entry.
return firstDefined<Symbol, SymbolCompletion>(symbols, (symbol): SymbolCompletion | undefined => { // TODO: Shouldn't need return type annotation (GH#12632)
return firstDefined(symbols, (symbol): SymbolCompletion | undefined => {
const origin = symbolToOriginInfoMap[getSymbolId(symbol)];
const info = getCompletionEntryDisplayNameForSymbol(symbol, compilerOptions.target!, origin, completionKind);
return info && info.name === entryId.name && getSourceFromOrigin(origin) === entryId.source
@@ -512,6 +580,7 @@ namespace ts.Completions {
readonly previousToken: Node | undefined;
readonly isJsxInitializer: IsJsxInitializer;
readonly insideJsDocTagTypeExpression: boolean;
readonly symbolToSortTextMap: SymbolSortTextMap;
}
type Request = { readonly kind: CompletionDataKind.JsDocTagName | CompletionDataKind.JsDocTag } | { readonly kind: CompletionDataKind.JsDocParameterName, tag: JSDocParameterTag };
@@ -804,6 +873,7 @@ namespace ts.Completions {
let keywordFilters = KeywordCompletionFilters.None;
let symbols: Symbol[] = [];
const symbolToOriginInfoMap: SymbolOriginInfoMap = [];
const symbolToSortTextMap: SymbolSortTextMap = [];
if (isRightOfDot) {
getTypeScriptMemberSymbols();
@@ -853,7 +923,8 @@ namespace ts.Completions {
recommendedCompletion,
previousToken,
isJsxInitializer,
insideJsDocTagTypeExpression
insideJsDocTagTypeExpression,
symbolToSortTextMap
};
type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag;
@@ -1054,6 +1125,12 @@ namespace ts.Completions {
const symbolMeanings = (isTypeOnly ? SymbolFlags.None : SymbolFlags.Value) | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias;
symbols = Debug.assertEachDefined(typeChecker.getSymbolsInScope(scopeNode, symbolMeanings), "getSymbolsInScope() should all be defined");
for (const symbol of symbols) {
if (!typeChecker.isArgumentsSymbol(symbol) &&
!some(symbol.declarations, d => d.getSourceFile() === sourceFile)) {
symbolToSortTextMap[getSymbolId(symbol)] = SortText.GlobalsOrKeywords;
}
}
// Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions`
if (preferences.includeCompletionsWithInsertText && scopeNode.kind !== SyntaxKind.SourceFile) {
@@ -1062,6 +1139,7 @@ namespace ts.Completions {
for (const symbol of getPropertiesForCompletion(thisType, typeChecker)) {
symbolToOriginInfoMap[getSymbolId(symbol)] = { kind: SymbolOriginInfoKind.ThisType };
symbols.push(symbol);
symbolToSortTextMap[getSymbolId(symbol)] = SortText.SuggestedClassMembers;
}
}
}
@@ -1195,6 +1273,7 @@ namespace ts.Completions {
// So in `declare namespace foo {} declare module "foo" { export = foo; }`, there will just be the global completion for `foo`.
some(resolvedModuleSymbol.declarations, d => !!d.getSourceFile().externalModuleIndicator)) {
symbols.push(resolvedModuleSymbol);
symbolToSortTextMap[getSymbolId(resolvedModuleSymbol)] = SortText.AutoImportSuggestions;
symbolToOriginInfoMap[getSymbolId(resolvedModuleSymbol)] = { kind: SymbolOriginInfoKind.Export, moduleSymbol, isDefaultExport: false };
}
@@ -1220,6 +1299,7 @@ namespace ts.Completions {
const origin: SymbolOriginInfoExport = { kind: SymbolOriginInfoKind.Export, moduleSymbol, isDefaultExport };
if (detailsEntryId || stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) {
symbols.push(symbol);
symbolToSortTextMap[getSymbolId(symbol)] = SortText.AutoImportSuggestions;
symbolToOriginInfoMap[getSymbolId(symbol)] = origin;
}
}
@@ -1941,7 +2021,7 @@ namespace ts.Completions {
name: tokenToString(i)!,
kind: ScriptElementKind.keyword,
kindModifiers: ScriptElementKindModifier.none,
sortText: "0"
sortText: SortText.GlobalsOrKeywords
});
}
return res;
+1 -1
View File
@@ -635,7 +635,7 @@ namespace ts.FindAllReferences.Core {
// Ignore UMD module and global merge
if (symbol.flags & SymbolFlags.Transient) return undefined;
// Assertions for GH#21814. We should be handling SourceFile symbols in `getReferencedSymbolsForModule` instead of getting here.
Debug.fail(`Unexpected symbol at ${Debug.showSyntaxKind(node)}: ${Debug.showSymbol(symbol)}`);
Debug.fail(`Unexpected symbol at ${Debug.formatSyntaxKind(node.kind)}: ${Debug.formatSymbol(symbol)}`);
}
return isTypeLiteralNode(decl.parent) && isUnionTypeNode(decl.parent.parent)
? checker.getPropertyOfType(checker.getTypeFromTypeNode(decl.parent.parent), symbol.name)
+2 -2
View File
@@ -133,7 +133,7 @@ namespace ts.FindAllReferences {
break;
default:
Debug.assertNever(direct, `Unexpected import kind: ${Debug.showSyntaxKind(direct)}`);
Debug.failBadSyntaxKind(direct, "Unexpected import kind.");
}
}
}
@@ -515,7 +515,7 @@ namespace ts.FindAllReferences {
const sym = useLhsSymbol ? checker.getSymbolAtLocation(cast(node.left, isPropertyAccessExpression).name) : symbol;
// Better detection for GH#20803
if (sym && !(checker.getMergedSymbol(sym.parent!).flags & SymbolFlags.Module)) {
Debug.fail(`Special property assignment kind does not have a module as its parent. Assignment is ${Debug.showSymbol(sym)}, parent is ${Debug.showSymbol(sym.parent!)}`);
Debug.fail(`Special property assignment kind does not have a module as its parent. Assignment is ${Debug.formatSymbol(sym)}, parent is ${Debug.formatSymbol(sym.parent!)}`);
}
return sym && exportInfo(sym, kind);
}
+25 -1
View File
@@ -89,7 +89,7 @@ namespace ts.OrganizeImports {
const usedImports: ImportDeclaration[] = [];
for (const importDecl of oldImports) {
const {importClause} = importDecl;
const { importClause, moduleSpecifier } = importDecl;
if (!importClause) {
// Imports without import clauses are assumed to be included for their side effects and are not removed.
@@ -125,6 +125,23 @@ namespace ts.OrganizeImports {
if (name || namedBindings) {
usedImports.push(updateImportDeclarationAndClause(importDecl, name, namedBindings));
}
// If a module is imported to be augmented, its used
else if (hasModuleDeclarationMatchingSpecifier(sourceFile, moduleSpecifier)) {
// If were in a declaration file, its safe to remove the import clause from it
if (sourceFile.isDeclarationFile) {
usedImports.push(createImportDeclaration(
importDecl.decorators,
importDecl.modifiers,
/*importClause*/ undefined,
moduleSpecifier));
}
// If were not in a declaration file, we cant remove the import clause even though
// the imported symbols are unused, because removing them makes it look like the import
// declaration has side effects, which will cause it to be preserved in the JS emit.
else {
usedImports.push(importDecl);
}
}
}
return usedImports;
@@ -135,6 +152,13 @@ namespace ts.OrganizeImports {
}
}
function hasModuleDeclarationMatchingSpecifier(sourceFile: SourceFile, moduleSpecifier: Expression) {
const moduleSpecifierText = isStringLiteral(moduleSpecifier) && moduleSpecifier.text;
return isString(moduleSpecifierText) && some(sourceFile.moduleAugmentations, moduleName =>
isStringLiteral(moduleName)
&& moduleName.text === moduleSpecifierText);
}
function getExternalModuleName(specifier: Expression) {
return specifier !== undefined && isStringLiteralLike(specifier)
? specifier.text
+20 -7
View File
@@ -173,7 +173,7 @@ namespace ts {
const textPos = scanner.getTextPos();
if (textPos <= end) {
if (token === SyntaxKind.Identifier) {
Debug.fail(`Did not expect ${Debug.showSyntaxKind(parent)} to have an Identifier in its trivia`);
Debug.fail(`Did not expect ${Debug.formatSyntaxKind(parent.kind)} to have an Identifier in its trivia`);
}
nodes.push(createNode(token, pos, textPos, parent));
}
@@ -1467,33 +1467,41 @@ namespace ts {
}
const typeChecker = program.getTypeChecker();
const symbol = getSymbolAtLocationForQuickInfo(node, typeChecker);
const nodeForQuickInfo = getNodeForQuickInfo(node);
const symbol = getSymbolAtLocationForQuickInfo(nodeForQuickInfo, typeChecker);
if (!symbol || typeChecker.isUnknownSymbol(symbol)) {
const type = shouldGetType(sourceFile, node, position) ? typeChecker.getTypeAtLocation(node) : undefined;
const type = shouldGetType(sourceFile, nodeForQuickInfo, position) ? typeChecker.getTypeAtLocation(nodeForQuickInfo) : undefined;
return type && {
kind: ScriptElementKind.unknown,
kindModifiers: ScriptElementKindModifier.none,
textSpan: createTextSpanFromNode(node, sourceFile),
displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(node))),
textSpan: createTextSpanFromNode(nodeForQuickInfo, sourceFile),
displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(nodeForQuickInfo))),
documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined,
tags: type.symbol ? type.symbol.getJsDocTags() : undefined
};
}
const { symbolKind, displayParts, documentation, tags } = typeChecker.runWithCancellationToken(cancellationToken, typeChecker =>
SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(node), node)
SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(nodeForQuickInfo), nodeForQuickInfo)
);
return {
kind: symbolKind,
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
textSpan: createTextSpanFromNode(node, sourceFile),
textSpan: createTextSpanFromNode(nodeForQuickInfo, sourceFile),
displayParts,
documentation,
tags,
};
}
function getNodeForQuickInfo(node: Node): Node {
if (isNewExpression(node.parent) && node.pos === node.parent.pos) {
return node.parent.expression;
}
return node;
}
function shouldGetType(sourceFile: SourceFile, node: Node, position: number): boolean {
switch (node.kind) {
case SyntaxKind.Identifier:
@@ -2072,6 +2080,10 @@ namespace ts {
};
}
function getSmartSelectionRange(fileName: string, position: number): SelectionRange {
return SmartSelectionRange.getSmartSelectionRange(position, syntaxTreeCache.getCurrentSourceFile(fileName));
}
function getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences = emptyOptions): ApplicableRefactorInfo[] {
synchronizeHostData();
const file = getValidSourceFile(fileName);
@@ -2119,6 +2131,7 @@ namespace ts {
getBreakpointStatementAtPosition,
getNavigateToItems,
getRenameInfo,
getSmartSelectionRange,
findRenameLocations,
getNavigationBarItems,
getNavigationTree,
+8
View File
@@ -165,6 +165,7 @@ namespace ts {
* { canRename: boolean, localizedErrorMessage: string, displayName: string, fullDisplayName: string, kind: string, kindModifiers: string, triggerSpan: { start; length } }
*/
getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): string;
getSmartSelectionRange(fileName: string, position: number): string;
/**
* Returns a JSON-encoded value of the type:
@@ -838,6 +839,13 @@ namespace ts {
);
}
public getSmartSelectionRange(fileName: string, position: number): string {
return this.forwardJSONCall(
`getSmartSelectionRange('${fileName}', ${position})`,
() => this.languageService.getSmartSelectionRange(fileName, position)
);
}
public findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): string {
return this.forwardJSONCall(
`findRenameLocations('${fileName}', ${position}, ${findInStrings}, ${findInComments}, ${providePrefixAndSuffixTextForRename})`,
+16 -6
View File
@@ -133,11 +133,21 @@ namespace ts.SignatureHelp {
}
function containsPrecedingToken(startingToken: Node, sourceFile: SourceFile, container: Node) {
const precedingToken = Debug.assertDefined(
findPrecedingToken(startingToken.getFullStart(), sourceFile, startingToken.parent, /*excludeJsdoc*/ true)
);
return rangeContainsRange(container, precedingToken);
const pos = startingToken.getFullStart();
// Theres a possibility that `startingToken.parent` contains only `startingToken` and
// missing nodes, none of which are valid to be returned by `findPrecedingToken`. In that
// case, the preceding token we want is actually higher up the tree—almost definitely the
// next parent, but theoretically the situation with missing nodes might be happening on
// multiple nested levels.
let currentParent: Node | undefined = startingToken.parent;
while (currentParent) {
const precedingToken = findPrecedingToken(pos, sourceFile, currentParent, /*excludeJsdoc*/ true);
if (precedingToken) {
return rangeContainsRange(container, precedingToken);
}
currentParent = currentParent.parent;
}
return Debug.fail("Could not find preceding token");
}
export interface ArgumentInfoForCompletions {
@@ -455,7 +465,7 @@ namespace ts.SignatureHelp {
for (let n = node; !isSourceFile(n) && (isManuallyInvoked || !isBlock(n)); n = n.parent) {
// If the node is not a subspan of its parent, this is a big problem.
// There have been crashes that might be caused by this violation.
Debug.assert(rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${Debug.showSyntaxKind(n)}, parent: ${Debug.showSyntaxKind(n.parent)}`);
Debug.assert(rangeContainsRange(n.parent, n), "Not a subspan", () => `Child: ${Debug.formatSyntaxKind(n.kind)}, parent: ${Debug.formatSyntaxKind(n.parent.kind)}`);
const argumentInfo = getImmediatelyContainingArgumentOrContextualParameterInfo(n, position, sourceFile, checker);
if (argumentInfo) {
return argumentInfo;
+266
View File
@@ -0,0 +1,266 @@
/* @internal */
namespace ts.SmartSelectionRange {
export function getSmartSelectionRange(pos: number, sourceFile: SourceFile): SelectionRange {
let selectionRange: SelectionRange = {
textSpan: createTextSpanFromBounds(sourceFile.getFullStart(), sourceFile.getEnd())
};
let parentNode: Node = sourceFile;
outer: while (true) {
const children = getSelectionChildren(parentNode);
if (!children.length) break;
for (let i = 0; i < children.length; i++) {
const prevNode: Node | undefined = children[i - 1];
const node: Node = children[i];
const nextNode: Node | undefined = children[i + 1];
if (node.getStart(sourceFile) > pos) {
break outer;
}
if (positionShouldSnapToNode(pos, node, nextNode)) {
// 1. Blocks are effectively redundant with SyntaxLists.
// 2. TemplateSpans, along with the SyntaxLists containing them, are a somewhat unintuitive grouping
// of things that should be considered independently.
// 3. A VariableStatements children are just a VaraiableDeclarationList and a semicolon.
// 4. A lone VariableDeclaration in a VaraibleDeclaration feels redundant with the VariableStatement.
//
// Dive in without pushing a selection range.
if (isBlock(node)
|| isTemplateSpan(node) || isTemplateHead(node)
|| prevNode && isTemplateHead(prevNode)
|| isVariableDeclarationList(node) && isVariableStatement(parentNode)
|| isSyntaxList(node) && isVariableDeclarationList(parentNode)
|| isVariableDeclaration(node) && isSyntaxList(parentNode) && children.length === 1) {
parentNode = node;
break;
}
// Synthesize a stop for '${ ... }' since '${' and '}' actually belong to siblings.
if (isTemplateSpan(parentNode) && nextNode && isTemplateMiddleOrTemplateTail(nextNode)) {
const start = node.getFullStart() - "${".length;
const end = nextNode.getStart() + "}".length;
pushSelectionRange(start, end);
}
// Blocks with braces, brackets, parens, or JSX tags on separate lines should be
// selected from open to close, including whitespace but not including the braces/etc. themselves.
const isBetweenMultiLineBookends = isSyntaxList(node)
&& isListOpener(prevNode)
&& isListCloser(nextNode)
&& !positionsAreOnSameLine(prevNode.getStart(), nextNode.getStart(), sourceFile);
const jsDocCommentStart = hasJSDocNodes(node) && node.jsDoc![0].getStart();
const start = isBetweenMultiLineBookends ? prevNode.getEnd() : node.getStart();
const end = isBetweenMultiLineBookends ? nextNode.getStart() : node.getEnd();
if (isNumber(jsDocCommentStart)) {
pushSelectionRange(jsDocCommentStart, end);
}
pushSelectionRange(start, end);
// String literals should have a stop both inside and outside their quotes.
if (isStringLiteral(node) || isTemplateLiteral(node)) {
pushSelectionRange(start + 1, end - 1);
}
parentNode = node;
break;
}
}
}
return selectionRange;
function pushSelectionRange(start: number, end: number): void {
// Skip empty ranges
if (start !== end) {
// Skip ranges that are identical to the parent
const textSpan = createTextSpanFromBounds(start, end);
if (!selectionRange || !textSpansEqual(textSpan, selectionRange.textSpan)) {
selectionRange = { textSpan, ...selectionRange && { parent: selectionRange } };
}
}
}
}
/**
* Like `ts.positionBelongsToNode`, except positions immediately after nodes
* count too, unless that position belongs to the next node. In effect, makes
* selections able to snap to preceding tokens when the cursor is on the tail
* end of them with only whitespace ahead.
* @param pos The position to check.
* @param node The candidate node to snap to.
* @param nextNode The next sibling node in the tree.
* @param sourceFile The source file containing the nodes.
*/
function positionShouldSnapToNode(pos: number, node: Node, nextNode: Node | undefined) {
// Cant use 'ts.positionBelongsToNode()' here because it cleverly accounts
// for missing nodes, which cant really be considered when deciding what
// to select.
Debug.assert(node.pos <= pos);
if (pos < node.end) {
return true;
}
const nodeEnd = node.getEnd();
const nextNodeStart = nextNode && nextNode.getStart();
if (nodeEnd === pos) {
return pos !== nextNodeStart;
}
return false;
}
const isImport = or(isImportDeclaration, isImportEqualsDeclaration);
/**
* Gets the children of a node to be considered for selection ranging,
* transforming them into an artificial tree according to their intuitive
* grouping where no grouping actually exists in the parse tree. For example,
* top-level imports are grouped into their own SyntaxList so they can be
* selected all together, even though in the AST theyre just siblings of each
* other as well as of other top-level statements and declarations.
*/
function getSelectionChildren(node: Node): ReadonlyArray<Node> {
// Group top-level imports
if (isSourceFile(node)) {
return groupChildren(node.getChildAt(0).getChildren(), isImport);
}
// Mapped types _look_ like ObjectTypes with a single member,
// but in fact dont contain a SyntaxList or a node containing
// the “key/value” pair like ObjectTypes do, but it seems intuitive
// that the selection would snap to those points. The philosophy
// of choosing a selection range is not so much about what the
// syntax currently _is_ as what the syntax might easily become
// if the user is making a selection; e.g., we synthesize a selection
// around the “key/value” pair not because theres a node there, but
// because it allows the mapped type to become an object type with a
// few keystrokes.
if (isMappedTypeNode(node)) {
const [openBraceToken, ...children] = node.getChildren();
const closeBraceToken = Debug.assertDefined(children.pop());
Debug.assertEqual(openBraceToken.kind, SyntaxKind.OpenBraceToken);
Debug.assertEqual(closeBraceToken.kind, SyntaxKind.CloseBraceToken);
// Group `-/+readonly` and `-/+?`
const groupedWithPlusMinusTokens = groupChildren(children, child =>
child === node.readonlyToken || child.kind === SyntaxKind.ReadonlyKeyword ||
child === node.questionToken || child.kind === SyntaxKind.QuestionToken);
// Group type parameter with surrounding brackets
const groupedWithBrackets = groupChildren(groupedWithPlusMinusTokens, ({ kind }) =>
kind === SyntaxKind.OpenBracketToken ||
kind === SyntaxKind.TypeParameter ||
kind === SyntaxKind.CloseBracketToken
);
return [
openBraceToken,
// Pivot on `:`
createSyntaxList(splitChildren(groupedWithBrackets, ({ kind }) => kind === SyntaxKind.ColonToken)),
closeBraceToken,
];
}
// Group modifiers and property name, then pivot on `:`.
if (isPropertySignature(node)) {
const children = groupChildren(node.getChildren(), child =>
child === node.name || contains(node.modifiers, child));
return splitChildren(children, ({ kind }) => kind === SyntaxKind.ColonToken);
}
// Group the parameter name with its `...`, then that group with its `?`, then pivot on `=`.
if (isParameter(node)) {
const groupedDotDotDotAndName = groupChildren(node.getChildren(), child =>
child === node.dotDotDotToken || child === node.name);
const groupedWithQuestionToken = groupChildren(groupedDotDotDotAndName, child =>
child === groupedDotDotDotAndName[0] || child === node.questionToken);
return splitChildren(groupedWithQuestionToken, ({ kind }) => kind === SyntaxKind.EqualsToken);
}
// Pivot on '='
if (isBindingElement(node)) {
return splitChildren(node.getChildren(), ({ kind }) => kind === SyntaxKind.EqualsToken);
}
return node.getChildren();
}
/**
* Groups sibling nodes together into their own SyntaxList if they
* a) are adjacent, AND b) match a predicate function.
*/
function groupChildren(children: Node[], groupOn: (child: Node) => boolean): Node[] {
const result: Node[] = [];
let group: Node[] | undefined;
for (const child of children) {
if (groupOn(child)) {
group = group || [];
group.push(child);
}
else {
if (group) {
result.push(createSyntaxList(group));
group = undefined;
}
result.push(child);
}
}
if (group) {
result.push(createSyntaxList(group));
}
return result;
}
/**
* Splits sibling nodes into up to four partitions:
* 1) everything left of the first node matched by `pivotOn`,
* 2) the first node matched by `pivotOn`,
* 3) everything right of the first node matched by `pivotOn`,
* 4) a trailing semicolon, if `separateTrailingSemicolon` is enabled.
* The left and right groups, if not empty, will each be grouped into their own containing SyntaxList.
* @param children The sibling nodes to split.
* @param pivotOn The predicate function to match the node to be the pivot. The first node that matches
* the predicate will be used; any others that may match will be included into the right-hand group.
* @param separateTrailingSemicolon If the last token is a semicolon, it will be returned as a separate
* child rather than be included in the right-hand group.
*/
function splitChildren(children: Node[], pivotOn: (child: Node) => boolean, separateTrailingSemicolon = true): Node[] {
if (children.length < 2) {
return children;
}
const splitTokenIndex = findIndex(children, pivotOn);
if (splitTokenIndex === -1) {
return children;
}
const leftChildren = children.slice(0, splitTokenIndex);
const splitToken = children[splitTokenIndex];
const lastToken = last(children);
const separateLastToken = separateTrailingSemicolon && lastToken.kind === SyntaxKind.SemicolonToken;
const rightChildren = children.slice(splitTokenIndex + 1, separateLastToken ? children.length - 1 : undefined);
const result = compact([
leftChildren.length ? createSyntaxList(leftChildren) : undefined,
splitToken,
rightChildren.length ? createSyntaxList(rightChildren) : undefined,
]);
return separateLastToken ? result.concat(lastToken) : result;
}
function createSyntaxList(children: Node[]): SyntaxList {
Debug.assertGreaterThanOrEqual(children.length, 1);
const syntaxList = createNode(SyntaxKind.SyntaxList, children[0].pos, last(children).end) as SyntaxList;
syntaxList._children = children;
return syntaxList;
}
function isListOpener(token: Node | undefined): token is Node {
const kind = token && token.kind;
return kind === SyntaxKind.OpenBraceToken
|| kind === SyntaxKind.OpenBracketToken
|| kind === SyntaxKind.OpenParenToken
|| kind === SyntaxKind.JsxOpeningElement;
}
function isListCloser(token: Node | undefined): token is Node {
const kind = token && token.kind;
return kind === SyntaxKind.CloseBraceToken
|| kind === SyntaxKind.CloseBracketToken
|| kind === SyntaxKind.CloseParenToken
|| kind === SyntaxKind.JsxClosingElement;
}
}
+12 -2
View File
@@ -21,7 +21,17 @@ namespace ts.Completions.StringCompletions {
return convertPathCompletions(completion.paths);
case StringLiteralCompletionKind.Properties: {
const entries: CompletionEntry[] = [];
getCompletionEntriesFromSymbols(completion.symbols, entries, sourceFile, sourceFile, checker, ScriptTarget.ESNext, log, CompletionKind.String, preferences); // Target will not be used, so arbitrary
getCompletionEntriesFromSymbols(
completion.symbols,
entries,
sourceFile,
sourceFile,
checker,
ScriptTarget.ESNext,
log,
CompletionKind.String,
preferences
); // Target will not be used, so arbitrary
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: completion.hasIndexSignature, entries };
}
case StringLiteralCompletionKind.Types: {
@@ -60,7 +70,7 @@ namespace ts.Completions.StringCompletions {
const isGlobalCompletion = false; // We don't want the editor to offer any other completions, such as snippets, inside a comment.
const isNewIdentifierLocation = true; // The user may type in a path that doesn't yet exist, creating a "new identifier" with respect to the collection of identifiers the server is aware of.
const entries = pathCompletions.map(({ name, kind, span, extension }): CompletionEntry =>
({ name, kind, kindModifiers: kindModifiersFromExtension(extension), sortText: "0", replacementSpan: span }));
({ name, kind, kindModifiers: kindModifiersFromExtension(extension), sortText: SortText.LocationPriority, replacementSpan: span }));
return { isGlobalCompletion, isMemberCompletion: false, isNewIdentifierLocation, entries };
}
function kindModifiersFromExtension(extension: Extension | undefined): ScriptElementKindModifier {
+1
View File
@@ -28,6 +28,7 @@
"patternMatcher.ts",
"preProcess.ts",
"rename.ts",
"smartSelection.ts",
"signatureHelp.ts",
"sourcemaps.ts",
"suggestionDiagnostics.ts",
+7
View File
@@ -296,6 +296,8 @@ namespace ts {
getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): RenameInfo;
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): ReadonlyArray<RenameLocation> | undefined;
getSmartSelectionRange(fileName: string, position: number): SelectionRange;
getDefinitionAtPosition(fileName: string, position: number): ReadonlyArray<DefinitionInfo> | undefined;
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan | undefined;
getTypeDefinitionAtPosition(fileName: string, position: number): ReadonlyArray<DefinitionInfo> | undefined;
@@ -848,6 +850,11 @@ namespace ts {
isOptional: boolean;
}
export interface SelectionRange {
textSpan: TextSpan;
parent?: SelectionRange;
}
/**
* Represents a single signature to show in signature help.
* The id is used for subsequent calls into the language service to ask questions about the
+1
View File
@@ -142,6 +142,7 @@
"unittests/tsserver/reload.ts",
"unittests/tsserver/rename.ts",
"unittests/tsserver/resolutionCache.ts",
"unittests/tsserver/smartSelection.ts",
"unittests/tsserver/session.ts",
"unittests/tsserver/skipLibCheck.ts",
"unittests/tsserver/symLinks.ts",
@@ -197,13 +197,13 @@ namespace ts {
const caseSensitiveBasePath = "/dev/";
const caseSensitiveHost = new fakes.ParseConfigHost(createFileSystem(/*ignoreCase*/ false, caseSensitiveBasePath, "/"));
function verifyDiagnostics(actual: Diagnostic[], expected: {code: number, category: DiagnosticCategory, messageText: string}[]) {
function verifyDiagnostics(actual: Diagnostic[], expected: { code: number; messageText: string; }[]) {
assert.isTrue(expected.length === actual.length, `Expected error: ${JSON.stringify(expected)}. Actual error: ${JSON.stringify(actual)}.`);
for (let i = 0; i < actual.length; i++) {
const actualError = actual[i];
const expectedError = expected[i];
assert.equal(actualError.code, expectedError.code, "Error code mismatch");
assert.equal(actualError.category, expectedError.category, "Category mismatch");
assert.equal(actualError.category, DiagnosticCategory.Error, "Category mismatch"); // Should always be error
assert.equal(flattenDiagnosticMessageText(actualError.messageText, "\n"), expectedError.messageText);
}
}
@@ -246,7 +246,7 @@ namespace ts {
});
}
function testFailure(name: string, entry: string, expectedDiagnostics: { code: number, category: DiagnosticCategory, messageText: string }[]) {
function testFailure(name: string, entry: string, expectedDiagnostics: { code: number; messageText: string; }[]) {
it(name, () => {
const parsed = getParseCommandLine(entry);
verifyDiagnostics(parsed.errors, expectedDiagnostics);
@@ -280,26 +280,22 @@ namespace ts {
testFailure("can report errors on circular imports", "circular.json", [
{
code: 18000,
category: DiagnosticCategory.Error,
messageText: `Circularity detected while resolving configuration: ${[combinePaths(basePath, "circular.json"), combinePaths(basePath, "circular2.json"), combinePaths(basePath, "circular.json")].join(" -> ")}`
}
]);
testFailure("can report missing configurations", "missing.json", [{
code: 6096,
category: DiagnosticCategory.Message,
messageText: `File './missing2' does not exist.`
code: 6053,
messageText: `File './missing2' not found.`
}]);
testFailure("can report errors in extended configs", "failure.json", [{
code: 6114,
category: DiagnosticCategory.Error,
messageText: `Unknown option 'excludes'. Did you mean 'exclude'?`
}]);
testFailure("can error when 'extends' is not a string", "extends.json", [{
code: 5024,
category: DiagnosticCategory.Error,
messageText: `Compiler option 'extends' requires a value of type string.`
}]);
+1 -1
View File
@@ -1,7 +1,7 @@
namespace ts {
describe("unittests:: FactoryAPI", () => {
function assertSyntaxKind(node: Node, expected: SyntaxKind) {
assert.strictEqual(node.kind, expected, `Actual: ${Debug.showSyntaxKind(node)} Expected: ${(ts as any).SyntaxKind[expected]}`);
assert.strictEqual(node.kind, expected, `Actual: ${Debug.formatSyntaxKind(node.kind)} Expected: ${Debug.formatSyntaxKind(expected)}`);
}
describe("createExportAssignment", () => {
it("parenthesizes default export if necessary", () => {
+17 -1
View File
@@ -530,7 +530,7 @@ export = C;
});
});
describe("unittests:: moduleResolution:: Files with different casing", () => {
describe("unittests:: moduleResolution:: Files with different casing with forceConsistentCasingInFileNames", () => {
let library: SourceFile;
function test(files: Map<string>, options: CompilerOptions, currentDirectory: string, useCaseSensitiveFileNames: boolean, rootFiles: string[], diagnosticCodes: number[]): void {
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
@@ -649,6 +649,22 @@ import b = require("./moduleB");
});
test(files, { module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true }, "/a/B/c", /*useCaseSensitiveFileNames*/ false, ["moduleD.ts"], []);
});
it("should succeed when the two files in program differ only in drive letter in their names", () => {
const files = createMapFromTemplate({
"d:/someFolder/moduleA.ts": `import a = require("D:/someFolder/moduleC")`,
"d:/someFolder/moduleB.ts": `import a = require("./moduleC")`,
"D:/someFolder/moduleC.ts": "export const x = 10",
});
test(
files,
{ module: ModuleKind.CommonJS, forceConsistentCasingInFileNames: true },
"d:/someFolder",
/*useCaseSensitiveFileNames*/ false,
["d:/someFolder/moduleA.ts", "d:/someFolder/moduleB.ts"],
[]
);
});
});
describe("unittests:: moduleResolution:: baseUrl augmented module resolution", () => {
@@ -1,5 +1,5 @@
namespace ts {
describe("unittests:: services:: Organize imports", () => {
describe("unittests:: services:: organizeImports", () => {
describe("Sort imports", () => {
it("Sort - non-relative vs non-relative", () => {
assertSortsBefore(
@@ -343,6 +343,36 @@ import { } from "lib";
},
libFile);
testOrganizeImports("Unused_false_positive_module_augmentation",
{
path: "/test.d.ts",
content: `
import foo from 'foo';
import { Caseless } from 'caseless';
declare module 'foo' {}
declare module 'caseless' {
interface Caseless {
test(name: KeyType): boolean;
}
}`
});
testOrganizeImports("Unused_preserve_imports_for_module_augmentation_in_non_declaration_file",
{
path: "/test.ts",
content: `
import foo from 'foo';
import { Caseless } from 'caseless';
declare module 'foo' {}
declare module 'caseless' {
interface Caseless {
test(name: KeyType): boolean;
}
}`
});
testOrganizeImports("Unused_false_positive_shorthand_assignment",
{
path: "/test.ts",
@@ -36,7 +36,7 @@ namespace ts.projectSystem {
kindModifiers: ScriptElementKindModifier.exportedModifier,
name: "foo",
replacementSpan: undefined,
sortText: "0",
sortText: Completions.SortText.AutoImportSuggestions,
source: "/a",
};
assert.deepEqual<protocol.CompletionInfo | undefined>(response, {
@@ -264,6 +264,7 @@ namespace ts.server {
CommandNames.OrganizeImportsFull,
CommandNames.GetEditsForFileRename,
CommandNames.GetEditsForFileRenameFull,
CommandNames.SelectionRange,
];
it("should not throw when commands are executed with invalid arguments", () => {
@@ -0,0 +1,66 @@
namespace ts.projectSystem {
function setup(fileName: string, content: string) {
const file: File = { path: fileName, content };
const host = createServerHost([file, libFile]);
const session = createSession(host);
openFilesForSession([file], session);
return function getSmartSelectionRange(locations: protocol.SelectionRangeRequestArgs["locations"]) {
return executeSessionRequest<protocol.SelectionRangeRequest, protocol.SelectionRangeResponse>(
session,
CommandNames.SelectionRange,
{ file: fileName, locations });
};
}
// More tests in fourslash/smartSelection_*
describe("unittests:: tsserver:: smartSelection", () => {
it("works for simple JavaScript", () => {
const getSmartSelectionRange = setup("/file.js", `
class Foo {
bar(a, b) {
if (a === b) {
return true;
}
return false;
}
}`);
const locations = getSmartSelectionRange([
{ line: 4, offset: 13 }, // a === b
]);
assert.deepEqual(locations, [{
textSpan: { // a
start: { line: 4, offset: 13 },
end: { line: 4, offset: 14 } },
parent: {
textSpan: { // a === b
start: { line: 4, offset: 13 },
end: { line: 4, offset: 20 } },
parent: {
textSpan: { // IfStatement
start: { line: 4, offset: 9 },
end: { line: 6, offset: 10 } },
parent: {
textSpan: { // SyntaxList + whitespace (body of method)
start: { line: 3, offset: 16 },
end: { line: 8, offset: 5 } },
parent: {
textSpan: { // MethodDeclaration
start: { line: 3, offset: 5 },
end: { line: 8, offset: 6 } },
parent: {
textSpan: { // SyntaxList + whitespace (body of class)
start: { line: 2, offset: 12 },
end: { line: 9, offset: 1 } },
parent: {
textSpan: { // ClassDeclaration
start: { line: 2, offset: 1 },
end: { line: 9, offset: 2 } },
parent: {
textSpan: { // SourceFile (all text)
start: { line: 1, offset: 1 },
end: { line: 9, offset: 2 }, } } } } } } } } }]);
});
});
}
+64
View File
@@ -0,0 +1,64 @@
//// [ES5For-of37.ts]
// https://github.com/microsoft/TypeScript/issues/30083
for (const i of [0, 1, 2, 3, 4]) {
try {
// Ensure catch binding for the following loop is reset per iteration:
for (const j of [1, 2, 3]) {
if (i === 2) {
throw new Error('ERR');
}
}
console.log(i);
} catch (err) {
console.log('E %s %s', i, err);
}
}
//// [ES5For-of37.js]
// https://github.com/microsoft/TypeScript/issues/30083
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
var e_1, _a, e_2, _b;
try {
for (var _c = __values([0, 1, 2, 3, 4]), _d = _c.next(); !_d.done; _d = _c.next()) {
var i = _d.value;
try {
try {
// Ensure catch binding for the following loop is reset per iteration:
for (var _e = (e_2 = void 0, __values([1, 2, 3])), _f = _e.next(); !_f.done; _f = _e.next()) {
var j = _f.value;
if (i === 2) {
throw new Error('ERR');
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_f && !_f.done && (_b = _e["return"])) _b.call(_e);
}
finally { if (e_2) throw e_2.error; }
}
console.log(i);
}
catch (err) {
console.log('E %s %s', i, err);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c["return"])) _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
@@ -0,0 +1,35 @@
=== tests/cases/conformance/statements/for-ofStatements/ES5For-of37.ts ===
// https://github.com/microsoft/TypeScript/issues/30083
for (const i of [0, 1, 2, 3, 4]) {
>i : Symbol(i, Decl(ES5For-of37.ts, 2, 10))
try {
// Ensure catch binding for the following loop is reset per iteration:
for (const j of [1, 2, 3]) {
>j : Symbol(j, Decl(ES5For-of37.ts, 5, 18))
if (i === 2) {
>i : Symbol(i, Decl(ES5For-of37.ts, 2, 10))
throw new Error('ERR');
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}
}
console.log(i);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>i : Symbol(i, Decl(ES5For-of37.ts, 2, 10))
} catch (err) {
>err : Symbol(err, Decl(ES5For-of37.ts, 11, 13))
console.log('E %s %s', i, err);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>i : Symbol(i, Decl(ES5For-of37.ts, 2, 10))
>err : Symbol(err, Decl(ES5For-of37.ts, 11, 13))
}
}
@@ -0,0 +1,52 @@
=== tests/cases/conformance/statements/for-ofStatements/ES5For-of37.ts ===
// https://github.com/microsoft/TypeScript/issues/30083
for (const i of [0, 1, 2, 3, 4]) {
>i : number
>[0, 1, 2, 3, 4] : number[]
>0 : 0
>1 : 1
>2 : 2
>3 : 3
>4 : 4
try {
// Ensure catch binding for the following loop is reset per iteration:
for (const j of [1, 2, 3]) {
>j : number
>[1, 2, 3] : number[]
>1 : 1
>2 : 2
>3 : 3
if (i === 2) {
>i === 2 : boolean
>i : number
>2 : 2
throw new Error('ERR');
>new Error('ERR') : Error
>Error : ErrorConstructor
>'ERR' : "ERR"
}
}
console.log(i);
>console.log(i) : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>i : number
} catch (err) {
>err : any
console.log('E %s %s', i, err);
>console.log('E %s %s', i, err) : void
>console.log : (message?: any, ...optionalParams: any[]) => void
>console : Console
>log : (message?: any, ...optionalParams: any[]) => void
>'E %s %s' : "E %s %s"
>i : number
>err : any
}
}
@@ -10,4 +10,5 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-of7.ts(6,9): error TS
var x = [w, v];
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'any', but here has type 'any[]'.
!!! related TS6203 tests/cases/conformance/statements/for-ofStatements/ES5For-of7.ts:2:9: 'x' was also declared here.
}
@@ -24,6 +24,7 @@ tests/cases/conformance/internalModules/DeclarationMerging/test.ts(2,5): error T
var fn = A.Point;
~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'fn' must be of type '() => { x: number; y: number; }', but here has type 'typeof Point'.
!!! related TS6203 tests/cases/conformance/internalModules/DeclarationMerging/test.ts:1:5: 'fn' was also declared here.
var cl: { x: number; y: number; }
var cl = A.Point();
@@ -46,6 +47,7 @@ tests/cases/conformance/internalModules/DeclarationMerging/test.ts(2,5): error T
var fn = B.Point; // not expected to be an error. bug 840000: [corelang] Function of fundule not assignalbe as expected
~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'fn' must be of type '() => { x: number; y: number; }', but here has type 'typeof Point'.
!!! related TS6203 tests/cases/conformance/internalModules/DeclarationMerging/test.ts:1:5: 'fn' was also declared here.
var cl: { x: number; y: number; }
var cl = B.Point();
+35 -11
View File
@@ -14,7 +14,7 @@ and limitations under the License.
***************************************************************************** */
declare namespace ts {
const versionMajorMinor = "3.5";
const versionMajorMinor = "3.6";
/** The version of the TypeScript compiler release */
const version: string;
}
@@ -1969,6 +1969,7 @@ declare namespace ts {
*/
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
getTypeOfAssignmentPattern(pattern: AssignmentPattern): Type;
getTypeAtLocation(node: Node): Type;
getTypeFromTypeNode(node: TypeNode): Type;
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
@@ -2390,8 +2391,8 @@ declare namespace ts {
root: ConditionalRoot;
checkType: Type;
extendsType: Type;
trueType: Type;
falseType: Type;
resolvedTrueType: Type;
resolvedFalseType: Type;
}
interface SubstitutionType extends InstantiableType {
typeVariable: TypeVariable;
@@ -2418,12 +2419,13 @@ declare namespace ts {
enum InferencePriority {
NakedTypeVariable = 1,
HomomorphicMappedType = 2,
MappedTypeConstraint = 4,
ReturnType = 8,
LiteralKeyof = 16,
NoConstraints = 32,
AlwaysStrict = 64,
PriorityImpliesCombination = 28
PartialHomomorphicMappedType = 4,
MappedTypeConstraint = 8,
ReturnType = 16,
LiteralKeyof = 32,
NoConstraints = 64,
AlwaysStrict = 128,
PriorityImpliesCombination = 56
}
/** @deprecated Use FileExtensionInfo instead. */
type JsFileExtensionInfo = FileExtensionInfo;
@@ -4808,6 +4810,7 @@ declare namespace ts {
getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): SignatureHelpItems | undefined;
getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): RenameInfo;
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): ReadonlyArray<RenameLocation> | undefined;
getSmartSelectionRange(fileName: string, position: number): SelectionRange;
getDefinitionAtPosition(fileName: string, position: number): ReadonlyArray<DefinitionInfo> | undefined;
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan | undefined;
getTypeDefinitionAtPosition(fileName: string, position: number): ReadonlyArray<DefinitionInfo> | undefined;
@@ -5252,6 +5255,10 @@ declare namespace ts {
displayParts: SymbolDisplayPart[];
isOptional: boolean;
}
interface SelectionRange {
textSpan: TextSpan;
parent?: SelectionRange;
}
/**
* Represents a single signature to show in signature help.
* The id is used for subsequent calls into the language service to ask questions about the
@@ -5799,7 +5806,8 @@ declare namespace ts.server.protocol {
GetEditsForRefactor = "getEditsForRefactor",
OrganizeImports = "organizeImports",
GetEditsForFileRename = "getEditsForFileRename",
ConfigurePlugin = "configurePlugin"
ConfigurePlugin = "configurePlugin",
SelectionRange = "selectionRange",
}
/**
* A TypeScript Server message
@@ -6762,6 +6770,20 @@ declare namespace ts.server.protocol {
}
interface ConfigurePluginResponse extends Response {
}
interface SelectionRangeRequest extends FileRequest {
command: CommandTypes.SelectionRange;
arguments: SelectionRangeRequestArgs;
}
interface SelectionRangeRequestArgs extends FileRequestArgs {
locations: Location[];
}
interface SelectionRangeResponse extends Response {
body?: SelectionRange[];
}
interface SelectionRange {
textSpan: TextSpan;
parent?: SelectionRange;
}
/**
* Information found in an "open" request.
*/
@@ -8299,7 +8321,7 @@ declare namespace ts.server {
private readonly cancellationToken;
isNonTsProject(): boolean;
isJsOnlyProject(): boolean;
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} | undefined;
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void, logErrors?: (message: string) => void): {} | undefined;
isKnownTypesPackageName(name: string): boolean;
installPackage(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
private readonly typingsCache;
@@ -9038,6 +9060,8 @@ declare namespace ts.server {
private getBraceMatching;
private getDiagnosticsForProject;
private configurePlugin;
private getSmartSelectionRange;
private mapSelectionRange;
getCanonicalFileName(fileName: string): string;
exit(): void;
private notRequired;
+16 -9
View File
@@ -14,7 +14,7 @@ and limitations under the License.
***************************************************************************** */
declare namespace ts {
const versionMajorMinor = "3.5";
const versionMajorMinor = "3.6";
/** The version of the TypeScript compiler release */
const version: string;
}
@@ -1969,6 +1969,7 @@ declare namespace ts {
*/
getExportSymbolOfSymbol(symbol: Symbol): Symbol;
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol | undefined;
getTypeOfAssignmentPattern(pattern: AssignmentPattern): Type;
getTypeAtLocation(node: Node): Type;
getTypeFromTypeNode(node: TypeNode): Type;
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
@@ -2390,8 +2391,8 @@ declare namespace ts {
root: ConditionalRoot;
checkType: Type;
extendsType: Type;
trueType: Type;
falseType: Type;
resolvedTrueType: Type;
resolvedFalseType: Type;
}
interface SubstitutionType extends InstantiableType {
typeVariable: TypeVariable;
@@ -2418,12 +2419,13 @@ declare namespace ts {
enum InferencePriority {
NakedTypeVariable = 1,
HomomorphicMappedType = 2,
MappedTypeConstraint = 4,
ReturnType = 8,
LiteralKeyof = 16,
NoConstraints = 32,
AlwaysStrict = 64,
PriorityImpliesCombination = 28
PartialHomomorphicMappedType = 4,
MappedTypeConstraint = 8,
ReturnType = 16,
LiteralKeyof = 32,
NoConstraints = 64,
AlwaysStrict = 128,
PriorityImpliesCombination = 56
}
/** @deprecated Use FileExtensionInfo instead. */
type JsFileExtensionInfo = FileExtensionInfo;
@@ -4808,6 +4810,7 @@ declare namespace ts {
getSignatureHelpItems(fileName: string, position: number, options: SignatureHelpItemsOptions | undefined): SignatureHelpItems | undefined;
getRenameInfo(fileName: string, position: number, options?: RenameInfoOptions): RenameInfo;
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): ReadonlyArray<RenameLocation> | undefined;
getSmartSelectionRange(fileName: string, position: number): SelectionRange;
getDefinitionAtPosition(fileName: string, position: number): ReadonlyArray<DefinitionInfo> | undefined;
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan | undefined;
getTypeDefinitionAtPosition(fileName: string, position: number): ReadonlyArray<DefinitionInfo> | undefined;
@@ -5252,6 +5255,10 @@ declare namespace ts {
displayParts: SymbolDisplayPart[];
isOptional: boolean;
}
interface SelectionRange {
textSpan: TextSpan;
parent?: SelectionRange;
}
/**
* Represents a single signature to show in signature help.
* The id is used for subsequent calls into the language service to ask questions about the
@@ -0,0 +1,8 @@
tests/cases/compiler/assigningFunctionToTupleIssuesError.ts(2,5): error TS2322: Type '() => void' is not assignable to type '[string]'.
==== tests/cases/compiler/assigningFunctionToTupleIssuesError.ts (1 errors) ====
declare let a: () => void;
let b: [string] = a;
~
!!! error TS2322: Type '() => void' is not assignable to type '[string]'.
@@ -0,0 +1,6 @@
//// [assigningFunctionToTupleIssuesError.ts]
declare let a: () => void;
let b: [string] = a;
//// [assigningFunctionToTupleIssuesError.js]
var b = a;
@@ -0,0 +1,8 @@
=== tests/cases/compiler/assigningFunctionToTupleIssuesError.ts ===
declare let a: () => void;
>a : Symbol(a, Decl(assigningFunctionToTupleIssuesError.ts, 0, 11))
let b: [string] = a;
>b : Symbol(b, Decl(assigningFunctionToTupleIssuesError.ts, 1, 3))
>a : Symbol(a, Decl(assigningFunctionToTupleIssuesError.ts, 0, 11))
@@ -0,0 +1,8 @@
=== tests/cases/compiler/assigningFunctionToTupleIssuesError.ts ===
declare let a: () => void;
>a : () => void
let b: [string] = a;
>b : [string]
>a : () => void
@@ -16,6 +16,7 @@ tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction5_es20
!!! error TS1005: ',' expected.
~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'any'.
!!! related TS6203 /.ts/lib.es2015.promise.d.ts:152:13: 'Promise' was also declared here.
~
!!! error TS1005: ',' expected.
~~
@@ -16,6 +16,7 @@ tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction5_es5.ts(
!!! error TS1005: ',' expected.
~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'any'.
!!! related TS6203 /.ts/lib.es2015.promise.d.ts:152:13: 'Promise' was also declared here.
~
!!! error TS1005: ',' expected.
~~
@@ -16,6 +16,7 @@ tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction5_es6.ts(
!!! error TS1005: ',' expected.
~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'any'.
!!! related TS6203 /.ts/lib.es2015.promise.d.ts:152:13: 'Promise' was also declared here.
~
!!! error TS1005: ',' expected.
~~
@@ -16,6 +16,7 @@ tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction9_es20
!!! error TS1005: ',' expected.
~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'any'.
!!! related TS6203 /.ts/lib.es2015.promise.d.ts:152:13: 'Promise' was also declared here.
~
!!! error TS1005: ',' expected.
~~
@@ -16,6 +16,7 @@ tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction9_es5.ts(
!!! error TS1005: ',' expected.
~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'any'.
!!! related TS6203 /.ts/lib.es2015.promise.d.ts:152:13: 'Promise' was also declared here.
~
!!! error TS1005: ',' expected.
~~
@@ -16,6 +16,7 @@ tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction9_es6.ts(
!!! error TS1005: ',' expected.
~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'any'.
!!! related TS6203 /.ts/lib.es2015.promise.d.ts:152:13: 'Promise' was also declared here.
~
!!! error TS1005: ',' expected.
~~
@@ -30,6 +30,7 @@ tests/cases/compiler/augmentedTypesVar.ts(31,8): error TS2300: Duplicate identif
var x3 = () => { } // error
~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x3' must be of type 'number', but here has type '() => void'.
!!! related TS6203 tests/cases/compiler/augmentedTypesVar.ts:9:5: 'x3' was also declared here.
// var then class
var x4 = 1; // error
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
=== tests/cases/conformance/salsa/loop.js ===
var loop1 = loop2;
>loop1 : Symbol(loop1, Decl(loop.js, 0, 3))
>loop2 : Symbol(loop2, Decl(loop.js, 1, 3))
var loop2 = loop1;
>loop2 : Symbol(loop2, Decl(loop.js, 1, 3))
>loop1 : Symbol(loop1, Decl(loop.js, 0, 3))
module.exports = loop2;
>module.exports : Symbol("tests/cases/conformance/salsa/loop", Decl(loop.js, 0, 0))
>module : Symbol(export=, Decl(loop.js, 1, 18))
>exports : Symbol(export=, Decl(loop.js, 1, 18))
>loop2 : Symbol(loop2, Decl(loop.js, 1, 3))
@@ -0,0 +1,16 @@
=== tests/cases/conformance/salsa/loop.js ===
var loop1 = loop2;
>loop1 : any
>loop2 : any
var loop2 = loop1;
>loop2 : any
>loop1 : any
module.exports = loop2;
>module.exports = loop2 : any
>module.exports : any
>module : { "tests/cases/conformance/salsa/loop": any; }
>exports : any
>loop2 : any
@@ -0,0 +1,37 @@
//// [booleanFilterAnyArray.ts]
interface Bullean { }
interface BulleanConstructor {
new(v1?: any): Bullean;
<T>(v2?: T): v2 is T;
}
interface Ari<T> {
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
filter(cb2: (value: T) => unknown): Ari<T>;
}
declare var Bullean: BulleanConstructor;
declare let anys: Ari<any>;
var xs: Ari<any>;
var xs = anys.filter(Bullean)
declare let realanys: any[];
var ys: any[];
var ys = realanys.filter(Boolean)
var foo = [{ name: 'x' }]
var foor: Array<{name: string}>
var foor = foo.filter(x => x.name)
var foos: Array<boolean>
var foos = [true, true, false, null].filter((thing): thing is boolean => thing !== null)
//// [booleanFilterAnyArray.js]
var xs;
var xs = anys.filter(Bullean);
var ys;
var ys = realanys.filter(Boolean);
var foo = [{ name: 'x' }];
var foor;
var foor = foo.filter(function (x) { return x.name; });
var foos;
var foos = [true, true, false, null].filter(function (thing) { return thing !== null; });
@@ -0,0 +1,108 @@
=== tests/cases/compiler/booleanFilterAnyArray.ts ===
interface Bullean { }
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
interface BulleanConstructor {
>BulleanConstructor : Symbol(BulleanConstructor, Decl(booleanFilterAnyArray.ts, 0, 21))
new(v1?: any): Bullean;
>v1 : Symbol(v1, Decl(booleanFilterAnyArray.ts, 2, 8))
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
<T>(v2?: T): v2 is T;
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 3, 5))
>v2 : Symbol(v2, Decl(booleanFilterAnyArray.ts, 3, 8))
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 3, 5))
>v2 : Symbol(v2, Decl(booleanFilterAnyArray.ts, 3, 8))
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 3, 5))
}
interface Ari<T> {
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
>S : Symbol(S, Decl(booleanFilterAnyArray.ts, 7, 11))
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
>cb1 : Symbol(cb1, Decl(booleanFilterAnyArray.ts, 7, 24))
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 7, 30))
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 7, 30))
>S : Symbol(S, Decl(booleanFilterAnyArray.ts, 7, 11))
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
>S : Symbol(S, Decl(booleanFilterAnyArray.ts, 7, 11))
filter(cb2: (value: T) => unknown): Ari<T>;
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
>cb2 : Symbol(cb2, Decl(booleanFilterAnyArray.ts, 8, 11))
>value : Symbol(value, Decl(booleanFilterAnyArray.ts, 8, 17))
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
>T : Symbol(T, Decl(booleanFilterAnyArray.ts, 6, 14))
}
declare var Bullean: BulleanConstructor;
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
>BulleanConstructor : Symbol(BulleanConstructor, Decl(booleanFilterAnyArray.ts, 0, 21))
declare let anys: Ari<any>;
>anys : Symbol(anys, Decl(booleanFilterAnyArray.ts, 11, 11))
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
var xs: Ari<any>;
>xs : Symbol(xs, Decl(booleanFilterAnyArray.ts, 12, 3), Decl(booleanFilterAnyArray.ts, 13, 3))
>Ari : Symbol(Ari, Decl(booleanFilterAnyArray.ts, 4, 1))
var xs = anys.filter(Bullean)
>xs : Symbol(xs, Decl(booleanFilterAnyArray.ts, 12, 3), Decl(booleanFilterAnyArray.ts, 13, 3))
>anys.filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
>anys : Symbol(anys, Decl(booleanFilterAnyArray.ts, 11, 11))
>filter : Symbol(Ari.filter, Decl(booleanFilterAnyArray.ts, 6, 18), Decl(booleanFilterAnyArray.ts, 7, 90))
>Bullean : Symbol(Bullean, Decl(booleanFilterAnyArray.ts, 0, 0), Decl(booleanFilterAnyArray.ts, 10, 11))
declare let realanys: any[];
>realanys : Symbol(realanys, Decl(booleanFilterAnyArray.ts, 15, 11))
var ys: any[];
>ys : Symbol(ys, Decl(booleanFilterAnyArray.ts, 16, 3), Decl(booleanFilterAnyArray.ts, 17, 3))
var ys = realanys.filter(Boolean)
>ys : Symbol(ys, Decl(booleanFilterAnyArray.ts, 16, 3), Decl(booleanFilterAnyArray.ts, 17, 3))
>realanys.filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>realanys : Symbol(realanys, Decl(booleanFilterAnyArray.ts, 15, 11))
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
var foo = [{ name: 'x' }]
>foo : Symbol(foo, Decl(booleanFilterAnyArray.ts, 19, 3))
>name : Symbol(name, Decl(booleanFilterAnyArray.ts, 19, 12))
var foor: Array<{name: string}>
>foor : Symbol(foor, Decl(booleanFilterAnyArray.ts, 20, 3), Decl(booleanFilterAnyArray.ts, 21, 3))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>name : Symbol(name, Decl(booleanFilterAnyArray.ts, 20, 17))
var foor = foo.filter(x => x.name)
>foor : Symbol(foor, Decl(booleanFilterAnyArray.ts, 20, 3), Decl(booleanFilterAnyArray.ts, 21, 3))
>foo.filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>foo : Symbol(foo, Decl(booleanFilterAnyArray.ts, 19, 3))
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(booleanFilterAnyArray.ts, 21, 22))
>x.name : Symbol(name, Decl(booleanFilterAnyArray.ts, 19, 12))
>x : Symbol(x, Decl(booleanFilterAnyArray.ts, 21, 22))
>name : Symbol(name, Decl(booleanFilterAnyArray.ts, 19, 12))
var foos: Array<boolean>
>foos : Symbol(foos, Decl(booleanFilterAnyArray.ts, 22, 3), Decl(booleanFilterAnyArray.ts, 23, 3))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
var foos = [true, true, false, null].filter((thing): thing is boolean => thing !== null)
>foos : Symbol(foos, Decl(booleanFilterAnyArray.ts, 22, 3), Decl(booleanFilterAnyArray.ts, 23, 3))
>[true, true, false, null].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>thing : Symbol(thing, Decl(booleanFilterAnyArray.ts, 23, 45))
>thing : Symbol(thing, Decl(booleanFilterAnyArray.ts, 23, 45))
>thing : Symbol(thing, Decl(booleanFilterAnyArray.ts, 23, 45))
@@ -0,0 +1,94 @@
=== tests/cases/compiler/booleanFilterAnyArray.ts ===
interface Bullean { }
interface BulleanConstructor {
new(v1?: any): Bullean;
>v1 : any
<T>(v2?: T): v2 is T;
>v2 : T
}
interface Ari<T> {
filter<S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>;
>filter : { <S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>; (cb2: (value: T) => unknown): Ari<T>; }
>cb1 : (value: T) => value is S
>value : T
filter(cb2: (value: T) => unknown): Ari<T>;
>filter : { <S extends T>(cb1: (value: T) => value is S): T extends any ? Ari<any> : Ari<S>; (cb2: (value: T) => unknown): Ari<T>; }
>cb2 : (value: T) => unknown
>value : T
}
declare var Bullean: BulleanConstructor;
>Bullean : BulleanConstructor
declare let anys: Ari<any>;
>anys : Ari<any>
var xs: Ari<any>;
>xs : Ari<any>
var xs = anys.filter(Bullean)
>xs : Ari<any>
>anys.filter(Bullean) : Ari<any>
>anys.filter : { <S extends any>(cb1: (value: any) => value is S): Ari<any>; (cb2: (value: any) => unknown): Ari<any>; }
>anys : Ari<any>
>filter : { <S extends any>(cb1: (value: any) => value is S): Ari<any>; (cb2: (value: any) => unknown): Ari<any>; }
>Bullean : BulleanConstructor
declare let realanys: any[];
>realanys : any[]
var ys: any[];
>ys : any[]
var ys = realanys.filter(Boolean)
>ys : any[]
>realanys.filter(Boolean) : any[]
>realanys.filter : { <S extends any>(callbackfn: (value: any, index: number, array: any[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: any, index: number, array: any[]) => unknown, thisArg?: any): any[]; }
>realanys : any[]
>filter : { <S extends any>(callbackfn: (value: any, index: number, array: any[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: any, index: number, array: any[]) => unknown, thisArg?: any): any[]; }
>Boolean : BooleanConstructor
var foo = [{ name: 'x' }]
>foo : { name: string; }[]
>[{ name: 'x' }] : { name: string; }[]
>{ name: 'x' } : { name: string; }
>name : string
>'x' : "x"
var foor: Array<{name: string}>
>foor : { name: string; }[]
>name : string
var foor = foo.filter(x => x.name)
>foor : { name: string; }[]
>foo.filter(x => x.name) : { name: string; }[]
>foo.filter : { <S extends { name: string; }>(callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => unknown, thisArg?: any): { name: string; }[]; }
>foo : { name: string; }[]
>filter : { <S extends { name: string; }>(callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: { name: string; }, index: number, array: { name: string; }[]) => unknown, thisArg?: any): { name: string; }[]; }
>x => x.name : (x: { name: string; }) => string
>x : { name: string; }
>x.name : string
>x : { name: string; }
>name : string
var foos: Array<boolean>
>foos : boolean[]
var foos = [true, true, false, null].filter((thing): thing is boolean => thing !== null)
>foos : boolean[]
>[true, true, false, null].filter((thing): thing is boolean => thing !== null) : boolean[]
>[true, true, false, null].filter : { <S extends boolean>(callbackfn: (value: boolean, index: number, array: boolean[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: boolean, index: number, array: boolean[]) => unknown, thisArg?: any): boolean[]; }
>[true, true, false, null] : boolean[]
>true : true
>true : true
>false : false
>null : null
>filter : { <S extends boolean>(callbackfn: (value: boolean, index: number, array: boolean[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: boolean, index: number, array: boolean[]) => unknown, thisArg?: any): boolean[]; }
>(thing): thing is boolean => thing !== null : (thing: boolean) => thing is boolean
>thing : boolean
>thing !== null : boolean
>thing : boolean
>null : null
@@ -71,6 +71,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot
var array1 = <number[]>numStrTuple;
~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'.
!!! related TS6203 tests/cases/conformance/types/tuple/castingTuple.ts:23:5: 'array1' was also declared here.
t4[2] = 10;
~~
!!! error TS2304: Cannot find name 't4'.
@@ -15,6 +15,7 @@ tests/cases/compiler/global.d.ts(6,16): error TS2403: Subsequent variable declar
export const THREE: typeof _three;
~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'THREE' must be of type 'typeof import("tests/cases/compiler/global")', but here has type 'typeof import("tests/cases/compiler/three")'.
!!! related TS6203 tests/cases/compiler/global.d.ts:1:1: 'THREE' was also declared here.
}
==== tests/cases/compiler/test.ts (0 errors) ====
@@ -11,22 +11,28 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin
Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | (TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[keyof GetProps<C> & string] | (TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P] : GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'TInjectedProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'TInjectedProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'TInjectedProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[keyof GetProps<C> & string] | (TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P] : GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
==== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ====
@@ -107,20 +113,26 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin
!!! error TS2344: Type 'GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type '(Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]) | (Extract<number, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<number, keyof GetProps<C>>] : GetProps<C>[Extract<number, keyof GetProps<C>>]) | (Extract<symbol, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<symbol, keyof GetProps<C>>] : GetProps<C>[Extract<symbol, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[Extract<string, keyof GetProps<C>>] | (TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[keyof GetProps<C> & string] | (TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P] : GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]) | GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] | GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'TInjectedProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'TInjectedProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'TInjectedProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[keyof GetProps<C> & string] | (TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[string]' is not assignable to type '(TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never) | undefined'.
!!! error TS2344: Type 'GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps<C>[keyof TInjectedProps & string] ? GetProps<C>[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps<C>[string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'keyof GetProps<C> & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] extends GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] ? GetProps<C>[keyof TInjectedProps & keyof GetProps<C> & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps<C> & string] : GetProps<C>[keyof GetProps<C> & string]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'Extract<string, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] extends GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] ? GetProps<C>[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : TInjectedProps[keyof TInjectedProps & Extract<string, keyof GetProps<C>>] : GetProps<C>[Extract<string, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'Extract<keyof TInjectedProps, keyof GetProps<C>> extends keyof TInjectedProps ? TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] extends GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] ? GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>] : TInjectedProps[Extract<keyof TInjectedProps, keyof GetProps<C>>] : GetProps<C>[Extract<keyof TInjectedProps, keyof GetProps<C>>]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : TInjectedProps[P] : GetProps<C>[P]' is not assignable to type 'TInjectedProps[P] extends GetProps<C>[P] ? GetProps<C>[P] : never'.
@@ -14,6 +14,7 @@ tests/cases/compiler/classWithDuplicateIdentifier.ts(11,5): error TS2717: Subseq
!!! error TS2300: Duplicate identifier 'a'.
~
!!! error TS2717: Subsequent property declarations must have the same type. Property 'a' must be of type '() => number', but here has type 'number'.
!!! related TS6203 tests/cases/compiler/classWithDuplicateIdentifier.ts:2:5: 'a' was also declared here.
}
class K {
b: number; // error: duplicate identifier
@@ -30,5 +31,6 @@ tests/cases/compiler/classWithDuplicateIdentifier.ts(11,5): error TS2717: Subseq
!!! error TS2300: Duplicate identifier 'c'.
~
!!! error TS2717: Subsequent property declarations must have the same type. Property 'c' must be of type 'number', but here has type 'string'.
!!! related TS6203 tests/cases/compiler/classWithDuplicateIdentifier.ts:10:5: 'c' was also declared here.
}
@@ -0,0 +1,8 @@
//// [index.js]
module.exports = {}
var x = 1
//// [index.js]
module.exports = {};
var x = 1;
@@ -0,0 +1,9 @@
=== tests/cases/compiler/index.js ===
module.exports = {}
>module.exports : Symbol("tests/cases/compiler/index", Decl(index.js, 0, 0))
>module : Symbol(module, Decl(index.js, 0, 0))
>exports : Symbol("tests/cases/compiler/index", Decl(index.js, 0, 0))
var x = 1
>x : Symbol(x, Decl(index.js, 1, 3))
@@ -0,0 +1,12 @@
=== tests/cases/compiler/index.js ===
module.exports = {}
>module.exports = {} : typeof import("tests/cases/compiler/index")
>module.exports : typeof import("tests/cases/compiler/index")
>module : { "tests/cases/compiler/index": typeof import("tests/cases/compiler/index"); }
>exports : typeof import("tests/cases/compiler/index")
>{} : {}
var x = 1
>x : number
>1 : 1
@@ -391,6 +391,7 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
var z: T2; // Error, T2 is distributive, T1 isn't
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo<T & U>'.
!!! related TS6203 tests/cases/conformance/types/conditional/conditionalTypes1.ts:262:9: 'z' was also declared here.
}
function f33<T, U>() {
@@ -645,7 +645,7 @@ declare type T82 = Eq2<false, true>;
declare type T83 = Eq2<false, false>;
declare type Foo<T> = T extends string ? boolean : number;
declare type Bar<T> = T extends string ? boolean : number;
declare const convert: <U>(value: Foo<U>) => Foo<U>;
declare const convert: <U>(value: Foo<U>) => Bar<U>;
declare type Baz<T> = Foo<T>;
declare const convert2: <T>(value: Foo<T>) => Foo<T>;
declare function f31<T>(): void;
@@ -779,8 +779,8 @@ type Bar<T> = T extends string ? boolean : number;
>Bar : Bar<T>
const convert = <U>(value: Foo<U>): Bar<U> => value;
>convert : <U>(value: Foo<U>) => Foo<U>
><U>(value: Foo<U>): Bar<U> => value : <U>(value: Foo<U>) => Foo<U>
>convert : <U>(value: Foo<U>) => Bar<U>
><U>(value: Foo<U>): Bar<U> => value : <U>(value: Foo<U>) => Bar<U>
>value : Foo<U>
>value : Foo<U>
@@ -832,7 +832,7 @@ function f33<T, U>() {
>T1 : Foo<T & U>
type T2 = Bar<T & U>;
>T2 : Foo<T & U>
>T2 : Bar<T & U>
var z: T1;
>z : Foo<T & U>
@@ -267,4 +267,10 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
};
type PCCA = ProductComplementComplement['a'];
type PCCB = ProductComplementComplement['b'];
// Repro from #31326
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
type What = Hmm<{}, { a: string }>
const w: What = { a: 4 };
@@ -188,6 +188,12 @@ type ProductComplementComplement = {
};
type PCCA = ProductComplementComplement['a'];
type PCCB = ProductComplementComplement['b'];
// Repro from #31326
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
type What = Hmm<{}, { a: string }>
const w: What = { a: 4 };
//// [conditionalTypes2.js]
@@ -265,6 +271,7 @@ function foo(value) {
toString2(value);
}
}
var w = { a: 4 };
//// [conditionalTypes2.d.ts]
@@ -392,3 +399,10 @@ declare type ProductComplementComplement = {
};
declare type PCCA = ProductComplementComplement['a'];
declare type PCCB = ProductComplementComplement['b'];
declare type Hmm<T, U extends T> = U extends T ? {
[K in keyof U]: number;
} : never;
declare type What = Hmm<{}, {
a: string;
}>;
declare const w: What;
@@ -685,3 +685,25 @@ type PCCB = ProductComplementComplement['b'];
>PCCB : Symbol(PCCB, Decl(conditionalTypes2.ts, 187, 45))
>ProductComplementComplement : Symbol(ProductComplementComplement, Decl(conditionalTypes2.ts, 181, 34))
// Repro from #31326
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
>Hmm : Symbol(Hmm, Decl(conditionalTypes2.ts, 188, 45))
>T : Symbol(T, Decl(conditionalTypes2.ts, 192, 9))
>U : Symbol(U, Decl(conditionalTypes2.ts, 192, 11))
>T : Symbol(T, Decl(conditionalTypes2.ts, 192, 9))
>U : Symbol(U, Decl(conditionalTypes2.ts, 192, 11))
>T : Symbol(T, Decl(conditionalTypes2.ts, 192, 9))
>K : Symbol(K, Decl(conditionalTypes2.ts, 192, 44))
>U : Symbol(U, Decl(conditionalTypes2.ts, 192, 11))
type What = Hmm<{}, { a: string }>
>What : Symbol(What, Decl(conditionalTypes2.ts, 192, 76))
>Hmm : Symbol(Hmm, Decl(conditionalTypes2.ts, 188, 45))
>a : Symbol(a, Decl(conditionalTypes2.ts, 193, 21))
const w: What = { a: 4 };
>w : Symbol(w, Decl(conditionalTypes2.ts, 194, 5))
>What : Symbol(What, Decl(conditionalTypes2.ts, 192, 76))
>a : Symbol(a, Decl(conditionalTypes2.ts, 194, 17))
@@ -431,3 +431,18 @@ type PCCA = ProductComplementComplement['a'];
type PCCB = ProductComplementComplement['b'];
>PCCB : Product<"b", 1>
// Repro from #31326
type Hmm<T, U extends T> = U extends T ? { [K in keyof U]: number } : never;
>Hmm : Hmm<T, U>
type What = Hmm<{}, { a: string }>
>What : { a: number; }
>a : string
const w: What = { a: 4 };
>w : { a: number; }
>{ a: 4 } : { a: number; }
>a : number
>4 : 4
@@ -1,49 +1,49 @@
=== tests/cases/compiler/conditionalTypesSimplifyWhenTrivial.ts ===
const fn1 = <Params>(
>fn1 : <Params>(params: Pick<Params, keyof Params>) => Params
><Params>( params: Pick<Params, Exclude<keyof Params, never>>,): Params => params : <Params>(params: Pick<Params, keyof Params>) => Params
>fn1 : <Params>(params: Pick<Params, Exclude<keyof Params, never>>) => Params
><Params>( params: Pick<Params, Exclude<keyof Params, never>>,): Params => params : <Params>(params: Pick<Params, Exclude<keyof Params, never>>) => Params
params: Pick<Params, Exclude<keyof Params, never>>,
>params : Pick<Params, keyof Params>
>params : Pick<Params, Exclude<keyof Params, never>>
): Params => params;
>params : Pick<Params, keyof Params>
>params : Pick<Params, Exclude<keyof Params, never>>
function fn2<T>(x: Exclude<T, never>) {
>fn2 : <T>(x: T) => void
>x : T
>fn2 : <T>(x: Exclude<T, never>) => void
>x : Exclude<T, never>
var y: T = x;
>y : T
>x : T
>x : Exclude<T, never>
x = y;
>x = y : T
>x : T
>x : Exclude<T, never>
>y : T
}
const fn3 = <Params>(
>fn3 : <Params>(params: Pick<Params, keyof Params>) => Params
><Params>( params: Pick<Params, Extract<keyof Params, keyof Params>>,): Params => params : <Params>(params: Pick<Params, keyof Params>) => Params
>fn3 : <Params>(params: Pick<Params, Extract<keyof Params, keyof Params>>) => Params
><Params>( params: Pick<Params, Extract<keyof Params, keyof Params>>,): Params => params : <Params>(params: Pick<Params, Extract<keyof Params, keyof Params>>) => Params
params: Pick<Params, Extract<keyof Params, keyof Params>>,
>params : Pick<Params, keyof Params>
>params : Pick<Params, Extract<keyof Params, keyof Params>>
): Params => params;
>params : Pick<Params, keyof Params>
>params : Pick<Params, Extract<keyof Params, keyof Params>>
function fn4<T>(x: Extract<T, T>) {
>fn4 : <T>(x: T) => void
>x : T
>fn4 : <T>(x: Extract<T, T>) => void
>x : Extract<T, T>
var y: T = x;
>y : T
>x : T
>x : Extract<T, T>
x = y;
>x = y : T
>x : T
>x : Extract<T, T>
>y : T
}
@@ -57,50 +57,50 @@ type ExcludeWithDefault<T, U, D = never> = T extends U ? D : T;
>ExcludeWithDefault : ExcludeWithDefault<T, U, D>
const fn5 = <Params>(
>fn5 : <Params>(params: Pick<Params, keyof Params>) => Params
><Params>( params: Pick<Params, ExcludeWithDefault<keyof Params, never>>,): Params => params : <Params>(params: Pick<Params, keyof Params>) => Params
>fn5 : <Params>(params: Pick<Params, ExcludeWithDefault<keyof Params, never, never>>) => Params
><Params>( params: Pick<Params, ExcludeWithDefault<keyof Params, never>>,): Params => params : <Params>(params: Pick<Params, ExcludeWithDefault<keyof Params, never, never>>) => Params
params: Pick<Params, ExcludeWithDefault<keyof Params, never>>,
>params : Pick<Params, keyof Params>
>params : Pick<Params, ExcludeWithDefault<keyof Params, never, never>>
): Params => params;
>params : Pick<Params, keyof Params>
>params : Pick<Params, ExcludeWithDefault<keyof Params, never, never>>
function fn6<T>(x: ExcludeWithDefault<T, never>) {
>fn6 : <T>(x: T) => void
>x : T
>fn6 : <T>(x: ExcludeWithDefault<T, never, never>) => void
>x : ExcludeWithDefault<T, never, never>
var y: T = x;
>y : T
>x : T
>x : ExcludeWithDefault<T, never, never>
x = y;
>x = y : T
>x : T
>x : ExcludeWithDefault<T, never, never>
>y : T
}
const fn7 = <Params>(
>fn7 : <Params>(params: Pick<Params, keyof Params>) => Params
><Params>( params: Pick<Params, ExtractWithDefault<keyof Params, keyof Params>>,): Params => params : <Params>(params: Pick<Params, keyof Params>) => Params
>fn7 : <Params>(params: Pick<Params, ExtractWithDefault<keyof Params, keyof Params, never>>) => Params
><Params>( params: Pick<Params, ExtractWithDefault<keyof Params, keyof Params>>,): Params => params : <Params>(params: Pick<Params, ExtractWithDefault<keyof Params, keyof Params, never>>) => Params
params: Pick<Params, ExtractWithDefault<keyof Params, keyof Params>>,
>params : Pick<Params, keyof Params>
>params : Pick<Params, ExtractWithDefault<keyof Params, keyof Params, never>>
): Params => params;
>params : Pick<Params, keyof Params>
>params : Pick<Params, ExtractWithDefault<keyof Params, keyof Params, never>>
function fn8<T>(x: ExtractWithDefault<T, T>) {
>fn8 : <T>(x: T) => void
>x : T
>fn8 : <T>(x: ExtractWithDefault<T, T, never>) => void
>x : ExtractWithDefault<T, T, never>
var y: T = x;
>y : T
>x : T
>x : ExtractWithDefault<T, T, never>
x = y;
>x = y : T
>x : T
>x : ExtractWithDefault<T, T, never>
>y : T
}
@@ -108,50 +108,50 @@ type TemplatedConditional<TCheck, TExtends, TTrue, TFalse> = TCheck extends TExt
>TemplatedConditional : TemplatedConditional<TCheck, TExtends, TTrue, TFalse>
const fn9 = <Params>(
>fn9 : <Params>(params: Pick<Params, keyof Params>) => Params
><Params>( params: Pick<Params, TemplatedConditional<keyof Params, never, never, keyof Params>>,): Params => params : <Params>(params: Pick<Params, keyof Params>) => Params
>fn9 : <Params>(params: Pick<Params, TemplatedConditional<keyof Params, never, never, keyof Params>>) => Params
><Params>( params: Pick<Params, TemplatedConditional<keyof Params, never, never, keyof Params>>,): Params => params : <Params>(params: Pick<Params, TemplatedConditional<keyof Params, never, never, keyof Params>>) => Params
params: Pick<Params, TemplatedConditional<keyof Params, never, never, keyof Params>>,
>params : Pick<Params, keyof Params>
>params : Pick<Params, TemplatedConditional<keyof Params, never, never, keyof Params>>
): Params => params;
>params : Pick<Params, keyof Params>
>params : Pick<Params, TemplatedConditional<keyof Params, never, never, keyof Params>>
function fn10<T>(x: TemplatedConditional<T, never, never, T>) {
>fn10 : <T>(x: T) => void
>x : T
>fn10 : <T>(x: TemplatedConditional<T, never, never, T>) => void
>x : TemplatedConditional<T, never, never, T>
var y: T = x;
>y : T
>x : T
>x : TemplatedConditional<T, never, never, T>
x = y;
>x = y : T
>x : T
>x : TemplatedConditional<T, never, never, T>
>y : T
}
const fn11 = <Params>(
>fn11 : <Params>(params: Pick<Params, keyof Params>) => Params
><Params>( params: Pick<Params, TemplatedConditional<keyof Params, keyof Params, keyof Params, never>>,): Params => params : <Params>(params: Pick<Params, keyof Params>) => Params
>fn11 : <Params>(params: Pick<Params, TemplatedConditional<keyof Params, keyof Params, keyof Params, never>>) => Params
><Params>( params: Pick<Params, TemplatedConditional<keyof Params, keyof Params, keyof Params, never>>,): Params => params : <Params>(params: Pick<Params, TemplatedConditional<keyof Params, keyof Params, keyof Params, never>>) => Params
params: Pick<Params, TemplatedConditional<keyof Params, keyof Params, keyof Params, never>>,
>params : Pick<Params, keyof Params>
>params : Pick<Params, TemplatedConditional<keyof Params, keyof Params, keyof Params, never>>
): Params => params;
>params : Pick<Params, keyof Params>
>params : Pick<Params, TemplatedConditional<keyof Params, keyof Params, keyof Params, never>>
function fn12<T>(x: TemplatedConditional<T, T, T, never>) {
>fn12 : <T>(x: T) => void
>x : T
>fn12 : <T>(x: TemplatedConditional<T, T, T, never>) => void
>x : TemplatedConditional<T, T, T, never>
var y: T = x;
>y : T
>x : T
>x : TemplatedConditional<T, T, T, never>
x = y;
>x = y : T
>x : T
>x : TemplatedConditional<T, T, T, never>
>y : T
}
@@ -0,0 +1,25 @@
//// [contravariantTypeAliasInference.ts]
type Func1<T> = (x: T) => void;
type Func2<T> = ((x: T) => void) | undefined;
declare let f1: Func1<string>;
declare let f2: Func1<"a">;
declare function foo<T>(f1: Func1<T>, f2: Func1<T>): void;
foo(f1, f2);
declare let g1: Func2<string>;
declare let g2: Func2<"a">;
declare function bar<T>(g1: Func2<T>, g2: Func2<T>): void;
bar(f1, f2);
bar(g1, g2);
//// [contravariantTypeAliasInference.js]
"use strict";
foo(f1, f2);
bar(f1, f2);
bar(g1, g2);
@@ -0,0 +1,64 @@
=== tests/cases/compiler/contravariantTypeAliasInference.ts ===
type Func1<T> = (x: T) => void;
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 0, 11))
>x : Symbol(x, Decl(contravariantTypeAliasInference.ts, 0, 17))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 0, 11))
type Func2<T> = ((x: T) => void) | undefined;
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 1, 11))
>x : Symbol(x, Decl(contravariantTypeAliasInference.ts, 1, 18))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 1, 11))
declare let f1: Func1<string>;
>f1 : Symbol(f1, Decl(contravariantTypeAliasInference.ts, 3, 11))
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
declare let f2: Func1<"a">;
>f2 : Symbol(f2, Decl(contravariantTypeAliasInference.ts, 4, 11))
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
declare function foo<T>(f1: Func1<T>, f2: Func1<T>): void;
>foo : Symbol(foo, Decl(contravariantTypeAliasInference.ts, 4, 27))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 6, 21))
>f1 : Symbol(f1, Decl(contravariantTypeAliasInference.ts, 6, 24))
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 6, 21))
>f2 : Symbol(f2, Decl(contravariantTypeAliasInference.ts, 6, 37))
>Func1 : Symbol(Func1, Decl(contravariantTypeAliasInference.ts, 0, 0))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 6, 21))
foo(f1, f2);
>foo : Symbol(foo, Decl(contravariantTypeAliasInference.ts, 4, 27))
>f1 : Symbol(f1, Decl(contravariantTypeAliasInference.ts, 3, 11))
>f2 : Symbol(f2, Decl(contravariantTypeAliasInference.ts, 4, 11))
declare let g1: Func2<string>;
>g1 : Symbol(g1, Decl(contravariantTypeAliasInference.ts, 10, 11))
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
declare let g2: Func2<"a">;
>g2 : Symbol(g2, Decl(contravariantTypeAliasInference.ts, 11, 11))
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
declare function bar<T>(g1: Func2<T>, g2: Func2<T>): void;
>bar : Symbol(bar, Decl(contravariantTypeAliasInference.ts, 11, 27))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 13, 21))
>g1 : Symbol(g1, Decl(contravariantTypeAliasInference.ts, 13, 24))
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 13, 21))
>g2 : Symbol(g2, Decl(contravariantTypeAliasInference.ts, 13, 37))
>Func2 : Symbol(Func2, Decl(contravariantTypeAliasInference.ts, 0, 31))
>T : Symbol(T, Decl(contravariantTypeAliasInference.ts, 13, 21))
bar(f1, f2);
>bar : Symbol(bar, Decl(contravariantTypeAliasInference.ts, 11, 27))
>f1 : Symbol(f1, Decl(contravariantTypeAliasInference.ts, 3, 11))
>f2 : Symbol(f2, Decl(contravariantTypeAliasInference.ts, 4, 11))
bar(g1, g2);
>bar : Symbol(bar, Decl(contravariantTypeAliasInference.ts, 11, 27))
>g1 : Symbol(g1, Decl(contravariantTypeAliasInference.ts, 10, 11))
>g2 : Symbol(g2, Decl(contravariantTypeAliasInference.ts, 11, 11))
@@ -0,0 +1,49 @@
=== tests/cases/compiler/contravariantTypeAliasInference.ts ===
type Func1<T> = (x: T) => void;
>Func1 : Func1<T>
>x : T
type Func2<T> = ((x: T) => void) | undefined;
>Func2 : Func2<T>
>x : T
declare let f1: Func1<string>;
>f1 : Func1<string>
declare let f2: Func1<"a">;
>f2 : Func1<"a">
declare function foo<T>(f1: Func1<T>, f2: Func1<T>): void;
>foo : <T>(f1: Func1<T>, f2: Func1<T>) => void
>f1 : Func1<T>
>f2 : Func1<T>
foo(f1, f2);
>foo(f1, f2) : void
>foo : <T>(f1: Func1<T>, f2: Func1<T>) => void
>f1 : Func1<string>
>f2 : Func1<"a">
declare let g1: Func2<string>;
>g1 : Func2<string>
declare let g2: Func2<"a">;
>g2 : Func2<"a">
declare function bar<T>(g1: Func2<T>, g2: Func2<T>): void;
>bar : <T>(g1: Func2<T>, g2: Func2<T>) => void
>g1 : Func2<T>
>g2 : Func2<T>
bar(f1, f2);
>bar(f1, f2) : void
>bar : <T>(g1: Func2<T>, g2: Func2<T>) => void
>f1 : Func1<string>
>f2 : Func1<"a">
bar(g1, g2);
>bar(g1, g2) : void
>bar : <T>(g1: Func2<T>, g2: Func2<T>) => void
>g1 : Func2<string>
>g2 : Func2<"a">
@@ -0,0 +1,36 @@
//// [controlFlowForCompoundAssignmentToThisMember.ts]
class DatasourceCommandWidgetElement {
_commandBased: boolean;
_commandElement: unknown;
commandElement: unknown;
constructor(target: unknown) {
if (target instanceof DatasourceCommandWidgetElement) {
this._commandBased = true;
this._commandElement = target.commandElement;
} else {
this._commandBased = false;
}
if (this._commandBased = (target instanceof DatasourceCommandWidgetElement)) {
this._commandElement = target.commandElement;
}
}
}
//// [controlFlowForCompoundAssignmentToThisMember.js]
var DatasourceCommandWidgetElement = /** @class */ (function () {
function DatasourceCommandWidgetElement(target) {
if (target instanceof DatasourceCommandWidgetElement) {
this._commandBased = true;
this._commandElement = target.commandElement;
}
else {
this._commandBased = false;
}
if (this._commandBased = (target instanceof DatasourceCommandWidgetElement)) {
this._commandElement = target.commandElement;
}
}
return DatasourceCommandWidgetElement;
}());
@@ -0,0 +1,57 @@
=== tests/cases/compiler/controlFlowForCompoundAssignmentToThisMember.ts ===
class DatasourceCommandWidgetElement {
>DatasourceCommandWidgetElement : Symbol(DatasourceCommandWidgetElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 0))
_commandBased: boolean;
>_commandBased : Symbol(DatasourceCommandWidgetElement._commandBased, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 38))
_commandElement: unknown;
>_commandElement : Symbol(DatasourceCommandWidgetElement._commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 1, 27))
commandElement: unknown;
>commandElement : Symbol(DatasourceCommandWidgetElement.commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 2, 29))
constructor(target: unknown) {
>target : Symbol(target, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 5, 16))
if (target instanceof DatasourceCommandWidgetElement) {
>target : Symbol(target, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 5, 16))
>DatasourceCommandWidgetElement : Symbol(DatasourceCommandWidgetElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 0))
this._commandBased = true;
>this._commandBased : Symbol(DatasourceCommandWidgetElement._commandBased, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 38))
>this : Symbol(DatasourceCommandWidgetElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 0))
>_commandBased : Symbol(DatasourceCommandWidgetElement._commandBased, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 38))
this._commandElement = target.commandElement;
>this._commandElement : Symbol(DatasourceCommandWidgetElement._commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 1, 27))
>this : Symbol(DatasourceCommandWidgetElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 0))
>_commandElement : Symbol(DatasourceCommandWidgetElement._commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 1, 27))
>target.commandElement : Symbol(DatasourceCommandWidgetElement.commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 2, 29))
>target : Symbol(target, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 5, 16))
>commandElement : Symbol(DatasourceCommandWidgetElement.commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 2, 29))
} else {
this._commandBased = false;
>this._commandBased : Symbol(DatasourceCommandWidgetElement._commandBased, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 38))
>this : Symbol(DatasourceCommandWidgetElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 0))
>_commandBased : Symbol(DatasourceCommandWidgetElement._commandBased, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 38))
}
if (this._commandBased = (target instanceof DatasourceCommandWidgetElement)) {
>this._commandBased : Symbol(DatasourceCommandWidgetElement._commandBased, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 38))
>this : Symbol(DatasourceCommandWidgetElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 0))
>_commandBased : Symbol(DatasourceCommandWidgetElement._commandBased, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 38))
>target : Symbol(target, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 5, 16))
>DatasourceCommandWidgetElement : Symbol(DatasourceCommandWidgetElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 0))
this._commandElement = target.commandElement;
>this._commandElement : Symbol(DatasourceCommandWidgetElement._commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 1, 27))
>this : Symbol(DatasourceCommandWidgetElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 0, 0))
>_commandElement : Symbol(DatasourceCommandWidgetElement._commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 1, 27))
>target.commandElement : Symbol(DatasourceCommandWidgetElement.commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 2, 29))
>target : Symbol(target, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 5, 16))
>commandElement : Symbol(DatasourceCommandWidgetElement.commandElement, Decl(controlFlowForCompoundAssignmentToThisMember.ts, 2, 29))
}
}
}
@@ -0,0 +1,67 @@
=== tests/cases/compiler/controlFlowForCompoundAssignmentToThisMember.ts ===
class DatasourceCommandWidgetElement {
>DatasourceCommandWidgetElement : DatasourceCommandWidgetElement
_commandBased: boolean;
>_commandBased : boolean
_commandElement: unknown;
>_commandElement : unknown
commandElement: unknown;
>commandElement : unknown
constructor(target: unknown) {
>target : unknown
if (target instanceof DatasourceCommandWidgetElement) {
>target instanceof DatasourceCommandWidgetElement : boolean
>target : unknown
>DatasourceCommandWidgetElement : typeof DatasourceCommandWidgetElement
this._commandBased = true;
>this._commandBased = true : true
>this._commandBased : boolean
>this : this
>_commandBased : boolean
>true : true
this._commandElement = target.commandElement;
>this._commandElement = target.commandElement : unknown
>this._commandElement : unknown
>this : this
>_commandElement : unknown
>target.commandElement : unknown
>target : DatasourceCommandWidgetElement
>commandElement : unknown
} else {
this._commandBased = false;
>this._commandBased = false : false
>this._commandBased : boolean
>this : this
>_commandBased : boolean
>false : false
}
if (this._commandBased = (target instanceof DatasourceCommandWidgetElement)) {
>this._commandBased = (target instanceof DatasourceCommandWidgetElement) : boolean
>this._commandBased : boolean
>this : this
>_commandBased : boolean
>(target instanceof DatasourceCommandWidgetElement) : boolean
>target instanceof DatasourceCommandWidgetElement : boolean
>target : unknown
>DatasourceCommandWidgetElement : typeof DatasourceCommandWidgetElement
this._commandElement = target.commandElement;
>this._commandElement = target.commandElement : unknown
>this._commandElement : unknown
>this : this
>_commandElement : unknown
>target.commandElement : unknown
>target : DatasourceCommandWidgetElement
>commandElement : unknown
}
}
}
@@ -111,7 +111,7 @@ function f5() {
>x : string
y; // string | undefined
>y : string | undefined
>y : string
}
else {
x; // string | undefined
@@ -0,0 +1,45 @@
//// [tests/cases/compiler/declarationEmitForGlobalishSpecifierSymlink.ts] ////
//// [impl.d.ts]
export function getA(): A;
export enum A {
Val
}
//// [index.d.ts]
export * from "./src/impl";
//// [package.json]
{
"name": "typescript-fsa",
"version": "1.0.0"
}
//// [impl.d.ts]
export function getA(): A;
export enum A {
Val
}
//// [index.d.ts]
export * from "./src/impl";
//// [package.json]
{
"name": "typescript-fsa",
"version": "1.0.0"
}
//// [index.ts]
import * as _whatever from "p2";
import { getA } from "typescript-fsa";
export const a = getA();
//// [index.d.ts]
export const a: import("typescript-fsa").A;
//// [index.js]
"use strict";
exports.__esModule = true;
var typescript_fsa_1 = require("typescript-fsa");
exports.a = typescript_fsa_1.getA();
//// [index.d.ts]
export declare const a: import("typescript-fsa").A;
@@ -0,0 +1,43 @@
=== /p1/node_modules/typescript-fsa/src/impl.d.ts ===
export function getA(): A;
>getA : Symbol(getA, Decl(impl.d.ts, 0, 0))
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
export enum A {
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
Val
>Val : Symbol(A.Val, Decl(impl.d.ts, 1, 15))
}
=== /p1/node_modules/typescript-fsa/index.d.ts ===
export * from "./src/impl";
No type information for this code.=== /p2/node_modules/typescript-fsa/src/impl.d.ts ===
export function getA(): A;
>getA : Symbol(getA, Decl(impl.d.ts, 0, 0))
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
export enum A {
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
Val
>Val : Symbol(A.Val, Decl(impl.d.ts, 1, 15))
}
=== /p2/node_modules/typescript-fsa/index.d.ts ===
export * from "./src/impl";
No type information for this code.=== /p1/index.ts ===
import * as _whatever from "p2";
>_whatever : Symbol(_whatever, Decl(index.ts, 0, 6))
import { getA } from "typescript-fsa";
>getA : Symbol(getA, Decl(index.ts, 1, 8))
export const a = getA();
>a : Symbol(a, Decl(index.ts, 3, 12))
>getA : Symbol(getA, Decl(index.ts, 1, 8))
=== /p2/index.d.ts ===
export const a: import("typescript-fsa").A;
>a : Symbol(a, Decl(index.d.ts, 0, 12))
>A : Symbol(A, Decl(impl.d.ts, 0, 26))
@@ -0,0 +1,41 @@
=== /p1/node_modules/typescript-fsa/src/impl.d.ts ===
export function getA(): A;
>getA : () => A
export enum A {
>A : A
Val
>Val : A
}
=== /p1/node_modules/typescript-fsa/index.d.ts ===
export * from "./src/impl";
No type information for this code.=== /p2/node_modules/typescript-fsa/src/impl.d.ts ===
export function getA(): A;
>getA : () => A
export enum A {
>A : A
Val
>Val : A
}
=== /p2/node_modules/typescript-fsa/index.d.ts ===
export * from "./src/impl";
No type information for this code.=== /p1/index.ts ===
import * as _whatever from "p2";
>_whatever : typeof _whatever
import { getA } from "typescript-fsa";
>getA : () => import("/p1/node_modules/typescript-fsa/index").A
export const a = getA();
>a : import("/p1/node_modules/typescript-fsa/index").A
>getA() : import("/p1/node_modules/typescript-fsa/index").A
>getA : () => import("/p1/node_modules/typescript-fsa/index").A
=== /p2/index.d.ts ===
export const a: import("typescript-fsa").A;
>a : import("/p2/node_modules/typescript-fsa/index").A
@@ -0,0 +1,33 @@
//// [tests/cases/compiler/declarationEmitForGlobalishSpecifierSymlink2.ts] ////
//// [impl.d.ts]
export function getA(): A;
export enum A {
Val
}
//// [index.d.ts]
export * from "./src/impl";
//// [package.json]
{
"name": "typescript-fsa",
"version": "1.0.0"
}
//// [index.ts]
import * as _whatever from "p2";
import { getA } from "typescript-fsa";
export const a = getA();
//// [index.d.ts]
export const a: import("typescript-fsa").A;
//// [index.js]
"use strict";
exports.__esModule = true;
var typescript_fsa_1 = require("typescript-fsa");
exports.a = typescript_fsa_1.getA();
//// [index.d.ts]
export declare const a: import("typescript-fsa").A;

Some files were not shown because too many files have changed in this diff Show More