mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' of https://github.com/Microsoft/TypeScript into bug/29880
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
[](https://travis-ci.org/Microsoft/TypeScript)
|
||||
[](https://dev.azure.com/typescript/TypeScript/_build/latest?definitionId=4&view=logs)
|
||||
[](https://www.npmjs.com/package/typescript)
|
||||
[](https://www.npmjs.com/package/typescript)
|
||||
|
||||
# TypeScript
|
||||
|
||||
[](https://gitter.im/Microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/Microsoft/TypeScript)
|
||||
[](https://dev.azure.com/typescript/TypeScript/_build/latest?definitionId=4&view=logs)
|
||||
[](https://www.npmjs.com/package/typescript)
|
||||
[](https://www.npmjs.com/package/typescript)
|
||||
|
||||
|
||||
|
||||
[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).
|
||||
|
||||
@@ -28,14 +30,14 @@ npm install -g typescript@next
|
||||
There are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.
|
||||
* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.
|
||||
* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).
|
||||
* Engage with other TypeScript users and developers on [StackOverflow](https://stackoverflow.com/questions/tagged/typescript).
|
||||
* Engage with other TypeScript users and developers on [StackOverflow](https://stackoverflow.com/questions/tagged/typescript).
|
||||
* Join the [#typescript](https://twitter.com/search?q=%23TypeScript) discussion on Twitter.
|
||||
* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).
|
||||
* Read the language specification ([docx](https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.docx?raw=true),
|
||||
[pdf](https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf?raw=true), [md](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)).
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see
|
||||
the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com)
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see
|
||||
the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com)
|
||||
with any additional questions or comments.
|
||||
|
||||
## Documentation
|
||||
@@ -71,17 +73,17 @@ npm install
|
||||
Use one of the following to build and test:
|
||||
|
||||
```
|
||||
gulp local # Build the compiler into built/local
|
||||
gulp clean # Delete the built compiler
|
||||
gulp local # Build the compiler into built/local
|
||||
gulp clean # Delete the built compiler
|
||||
gulp LKG # Replace the last known good with the built one.
|
||||
# Bootstrapping step to be executed when the built compiler reaches a stable state.
|
||||
gulp tests # Build the test infrastructure using the built compiler.
|
||||
gulp runtests # Run tests using the built compiler and test infrastructure.
|
||||
# You can override the host or specify a test for this command.
|
||||
# Use --host=<hostName> or --tests=<testPath>.
|
||||
gulp tests # Build the test infrastructure using the built compiler.
|
||||
gulp runtests # Run tests using the built compiler and test infrastructure.
|
||||
# You can override the host or specify a test for this command.
|
||||
# Use --host=<hostName> or --tests=<testPath>.
|
||||
gulp baseline-accept # This replaces the baseline test results with the results obtained from gulp runtests.
|
||||
gulp lint # Runs tslint on the TypeScript source.
|
||||
gulp help # List the above commands.
|
||||
gulp help # List the above commands.
|
||||
```
|
||||
|
||||
|
||||
|
||||
+23
-17
@@ -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 {
|
||||
|
||||
+376
-234
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+4
-87
@@ -239,7 +239,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// When the deleted entry was the last one, we need to
|
||||
// adust the lastEntry reference.
|
||||
// adjust the lastEntry reference.
|
||||
if (this.lastEntry === entry) {
|
||||
this.lastEntry = previousEntry;
|
||||
}
|
||||
@@ -1255,7 +1255,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the only element of an array if it contains only one element; otheriwse, returns the
|
||||
* Returns the only element of an array if it contains only one element; otherwise, returns the
|
||||
* array.
|
||||
*/
|
||||
export function singleOrMany<T>(array: T[]): T | T[];
|
||||
@@ -1400,8 +1400,8 @@ namespace ts {
|
||||
/** Shims `Array.from`. */
|
||||
export function arrayFrom<T, U>(iterator: Iterator<T> | IterableIterator<T>, map: (t: T) => U): U[];
|
||||
export function arrayFrom<T>(iterator: Iterator<T> | IterableIterator<T>): T[];
|
||||
export function arrayFrom(iterator: Iterator<any> | IterableIterator<any>, map?: (t: any) => any): any[] {
|
||||
const result: any[] = [];
|
||||
export function arrayFrom<T, U>(iterator: Iterator<T> | IterableIterator<T>, map?: (t: T) => U): (T | U)[] {
|
||||
const result: (T | U)[] = [];
|
||||
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
|
||||
result.push(map ? map(value) : value);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -4962,7 +4978,20 @@
|
||||
"category": "Message",
|
||||
"code": 95076
|
||||
},
|
||||
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer." :{
|
||||
"Extract type": {
|
||||
"category": "Message",
|
||||
"code": 95077
|
||||
},
|
||||
"Extract to type alias": {
|
||||
"category": "Message",
|
||||
"code": 95078
|
||||
},
|
||||
"Extract to typedef": {
|
||||
"category": "Message",
|
||||
"code": 95079
|
||||
},
|
||||
|
||||
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
|
||||
"category": "Error",
|
||||
"code": 18004
|
||||
},
|
||||
|
||||
@@ -222,7 +222,7 @@ namespace ts {
|
||||
|
||||
/*@internal*/
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile | undefined, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<Bundle | SourceFile>[], declarationTransformers?: TransformerFactory<Bundle | SourceFile>[], onlyBuildInfo?: boolean): EmitResult {
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile | undefined, { scriptTransformers, declarationTransformers }: EmitTransformers, emitOnlyDtsFiles?: boolean, onlyBuildInfo?: boolean): EmitResult {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const sourceMapDataList: SourceMapEmitResult[] | undefined = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
|
||||
const emittedFilesList: string[] | undefined = compilerOptions.listEmittedFiles ? [] : undefined;
|
||||
@@ -303,7 +303,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
// Transform the source files
|
||||
const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], transformers!, /*allowDtsFiles*/ false);
|
||||
const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
|
||||
|
||||
const printerOptions: PrinterOptions = {
|
||||
removeComments: compilerOptions.removeComments,
|
||||
@@ -349,7 +349,7 @@ namespace ts {
|
||||
// Do that here when emitting only dts files
|
||||
nonJsFiles.forEach(collectLinkedAliases);
|
||||
}
|
||||
const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, concatenate([transformDeclarations], declarationTransformers), /*allowDtsFiles*/ false);
|
||||
const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
|
||||
if (length(declarationTransform.diagnostics)) {
|
||||
for (const diagnostic of declarationTransform.diagnostics!) {
|
||||
emitterDiagnostics.add(diagnostic);
|
||||
@@ -723,7 +723,7 @@ namespace ts {
|
||||
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
|
||||
getProgramBuildInfo: returnUndefined
|
||||
};
|
||||
emitFiles(notImplementedResolver, emitHost, /*targetSourceFile*/ undefined, /*emitOnlyDtsFiles*/ false, getTransformers(config.options));
|
||||
emitFiles(notImplementedResolver, emitHost, /*targetSourceFile*/ undefined, getTransformers(config.options), /*emitOnlyDtsFiles*/ false);
|
||||
return outputFiles;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1004,10 +1004,10 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createPropertyAccess(expression: Expression, name: string | Identifier | undefined) {
|
||||
export function createPropertyAccess(expression: Expression, name: string | Identifier) {
|
||||
const node = <PropertyAccessExpression>createSynthesizedNode(SyntaxKind.PropertyAccessExpression);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.name = asName(name)!; // TODO: GH#18217
|
||||
node.name = asName(name);
|
||||
setEmitFlags(node, EmitFlags.NoIndentation);
|
||||
return node;
|
||||
}
|
||||
@@ -2468,7 +2468,7 @@ namespace ts {
|
||||
|
||||
export function createSpreadAssignment(expression: Expression) {
|
||||
const node = <SpreadAssignment>createSynthesizedNode(SyntaxKind.SpreadAssignment);
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined!; // TODO: GH#18217
|
||||
node.expression = parenthesizeExpressionForList(expression);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -2949,7 +2949,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends: ReadonlyArray<UnparsedSource> = emptyArray) {
|
||||
export function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends: ReadonlyArray<UnparsedSource | InputFiles> = emptyArray) {
|
||||
if (node.sourceFiles !== sourceFiles || node.prepends !== prepends) {
|
||||
return createBundle(sourceFiles, prepends);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1328,6 +1328,8 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function createMissingNode<T extends Node>(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, arg0?: any): T;
|
||||
function createMissingNode<T extends Node>(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T;
|
||||
function createMissingNode<T extends Node>(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T {
|
||||
if (reportAtCurrentPosition) {
|
||||
parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
|
||||
@@ -3122,15 +3124,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseUnionOrIntersectionType(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, parseConstituentType: () => TypeNode, operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken): TypeNode {
|
||||
parseOptional(operator);
|
||||
const start = scanner.getStartPos();
|
||||
const hasLeadingOperator = parseOptional(operator);
|
||||
let type = parseConstituentType();
|
||||
if (token() === operator) {
|
||||
if (token() === operator || hasLeadingOperator) {
|
||||
const types = [type];
|
||||
while (parseOptional(operator)) {
|
||||
types.push(parseConstituentType());
|
||||
}
|
||||
const node = <UnionOrIntersectionTypeNode>createNode(kind, type.pos);
|
||||
node.types = createNodeArray(types, type.pos);
|
||||
const node = <UnionOrIntersectionTypeNode>createNode(kind, start);
|
||||
node.types = createNodeArray(types, start);
|
||||
type = finishNode(node);
|
||||
}
|
||||
return type;
|
||||
@@ -4290,7 +4293,7 @@ namespace ts {
|
||||
badNode.end = invalidElement.end;
|
||||
badNode.left = result;
|
||||
badNode.right = invalidElement;
|
||||
badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined!); // TODO: GH#18217
|
||||
badNode.operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false);
|
||||
badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
|
||||
return <JsxElement><Node>badNode;
|
||||
}
|
||||
|
||||
+13
-11
@@ -1453,9 +1453,8 @@ namespace ts {
|
||||
notImplementedResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
/*targetSourceFile*/ undefined,
|
||||
/*transformers*/ noTransformers,
|
||||
/*emitOnlyDtsFiles*/ false,
|
||||
/*transformers*/ undefined,
|
||||
/*declaraitonTransformers*/ undefined,
|
||||
/*onlyBuildInfo*/ true
|
||||
);
|
||||
|
||||
@@ -1574,14 +1573,12 @@ namespace ts {
|
||||
|
||||
performance.mark("beforeEmit");
|
||||
|
||||
const transformers = emitOnlyDtsFiles ? [] : getTransformers(options, customTransformers);
|
||||
const emitResult = emitFiles(
|
||||
emitResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile,
|
||||
getTransformers(options, customTransformers, emitOnlyDtsFiles),
|
||||
emitOnlyDtsFiles,
|
||||
transformers,
|
||||
customTransformers && customTransformers.afterDeclarations
|
||||
);
|
||||
|
||||
performance.mark("afterEmit");
|
||||
@@ -2235,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);
|
||||
}
|
||||
}
|
||||
@@ -2688,6 +2688,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
sourceFile = Debug.assertDefined(commandLine.options.configFile);
|
||||
Debug.assert(!sourceFile.path || sourceFile.path === sourceFilePath);
|
||||
addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
|
||||
}
|
||||
else {
|
||||
@@ -2699,11 +2700,12 @@ namespace ts {
|
||||
projectReferenceRedirects.set(sourceFilePath, false);
|
||||
return undefined;
|
||||
}
|
||||
sourceFile.path = sourceFilePath;
|
||||
sourceFile.resolvedPath = sourceFilePath;
|
||||
sourceFile.originalFileName = refPath;
|
||||
commandLine = parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
|
||||
}
|
||||
sourceFile.path = sourceFilePath;
|
||||
sourceFile.resolvedPath = sourceFilePath;
|
||||
sourceFile.originalFileName = refPath;
|
||||
|
||||
const resolvedRef: ResolvedProjectReference = { commandLine, sourceFile };
|
||||
projectReferenceRedirects.set(sourceFilePath, resolvedRef);
|
||||
if (commandLine.projectReferences) {
|
||||
@@ -2856,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,13 +24,24 @@ namespace ts {
|
||||
EmitNotifications = 1 << 1,
|
||||
}
|
||||
|
||||
export function getTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers) {
|
||||
export const noTransformers: EmitTransformers = { scriptTransformers: emptyArray, declarationTransformers: emptyArray };
|
||||
|
||||
export function getTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers, emitOnlyDtsFiles?: boolean): EmitTransformers {
|
||||
return {
|
||||
scriptTransformers: getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles),
|
||||
declarationTransformers: getDeclarationTransformers(customTransformers),
|
||||
};
|
||||
}
|
||||
|
||||
function getScriptTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers, emitOnlyDtsFiles?: boolean) {
|
||||
if (emitOnlyDtsFiles) return emptyArray;
|
||||
|
||||
const jsx = compilerOptions.jsx;
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
const transformers: TransformerFactory<SourceFile | Bundle>[] = [];
|
||||
|
||||
addRange(transformers, customTransformers && customTransformers.before);
|
||||
addRange(transformers, customTransformers && map(customTransformers.before, wrapScriptTransformerFactory));
|
||||
|
||||
transformers.push(transformTypeScript);
|
||||
|
||||
@@ -71,11 +82,44 @@ namespace ts {
|
||||
transformers.push(transformES5);
|
||||
}
|
||||
|
||||
addRange(transformers, customTransformers && customTransformers.after);
|
||||
|
||||
addRange(transformers, customTransformers && map(customTransformers.after, wrapScriptTransformerFactory));
|
||||
return transformers;
|
||||
}
|
||||
|
||||
function getDeclarationTransformers(customTransformers?: CustomTransformers) {
|
||||
const transformers: TransformerFactory<SourceFile | Bundle>[] = [];
|
||||
transformers.push(transformDeclarations);
|
||||
addRange(transformers, customTransformers && map(customTransformers.afterDeclarations, wrapDeclarationTransformerFactory));
|
||||
return transformers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a custom script or declaration transformer object in a `Transformer` callback with fallback support for transforming bundles.
|
||||
*/
|
||||
function wrapCustomTransformer(transformer: CustomTransformer): Transformer<Bundle | SourceFile> {
|
||||
return node => isBundle(node) ? transformer.transformBundle(node) : transformer.transformSourceFile(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a transformer factory that may return a custom script or declaration transformer object.
|
||||
*/
|
||||
function wrapCustomTransformerFactory<T extends SourceFile | Bundle>(transformer: TransformerFactory<T> | CustomTransformerFactory, handleDefault: (node: Transformer<T>) => Transformer<Bundle | SourceFile>): TransformerFactory<Bundle | SourceFile> {
|
||||
return context => {
|
||||
const customTransformer = transformer(context);
|
||||
return typeof customTransformer === "function"
|
||||
? handleDefault(customTransformer)
|
||||
: wrapCustomTransformer(customTransformer);
|
||||
};
|
||||
}
|
||||
|
||||
function wrapScriptTransformerFactory(transformer: TransformerFactory<SourceFile> | CustomTransformerFactory): TransformerFactory<Bundle | SourceFile> {
|
||||
return wrapCustomTransformerFactory(transformer, chainBundle);
|
||||
}
|
||||
|
||||
function wrapDeclarationTransformerFactory(transformer: TransformerFactory<Bundle | SourceFile> | CustomTransformerFactory): TransformerFactory<Bundle | SourceFile> {
|
||||
return wrapCustomTransformerFactory(transformer, identity);
|
||||
}
|
||||
|
||||
export function noEmitSubstitution(_hint: EmitHint, node: Node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -521,8 +521,10 @@ namespace ts {
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
|
||||
t[p[i]] = s[p[i]];
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};`
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -1639,7 +1640,7 @@ namespace ts {
|
||||
// arguments are both mapped contiguously to the accessor name.
|
||||
const target = getMutableClone(receiver);
|
||||
setEmitFlags(target, EmitFlags.NoComments | EmitFlags.NoTrailingSourceMap);
|
||||
setSourceMapRange(target, firstAccessor.name); // TODO: GH#18217
|
||||
setSourceMapRange(target, firstAccessor.name);
|
||||
|
||||
const propertyName = createExpressionForPropertyName(visitNode(firstAccessor.name, visitor, isPropertyName));
|
||||
setEmitFlags(propertyName, EmitFlags.NoComments | EmitFlags.NoLeadingSourceMap);
|
||||
@@ -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));
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
"files": [
|
||||
"core.ts",
|
||||
"debug.ts",
|
||||
"performance.ts",
|
||||
"semver.ts",
|
||||
|
||||
|
||||
+46
-23
@@ -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
|
||||
}
|
||||
@@ -2614,7 +2616,7 @@ namespace ts {
|
||||
|
||||
// Incomplete types occur during control flow analysis of loops. An IncompleteType
|
||||
// is distinguished from a regular type by a flags value of zero. Incomplete type
|
||||
// objects are internal to the getFlowTypeOfRefecence function and never escape it.
|
||||
// objects are internal to the getFlowTypeOfReference function and never escape it.
|
||||
export interface IncompleteType {
|
||||
flags: TypeFlags; // No flags set
|
||||
type: Type; // The type marked incomplete
|
||||
@@ -3011,13 +3013,26 @@ namespace ts {
|
||||
Completely = 1 << 1,
|
||||
}
|
||||
|
||||
export type CustomTransformerFactory = (context: TransformationContext) => CustomTransformer;
|
||||
|
||||
export interface CustomTransformer {
|
||||
transformSourceFile(node: SourceFile): SourceFile;
|
||||
transformBundle(node: Bundle): Bundle;
|
||||
}
|
||||
|
||||
export interface CustomTransformers {
|
||||
/** Custom transformers to evaluate before built-in .js transformations. */
|
||||
before?: TransformerFactory<SourceFile>[];
|
||||
before?: (TransformerFactory<SourceFile> | CustomTransformerFactory)[];
|
||||
/** Custom transformers to evaluate after built-in .js transformations. */
|
||||
after?: TransformerFactory<SourceFile>[];
|
||||
after?: (TransformerFactory<SourceFile> | CustomTransformerFactory)[];
|
||||
/** Custom transformers to evaluate after built-in .d.ts transformations. */
|
||||
afterDeclarations?: TransformerFactory<Bundle | SourceFile>[];
|
||||
afterDeclarations?: (TransformerFactory<Bundle | SourceFile> | CustomTransformerFactory)[];
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface EmitTransformers {
|
||||
scriptTransformers: readonly TransformerFactory<SourceFile | Bundle>[];
|
||||
declarationTransformers: readonly TransformerFactory<SourceFile | Bundle>[];
|
||||
}
|
||||
|
||||
export interface SourceMapSpan {
|
||||
@@ -3139,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;
|
||||
|
||||
@@ -3735,7 +3751,7 @@ namespace ts {
|
||||
specifierCache?: Map<string>; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings
|
||||
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?: Variance[]; // Alias symbol type argument variance cache
|
||||
variances?: VarianceFlags[]; // Alias symbol type argument variance cache
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3951,6 +3967,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,
|
||||
@@ -4131,12 +4149,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum Variance {
|
||||
Invariant = 0, // Neither covariant nor contravariant
|
||||
Covariant = 1, // Covariant
|
||||
Contravariant = 2, // Contravariant
|
||||
Bivariant = 3, // Both covariant and contravariant
|
||||
Independent = 4, // Unwitnessed type parameter
|
||||
export const enum VarianceFlags {
|
||||
Invariant = 0, // Neither covariant nor contravariant
|
||||
Covariant = 1 << 0, // Covariant
|
||||
Contravariant = 1 << 1, // Contravariant
|
||||
Bivariant = Covariant | Contravariant, // Both covariant and contravariant
|
||||
Independent = 1 << 2, // Unwitnessed type parameter
|
||||
VarianceMask = Invariant | Covariant | Contravariant | Independent, // Mask containing all measured variances without the unmeasurable flag
|
||||
Unmeasurable = 1 << 3, // Variance result is unusable - relationship relies on structural comparisons which are not reflected in generic relationships
|
||||
Unreliable = 1 << 4, // Variance result is unreliable - relationship relies on structural comparisons which are not reflected in generic relationships
|
||||
AllowsStructuralFallback = Unmeasurable | Unreliable,
|
||||
}
|
||||
|
||||
// Generic class and interface types
|
||||
@@ -4144,7 +4166,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
instantiations: Map<TypeReference>; // Generic instantiation cache
|
||||
/* @internal */
|
||||
variances?: Variance[]; // Variance of each type parameter
|
||||
variances?: VarianceFlags[]; // Variance of each type parameter
|
||||
}
|
||||
|
||||
export interface TupleType extends GenericType {
|
||||
@@ -4319,8 +4341,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 */
|
||||
@@ -4405,15 +4427,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 */
|
||||
@@ -5133,7 +5156,7 @@ namespace ts {
|
||||
createHash?(data: string): string;
|
||||
getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined;
|
||||
|
||||
// TODO: later handle this in better way in builder host instead once the api for tsbuild finalizes and doesnt use compilerHost as base
|
||||
// TODO: later handle this in better way in builder host instead once the api for tsbuild finalizes and doesn't use compilerHost as base
|
||||
/*@internal*/createDirectory?(directory: string): void;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
+130
-34
@@ -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)!;
|
||||
@@ -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
|
||||
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -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;
|
||||
|
||||
Vendored
+2
-4
@@ -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
|
||||
|
||||
Vendored
+2
-1
@@ -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;
|
||||
|
||||
+22
-1
@@ -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
@@ -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.");
|
||||
|
||||
+101
-23
@@ -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)
|
||||
@@ -78,7 +87,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 +116,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 +124,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 +147,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 +213,7 @@ namespace ts.Completions {
|
||||
name: realName,
|
||||
kind: ScriptElementKind.warning,
|
||||
kindModifiers: "",
|
||||
sortText: "1"
|
||||
sortText: SortText.JavascriptIdentifiers
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -169,28 +222,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 +278,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 +314,7 @@ namespace ts.Completions {
|
||||
isJsxInitializer?: IsJsxInitializer,
|
||||
recommendedCompletion?: Symbol,
|
||||
symbolToOriginInfoMap?: SymbolOriginInfoMap,
|
||||
symbolToSortTextMap?: SymbolSortTextMap,
|
||||
): Map<true> {
|
||||
const start = timestamp();
|
||||
// Tracks unique names.
|
||||
@@ -275,13 +324,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 +387,7 @@ namespace ts.Completions {
|
||||
name,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
kind: ScriptElementKind.label,
|
||||
sortText: "0"
|
||||
sortText: SortText.LocationPriority
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -358,7 +424,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 +578,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 +871,7 @@ namespace ts.Completions {
|
||||
let keywordFilters = KeywordCompletionFilters.None;
|
||||
let symbols: Symbol[] = [];
|
||||
const symbolToOriginInfoMap: SymbolOriginInfoMap = [];
|
||||
const symbolToSortTextMap: SymbolSortTextMap = [];
|
||||
|
||||
if (isRightOfDot) {
|
||||
getTypeScriptMemberSymbols();
|
||||
@@ -853,7 +921,8 @@ namespace ts.Completions {
|
||||
recommendedCompletion,
|
||||
previousToken,
|
||||
isJsxInitializer,
|
||||
insideJsDocTagTypeExpression
|
||||
insideJsDocTagTypeExpression,
|
||||
symbolToSortTextMap
|
||||
};
|
||||
|
||||
type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag;
|
||||
@@ -1057,6 +1126,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) {
|
||||
@@ -1065,6 +1140,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1198,6 +1274,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 };
|
||||
}
|
||||
|
||||
@@ -1223,6 +1300,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;
|
||||
}
|
||||
}
|
||||
@@ -1944,7 +2022,7 @@ namespace ts.Completions {
|
||||
name: tokenToString(i)!,
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
sortText: "0"
|
||||
sortText: SortText.GlobalsOrKeywords
|
||||
});
|
||||
}
|
||||
return res;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
/* @internal */
|
||||
namespace ts.refactor {
|
||||
const refactorName = "Extract type";
|
||||
const extractToTypeAlias = "Extract to type alias";
|
||||
const extractToTypeDef = "Extract to typedef";
|
||||
registerRefactor(refactorName, {
|
||||
getAvailableActions(context): ReadonlyArray<ApplicableRefactorInfo> {
|
||||
const info = getRangeToExtract(context);
|
||||
if (!info) return emptyArray;
|
||||
|
||||
return [{
|
||||
name: refactorName,
|
||||
description: getLocaleSpecificMessage(Diagnostics.Extract_type),
|
||||
actions: [info.isJS ? {
|
||||
name: extractToTypeDef, description: getLocaleSpecificMessage(Diagnostics.Extract_to_typedef)
|
||||
} : {
|
||||
name: extractToTypeAlias, description: getLocaleSpecificMessage(Diagnostics.Extract_to_type_alias)
|
||||
}]
|
||||
}];
|
||||
},
|
||||
getEditsForAction(context, actionName): RefactorEditInfo {
|
||||
Debug.assert(actionName === extractToTypeAlias || actionName === extractToTypeDef);
|
||||
const { file } = context;
|
||||
const info = Debug.assertDefined(getRangeToExtract(context));
|
||||
Debug.assert(actionName === extractToTypeAlias && !info.isJS || actionName === extractToTypeDef && info.isJS);
|
||||
|
||||
const name = getUniqueName("NewType", file);
|
||||
const edits = textChanges.ChangeTracker.with(context, changes => info.isJS ?
|
||||
doTypedefChange(changes, file, name, info.firstStatement, info.selection, info.typeParameters) :
|
||||
doTypeAliasChange(changes, file, name, info.firstStatement, info.selection, info.typeParameters));
|
||||
|
||||
const renameFilename = file.fileName;
|
||||
const renameLocation = getRenameLocation(edits, renameFilename, name, /*preferLastLocation*/ false);
|
||||
return { edits, renameFilename, renameLocation };
|
||||
}
|
||||
});
|
||||
|
||||
interface Info { isJS: boolean; selection: TypeNode; firstStatement: Statement; typeParameters: ReadonlyArray<TypeParameterDeclaration>; }
|
||||
|
||||
function getRangeToExtract(context: RefactorContext): Info | undefined {
|
||||
const { file, startPosition } = context;
|
||||
const isJS = isSourceFileJS(file);
|
||||
const current = getTokenAtPosition(file, startPosition);
|
||||
const range = createTextRangeFromSpan(getRefactorContextSpan(context));
|
||||
|
||||
const selection = findAncestor(current, (node => node.parent && rangeContainsSkipTrivia(range, node, file) && !rangeContainsSkipTrivia(range, node.parent, file)));
|
||||
if (!selection || !isTypeNode(selection)) return undefined;
|
||||
|
||||
const checker = context.program.getTypeChecker();
|
||||
const firstStatement = Debug.assertDefined(isJS ? findAncestor(selection, isStatementAndHasJSDoc) : findAncestor(selection, isStatement));
|
||||
const typeParameters = collectTypeParameters(checker, selection, firstStatement, file);
|
||||
if (!typeParameters) return undefined;
|
||||
|
||||
return { isJS, selection, firstStatement, typeParameters };
|
||||
}
|
||||
|
||||
function isStatementAndHasJSDoc(n: Node): n is (Statement & HasJSDoc) {
|
||||
return isStatement(n) && hasJSDocNodes(n);
|
||||
}
|
||||
|
||||
function rangeContainsSkipTrivia(r1: TextRange, node: Node, file: SourceFile): boolean {
|
||||
return rangeContainsStartEnd(r1, skipTrivia(file.text, node.pos), node.end);
|
||||
}
|
||||
|
||||
function collectTypeParameters(checker: TypeChecker, selection: TypeNode, statement: Statement, file: SourceFile): TypeParameterDeclaration[] | undefined {
|
||||
const result: TypeParameterDeclaration[] = [];
|
||||
return visitor(selection) ? undefined : result;
|
||||
|
||||
function visitor(node: Node): true | undefined {
|
||||
if (isTypeReferenceNode(node)) {
|
||||
if (isIdentifier(node.typeName)) {
|
||||
const symbol = checker.resolveName(node.typeName.text, node.typeName, SymbolFlags.TypeParameter, /* excludeGlobals */ true);
|
||||
if (symbol) {
|
||||
const declaration = cast(first(symbol.declarations), isTypeParameterDeclaration);
|
||||
if (rangeContainsSkipTrivia(statement, declaration, file) && !rangeContainsSkipTrivia(selection, declaration, file)) {
|
||||
result.push(declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isInferTypeNode(node)) {
|
||||
const conditionalTypeNode = findAncestor(node, n => isConditionalTypeNode(n) && rangeContainsSkipTrivia(n.extendsType, node, file));
|
||||
if (!conditionalTypeNode || !rangeContainsSkipTrivia(selection, conditionalTypeNode, file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if ((isTypePredicateNode(node) || isThisTypeNode(node))) {
|
||||
const functionLikeNode = findAncestor(node.parent, isFunctionLike);
|
||||
if (functionLikeNode && functionLikeNode.type && rangeContainsSkipTrivia(functionLikeNode.type, node, file) && !rangeContainsSkipTrivia(selection, functionLikeNode, file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (isTypeQueryNode(node)) {
|
||||
if (isIdentifier(node.exprName)) {
|
||||
const symbol = checker.resolveName(node.exprName.text, node.exprName, SymbolFlags.Value, /* excludeGlobals */ false);
|
||||
if (symbol && rangeContainsSkipTrivia(statement, symbol.valueDeclaration, file) && !rangeContainsSkipTrivia(selection, symbol.valueDeclaration, file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isThisIdentifier(node.exprName.left) && !rangeContainsSkipTrivia(selection, node.parent, file)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return forEachChild(node, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
function doTypeAliasChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, firstStatement: Statement, selection: TypeNode, typeParameters: ReadonlyArray<TypeParameterDeclaration>) {
|
||||
const newTypeNode = createTypeAliasDeclaration(
|
||||
/* decorators */ undefined,
|
||||
/* modifiers */ undefined,
|
||||
name,
|
||||
typeParameters.map(id => updateTypeParameterDeclaration(id, id.name, id.constraint, /* defaultType */ undefined)),
|
||||
selection
|
||||
);
|
||||
changes.insertNodeBefore(file, firstStatement, newTypeNode, /* blankLineBetween */ true);
|
||||
changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
|
||||
}
|
||||
|
||||
function doTypedefChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, firstStatement: Statement, selection: TypeNode, typeParameters: ReadonlyArray<TypeParameterDeclaration>) {
|
||||
const node = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag);
|
||||
node.tagName = createIdentifier("typedef"); // TODO: jsdoc factory https://github.com/Microsoft/TypeScript/pull/29539
|
||||
node.fullName = createIdentifier(name);
|
||||
node.name = node.fullName;
|
||||
node.typeExpression = createJSDocTypeExpression(selection);
|
||||
|
||||
const templates: JSDocTemplateTag[] = [];
|
||||
forEach(typeParameters, typeParameter => {
|
||||
const constraint = getEffectiveConstraintOfTypeParameter(typeParameter);
|
||||
|
||||
const template = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag);
|
||||
template.tagName = createIdentifier("template");
|
||||
template.constraint = constraint && cast(constraint, isJSDocTypeExpression);
|
||||
|
||||
const parameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
|
||||
parameter.name = typeParameter.name;
|
||||
template.typeParameters = createNodeArray([parameter]);
|
||||
|
||||
templates.push(template);
|
||||
});
|
||||
|
||||
changes.insertNodeBefore(file, firstStatement, createJSDocComment(/* comment */ undefined, createNodeArray(concatenate<JSDocTag>(templates, [node]))), /* blankLineBetween */ true);
|
||||
changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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})`,
|
||||
|
||||
@@ -455,7 +455,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;
|
||||
|
||||
@@ -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 VariableStatement’s 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) {
|
||||
// Can’t use 'ts.positionBelongsToNode()' here because it cleverly accounts
|
||||
// for missing nodes, which can’t 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 they’re 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 don’t 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 there’s 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;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"patternMatcher.ts",
|
||||
"preProcess.ts",
|
||||
"rename.ts",
|
||||
"smartSelection.ts",
|
||||
"signatureHelp.ts",
|
||||
"sourcemaps.ts",
|
||||
"suggestionDiagnostics.ts",
|
||||
@@ -80,6 +81,7 @@
|
||||
"refactors/convertExport.ts",
|
||||
"refactors/convertImport.ts",
|
||||
"refactors/extractSymbol.ts",
|
||||
"refactors/extractType.ts",
|
||||
"refactors/generateGetAccessorAndSetAccessor.ts",
|
||||
"refactors/moveToNewFile.ts",
|
||||
"refactors/addOrRemoveBracesToArrowFunction.ts",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.`
|
||||
}]);
|
||||
|
||||
|
||||
@@ -140,22 +140,28 @@ namespace ts {
|
||||
],
|
||||
{
|
||||
before: [
|
||||
context => node => visitNode(node, function visitor(node: Node): Node {
|
||||
if (isIdentifier(node) && node.text === "original") {
|
||||
const newNode = createIdentifier("changed");
|
||||
setSourceMapRange(newNode, {
|
||||
pos: 0,
|
||||
end: 7,
|
||||
// Do not provide a custom skipTrivia function for `source`.
|
||||
source: createSourceMapSource("another.html", "changed;")
|
||||
});
|
||||
return newNode;
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
})
|
||||
context => {
|
||||
const transformSourceFile: Transformer<SourceFile> = node => visitNode(node, function visitor(node: Node): Node {
|
||||
if (isIdentifier(node) && node.text === "original") {
|
||||
const newNode = createIdentifier("changed");
|
||||
setSourceMapRange(newNode, {
|
||||
pos: 0,
|
||||
end: 7,
|
||||
// Do not provide a custom skipTrivia function for `source`.
|
||||
source: createSourceMapSource("another.html", "changed;")
|
||||
});
|
||||
return newNode;
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
});
|
||||
return {
|
||||
transformSourceFile,
|
||||
transformBundle: node => createBundle(map(node.sourceFiles, transformSourceFile), node.prepends),
|
||||
};
|
||||
}
|
||||
]
|
||||
},
|
||||
{ sourceMap: true }
|
||||
{ sourceMap: true, outFile: "source.js" }
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
@@ -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", () => {
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace ts {
|
||||
parsesCorrectly("callSignatureInRecordType", "{{(): number}}");
|
||||
parsesCorrectly("methodInRecordType", "{{foo(): number}}");
|
||||
parsesCorrectly("unionType", "{(number|string)}");
|
||||
parsesCorrectly("unionTypeWithLeadingOperator", "{( | number | string )}");
|
||||
parsesCorrectly("unionTypeWithOneElementAndLeadingOperator", "{( | number )}");
|
||||
parsesCorrectly("topLevelNoParenUnionType", "{number|string}");
|
||||
parsesCorrectly("functionType1", "{function()}");
|
||||
parsesCorrectly("functionType2", "{function(string, boolean)}");
|
||||
|
||||
@@ -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", () => {
|
||||
|
||||
@@ -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 }, } } } } } } } } }]);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"kind": "ParenthesizedType",
|
||||
"pos": 1,
|
||||
"end": 22,
|
||||
"flags": "JSDoc",
|
||||
"modifierFlagsCache": 0,
|
||||
"transformFlags": 0,
|
||||
"type": {
|
||||
"kind": "UnionType",
|
||||
"pos": 2,
|
||||
"end": 20,
|
||||
"flags": "JSDoc",
|
||||
"modifierFlagsCache": 0,
|
||||
"transformFlags": 0,
|
||||
"types": {
|
||||
"0": {
|
||||
"kind": "NumberKeyword",
|
||||
"pos": 4,
|
||||
"end": 11,
|
||||
"flags": "JSDoc",
|
||||
"modifierFlagsCache": 0,
|
||||
"transformFlags": 0
|
||||
},
|
||||
"1": {
|
||||
"kind": "StringKeyword",
|
||||
"pos": 13,
|
||||
"end": 20,
|
||||
"flags": "JSDoc",
|
||||
"modifierFlagsCache": 0,
|
||||
"transformFlags": 0
|
||||
},
|
||||
"length": 2,
|
||||
"pos": 2,
|
||||
"end": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"kind": "ParenthesizedType",
|
||||
"pos": 1,
|
||||
"end": 13,
|
||||
"flags": "JSDoc",
|
||||
"modifierFlagsCache": 0,
|
||||
"transformFlags": 0,
|
||||
"type": {
|
||||
"kind": "UnionType",
|
||||
"pos": 2,
|
||||
"end": 11,
|
||||
"flags": "JSDoc",
|
||||
"modifierFlagsCache": 0,
|
||||
"transformFlags": 0,
|
||||
"types": {
|
||||
"0": {
|
||||
"kind": "NumberKeyword",
|
||||
"pos": 4,
|
||||
"end": 11,
|
||||
"flags": "JSDoc",
|
||||
"modifierFlagsCache": 0,
|
||||
"transformFlags": 0
|
||||
},
|
||||
"length": 1,
|
||||
"pos": 2,
|
||||
"end": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
-14
@@ -1879,13 +1879,18 @@ declare namespace ts {
|
||||
sourceFile: SourceFile;
|
||||
references?: ReadonlyArray<ResolvedProjectReference | undefined>;
|
||||
}
|
||||
type CustomTransformerFactory = (context: TransformationContext) => CustomTransformer;
|
||||
interface CustomTransformer {
|
||||
transformSourceFile(node: SourceFile): SourceFile;
|
||||
transformBundle(node: Bundle): Bundle;
|
||||
}
|
||||
interface CustomTransformers {
|
||||
/** Custom transformers to evaluate before built-in .js transformations. */
|
||||
before?: TransformerFactory<SourceFile>[];
|
||||
before?: (TransformerFactory<SourceFile> | CustomTransformerFactory)[];
|
||||
/** Custom transformers to evaluate after built-in .js transformations. */
|
||||
after?: TransformerFactory<SourceFile>[];
|
||||
after?: (TransformerFactory<SourceFile> | CustomTransformerFactory)[];
|
||||
/** Custom transformers to evaluate after built-in .d.ts transformations. */
|
||||
afterDeclarations?: TransformerFactory<Bundle | SourceFile>[];
|
||||
afterDeclarations?: (TransformerFactory<Bundle | SourceFile> | CustomTransformerFactory)[];
|
||||
}
|
||||
interface SourceMapSpan {
|
||||
/** Line number in the .js file. */
|
||||
@@ -1964,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;
|
||||
@@ -2385,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;
|
||||
@@ -2413,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;
|
||||
@@ -3856,7 +3863,7 @@ declare namespace ts {
|
||||
function updateArrayLiteral(node: ArrayLiteralExpression, elements: ReadonlyArray<Expression>): ArrayLiteralExpression;
|
||||
function createObjectLiteral(properties?: ReadonlyArray<ObjectLiteralElementLike>, multiLine?: boolean): ObjectLiteralExpression;
|
||||
function updateObjectLiteral(node: ObjectLiteralExpression, properties: ReadonlyArray<ObjectLiteralElementLike>): ObjectLiteralExpression;
|
||||
function createPropertyAccess(expression: Expression, name: string | Identifier | undefined): PropertyAccessExpression;
|
||||
function createPropertyAccess(expression: Expression, name: string | Identifier): PropertyAccessExpression;
|
||||
function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression;
|
||||
function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression;
|
||||
function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression;
|
||||
@@ -4071,7 +4078,7 @@ declare namespace ts {
|
||||
function createInputFiles(javascriptText: string, declarationText: string): InputFiles;
|
||||
function createInputFiles(readFileText: (path: string) => string | undefined, javascriptPath: string, javascriptMapPath: string | undefined, declarationPath: string, declarationMapPath: string | undefined, buildInfoPath: string | undefined): InputFiles;
|
||||
function createInputFiles(javascriptText: string, declarationText: string, javascriptMapPath: string | undefined, javascriptMapText: string | undefined, declarationMapPath: string | undefined, declarationMapText: string | undefined): InputFiles;
|
||||
function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends?: ReadonlyArray<UnparsedSource>): Bundle;
|
||||
function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends?: ReadonlyArray<UnparsedSource | InputFiles>): Bundle;
|
||||
function createImmediatelyInvokedFunctionExpression(statements: ReadonlyArray<Statement>): CallExpression;
|
||||
function createImmediatelyInvokedFunctionExpression(statements: ReadonlyArray<Statement>, param: ParameterDeclaration, paramValue: Expression): CallExpression;
|
||||
function createImmediatelyInvokedArrowFunction(statements: ReadonlyArray<Statement>): CallExpression;
|
||||
@@ -4803,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;
|
||||
@@ -5247,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
|
||||
@@ -5794,7 +5806,8 @@ declare namespace ts.server.protocol {
|
||||
GetEditsForRefactor = "getEditsForRefactor",
|
||||
OrganizeImports = "organizeImports",
|
||||
GetEditsForFileRename = "getEditsForFileRename",
|
||||
ConfigurePlugin = "configurePlugin"
|
||||
ConfigurePlugin = "configurePlugin",
|
||||
SelectionRange = "selectionRange",
|
||||
}
|
||||
/**
|
||||
* A TypeScript Server message
|
||||
@@ -6757,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.
|
||||
*/
|
||||
@@ -9033,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;
|
||||
|
||||
+25
-13
@@ -1879,13 +1879,18 @@ declare namespace ts {
|
||||
sourceFile: SourceFile;
|
||||
references?: ReadonlyArray<ResolvedProjectReference | undefined>;
|
||||
}
|
||||
type CustomTransformerFactory = (context: TransformationContext) => CustomTransformer;
|
||||
interface CustomTransformer {
|
||||
transformSourceFile(node: SourceFile): SourceFile;
|
||||
transformBundle(node: Bundle): Bundle;
|
||||
}
|
||||
interface CustomTransformers {
|
||||
/** Custom transformers to evaluate before built-in .js transformations. */
|
||||
before?: TransformerFactory<SourceFile>[];
|
||||
before?: (TransformerFactory<SourceFile> | CustomTransformerFactory)[];
|
||||
/** Custom transformers to evaluate after built-in .js transformations. */
|
||||
after?: TransformerFactory<SourceFile>[];
|
||||
after?: (TransformerFactory<SourceFile> | CustomTransformerFactory)[];
|
||||
/** Custom transformers to evaluate after built-in .d.ts transformations. */
|
||||
afterDeclarations?: TransformerFactory<Bundle | SourceFile>[];
|
||||
afterDeclarations?: (TransformerFactory<Bundle | SourceFile> | CustomTransformerFactory)[];
|
||||
}
|
||||
interface SourceMapSpan {
|
||||
/** Line number in the .js file. */
|
||||
@@ -1964,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;
|
||||
@@ -2385,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;
|
||||
@@ -2413,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;
|
||||
@@ -3856,7 +3863,7 @@ declare namespace ts {
|
||||
function updateArrayLiteral(node: ArrayLiteralExpression, elements: ReadonlyArray<Expression>): ArrayLiteralExpression;
|
||||
function createObjectLiteral(properties?: ReadonlyArray<ObjectLiteralElementLike>, multiLine?: boolean): ObjectLiteralExpression;
|
||||
function updateObjectLiteral(node: ObjectLiteralExpression, properties: ReadonlyArray<ObjectLiteralElementLike>): ObjectLiteralExpression;
|
||||
function createPropertyAccess(expression: Expression, name: string | Identifier | undefined): PropertyAccessExpression;
|
||||
function createPropertyAccess(expression: Expression, name: string | Identifier): PropertyAccessExpression;
|
||||
function updatePropertyAccess(node: PropertyAccessExpression, expression: Expression, name: Identifier): PropertyAccessExpression;
|
||||
function createElementAccess(expression: Expression, index: number | Expression): ElementAccessExpression;
|
||||
function updateElementAccess(node: ElementAccessExpression, expression: Expression, argumentExpression: Expression): ElementAccessExpression;
|
||||
@@ -4071,7 +4078,7 @@ declare namespace ts {
|
||||
function createInputFiles(javascriptText: string, declarationText: string): InputFiles;
|
||||
function createInputFiles(readFileText: (path: string) => string | undefined, javascriptPath: string, javascriptMapPath: string | undefined, declarationPath: string, declarationMapPath: string | undefined, buildInfoPath: string | undefined): InputFiles;
|
||||
function createInputFiles(javascriptText: string, declarationText: string, javascriptMapPath: string | undefined, javascriptMapText: string | undefined, declarationMapPath: string | undefined, declarationMapText: string | undefined): InputFiles;
|
||||
function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends?: ReadonlyArray<UnparsedSource>): Bundle;
|
||||
function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends?: ReadonlyArray<UnparsedSource | InputFiles>): Bundle;
|
||||
function createImmediatelyInvokedFunctionExpression(statements: ReadonlyArray<Statement>): CallExpression;
|
||||
function createImmediatelyInvokedFunctionExpression(statements: ReadonlyArray<Statement>, param: ParameterDeclaration, paramValue: Expression): CallExpression;
|
||||
function createImmediatelyInvokedArrowFunction(statements: ReadonlyArray<Statement>): CallExpression;
|
||||
@@ -4803,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;
|
||||
@@ -5247,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.
|
||||
~~
|
||||
|
||||
@@ -45,8 +45,10 @@ var __rest = (this && this.__rest) || function (s, e) {
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
|
||||
t[p[i]] = s[p[i]];
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var _this = this;
|
||||
|
||||
@@ -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'.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
tests/cases/compiler/checkInfiniteExpansionTermination.ts(16,1): error TS2322: Type 'ISubject<Bar>' is not assignable to type 'IObservable<Foo>'.
|
||||
Types of property 'n' are incompatible.
|
||||
Type 'IObservable<Bar[]>' is not assignable to type 'IObservable<Foo[]>'.
|
||||
Type 'Bar[]' is not assignable to type 'Foo[]'.
|
||||
Property 'x' is missing in type 'Bar' but required in type 'Foo'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/checkInfiniteExpansionTermination.ts (1 errors) ====
|
||||
// Regression test for #1002
|
||||
// Before fix this code would cause infinite loop
|
||||
|
||||
interface IObservable<T> {
|
||||
n: IObservable<T[]>; // Needed, must be T[]
|
||||
}
|
||||
|
||||
// Needed
|
||||
interface ISubject<T> extends IObservable<T> { }
|
||||
|
||||
interface Foo { x }
|
||||
interface Bar { y }
|
||||
|
||||
var values: IObservable<Foo>;
|
||||
var values2: ISubject<Bar>;
|
||||
values = values2;
|
||||
~~~~~~
|
||||
!!! error TS2322: Type 'ISubject<Bar>' is not assignable to type 'IObservable<Foo>'.
|
||||
!!! error TS2322: Types of property 'n' are incompatible.
|
||||
!!! error TS2322: Type 'IObservable<Bar[]>' is not assignable to type 'IObservable<Foo[]>'.
|
||||
!!! error TS2322: Type 'Bar[]' is not assignable to type 'Foo[]'.
|
||||
!!! error TS2322: Property 'x' is missing in type 'Bar' but required in type 'Foo'.
|
||||
!!! related TS2728 tests/cases/compiler/checkInfiniteExpansionTermination.ts:11:17: 'x' is declared here.
|
||||
|
||||
@@ -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) ====
|
||||
|
||||
+44
-32
@@ -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
|
||||
|
||||
@@ -19,12 +19,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(104,5): error TS2
|
||||
'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(106,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>' is not assignable to type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>'.
|
||||
Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
|
||||
Type 'keyof T' is not assignable to type 'never'.
|
||||
Type 'string | number | symbol' is not assignable to type 'never'.
|
||||
Type 'string' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(108,5): error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>' is not assignable to type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>'.
|
||||
Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
|
||||
Type 'keyof T' is not assignable to type 'never'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
|
||||
Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
|
||||
Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
|
||||
@@ -195,15 +191,11 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
|
||||
~
|
||||
!!! error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>' is not assignable to type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>'.
|
||||
!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'never'.
|
||||
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'never'.
|
||||
z = x;
|
||||
z = y; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Pick<T, { [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]>' is not assignable to type 'Pick<T, { [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]>'.
|
||||
!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'never'.
|
||||
}
|
||||
|
||||
function f8<T>(x: keyof T, y: FunctionPropertyNames<T>, z: NonFunctionPropertyNames<T>) {
|
||||
@@ -399,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,55 @@
|
||||
tests/cases/compiler/consistentAliasVsNonAliasRecordBehavior.ts(18,5): error TS2741: Property 'a' is missing in type 'Record<string, string>' but required in type 'Record2<"a", string>'.
|
||||
tests/cases/compiler/consistentAliasVsNonAliasRecordBehavior.ts(22,5): error TS2741: Property 'a' is missing in type 'Record2<string, string>' but required in type 'Record<"a", string>'.
|
||||
tests/cases/compiler/consistentAliasVsNonAliasRecordBehavior.ts(34,5): error TS2741: Property 'a' is missing in type 'Record<string, T>' but required in type 'Record2<"a", T>'.
|
||||
tests/cases/compiler/consistentAliasVsNonAliasRecordBehavior.ts(38,5): error TS2741: Property 'a' is missing in type 'Record2<string, T>' but required in type 'Record<"a", T>'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/consistentAliasVsNonAliasRecordBehavior.ts (4 errors) ====
|
||||
// TODO: FIXME: All the below cases labeled `no error` _should be an error_, and are only prevented from so being
|
||||
// by incorrect variance-based relationships
|
||||
// Ref: https://github.com/Microsoft/TypeScript/issues/29698
|
||||
|
||||
type Record2<K extends keyof any, T> = {
|
||||
[P in K]: T;
|
||||
};
|
||||
|
||||
function defaultRecord(x: Record<'a', string>, y: Record<string, string>) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
|
||||
function customRecord(x: Record2<'a', string>, y: Record2<string, string>) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
|
||||
function mixed1(x: Record2<'a', string>, y: Record<string, string>) {
|
||||
x = y; // error
|
||||
~
|
||||
!!! error TS2741: Property 'a' is missing in type 'Record<string, string>' but required in type 'Record2<"a", string>'.
|
||||
}
|
||||
|
||||
function mixed2(x: Record<'a', string>, y: Record2<string, string>) {
|
||||
x = y; // error
|
||||
~
|
||||
!!! error TS2741: Property 'a' is missing in type 'Record2<string, string>' but required in type 'Record<"a", string>'.
|
||||
}
|
||||
|
||||
function defaultRecord2<T>(x: Record<'a', T>, y: Record<string, T>) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
|
||||
function customRecord2<T>(x: Record2<'a', T>, y: Record2<string, T>) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
|
||||
function mixed3<T>(x: Record2<'a', T>, y: Record<string, T>) {
|
||||
x = y; // error
|
||||
~
|
||||
!!! error TS2741: Property 'a' is missing in type 'Record<string, T>' but required in type 'Record2<"a", T>'.
|
||||
}
|
||||
|
||||
function mixed4<T>(x: Record<'a', T>, y: Record2<string, T>) {
|
||||
x = y; // error
|
||||
~
|
||||
!!! error TS2741: Property 'a' is missing in type 'Record2<string, T>' but required in type 'Record<"a", T>'.
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//// [consistentAliasVsNonAliasRecordBehavior.ts]
|
||||
// TODO: FIXME: All the below cases labeled `no error` _should be an error_, and are only prevented from so being
|
||||
// by incorrect variance-based relationships
|
||||
// Ref: https://github.com/Microsoft/TypeScript/issues/29698
|
||||
|
||||
type Record2<K extends keyof any, T> = {
|
||||
[P in K]: T;
|
||||
};
|
||||
|
||||
function defaultRecord(x: Record<'a', string>, y: Record<string, string>) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
|
||||
function customRecord(x: Record2<'a', string>, y: Record2<string, string>) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
|
||||
function mixed1(x: Record2<'a', string>, y: Record<string, string>) {
|
||||
x = y; // error
|
||||
}
|
||||
|
||||
function mixed2(x: Record<'a', string>, y: Record2<string, string>) {
|
||||
x = y; // error
|
||||
}
|
||||
|
||||
function defaultRecord2<T>(x: Record<'a', T>, y: Record<string, T>) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
|
||||
function customRecord2<T>(x: Record2<'a', T>, y: Record2<string, T>) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
|
||||
function mixed3<T>(x: Record2<'a', T>, y: Record<string, T>) {
|
||||
x = y; // error
|
||||
}
|
||||
|
||||
function mixed4<T>(x: Record<'a', T>, y: Record2<string, T>) {
|
||||
x = y; // error
|
||||
}
|
||||
|
||||
|
||||
//// [consistentAliasVsNonAliasRecordBehavior.js]
|
||||
// TODO: FIXME: All the below cases labeled `no error` _should be an error_, and are only prevented from so being
|
||||
// by incorrect variance-based relationships
|
||||
// Ref: https://github.com/Microsoft/TypeScript/issues/29698
|
||||
function defaultRecord(x, y) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
function customRecord(x, y) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
function mixed1(x, y) {
|
||||
x = y; // error
|
||||
}
|
||||
function mixed2(x, y) {
|
||||
x = y; // error
|
||||
}
|
||||
function defaultRecord2(x, y) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
function customRecord2(x, y) {
|
||||
x = y; // no error, but error expected.
|
||||
}
|
||||
function mixed3(x, y) {
|
||||
x = y; // error
|
||||
}
|
||||
function mixed4(x, y) {
|
||||
x = y; // error
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
=== tests/cases/compiler/consistentAliasVsNonAliasRecordBehavior.ts ===
|
||||
// TODO: FIXME: All the below cases labeled `no error` _should be an error_, and are only prevented from so being
|
||||
// by incorrect variance-based relationships
|
||||
// Ref: https://github.com/Microsoft/TypeScript/issues/29698
|
||||
|
||||
type Record2<K extends keyof any, T> = {
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
>K : Symbol(K, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 4, 13))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 4, 33))
|
||||
|
||||
[P in K]: T;
|
||||
>P : Symbol(P, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 5, 5))
|
||||
>K : Symbol(K, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 4, 13))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 4, 33))
|
||||
|
||||
};
|
||||
|
||||
function defaultRecord(x: Record<'a', string>, y: Record<string, string>) {
|
||||
>defaultRecord : Symbol(defaultRecord, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 6, 2))
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 8, 23))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 8, 46))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
x = y; // no error, but error expected.
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 8, 23))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 8, 46))
|
||||
}
|
||||
|
||||
function customRecord(x: Record2<'a', string>, y: Record2<string, string>) {
|
||||
>customRecord : Symbol(customRecord, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 10, 1))
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 12, 22))
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 12, 46))
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
|
||||
x = y; // no error, but error expected.
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 12, 22))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 12, 46))
|
||||
}
|
||||
|
||||
function mixed1(x: Record2<'a', string>, y: Record<string, string>) {
|
||||
>mixed1 : Symbol(mixed1, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 14, 1))
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 16, 16))
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 16, 40))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
x = y; // error
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 16, 16))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 16, 40))
|
||||
}
|
||||
|
||||
function mixed2(x: Record<'a', string>, y: Record2<string, string>) {
|
||||
>mixed2 : Symbol(mixed2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 18, 1))
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 20, 16))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 20, 39))
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
|
||||
x = y; // error
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 20, 16))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 20, 39))
|
||||
}
|
||||
|
||||
function defaultRecord2<T>(x: Record<'a', T>, y: Record<string, T>) {
|
||||
>defaultRecord2 : Symbol(defaultRecord2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 22, 1))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 24, 24))
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 24, 27))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 24, 24))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 24, 45))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 24, 24))
|
||||
|
||||
x = y; // no error, but error expected.
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 24, 27))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 24, 45))
|
||||
}
|
||||
|
||||
function customRecord2<T>(x: Record2<'a', T>, y: Record2<string, T>) {
|
||||
>customRecord2 : Symbol(customRecord2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 26, 1))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 28, 23))
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 28, 26))
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 28, 23))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 28, 45))
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 28, 23))
|
||||
|
||||
x = y; // no error, but error expected.
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 28, 26))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 28, 45))
|
||||
}
|
||||
|
||||
function mixed3<T>(x: Record2<'a', T>, y: Record<string, T>) {
|
||||
>mixed3 : Symbol(mixed3, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 30, 1))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 32, 16))
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 32, 19))
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 32, 16))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 32, 38))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 32, 16))
|
||||
|
||||
x = y; // error
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 32, 19))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 32, 38))
|
||||
}
|
||||
|
||||
function mixed4<T>(x: Record<'a', T>, y: Record2<string, T>) {
|
||||
>mixed4 : Symbol(mixed4, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 34, 1))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 36, 16))
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 36, 19))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 36, 16))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 36, 37))
|
||||
>Record2 : Symbol(Record2, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 36, 16))
|
||||
|
||||
x = y; // error
|
||||
>x : Symbol(x, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 36, 19))
|
||||
>y : Symbol(y, Decl(consistentAliasVsNonAliasRecordBehavior.ts, 36, 37))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
=== tests/cases/compiler/consistentAliasVsNonAliasRecordBehavior.ts ===
|
||||
// TODO: FIXME: All the below cases labeled `no error` _should be an error_, and are only prevented from so being
|
||||
// by incorrect variance-based relationships
|
||||
// Ref: https://github.com/Microsoft/TypeScript/issues/29698
|
||||
|
||||
type Record2<K extends keyof any, T> = {
|
||||
>Record2 : Record2<K, T>
|
||||
|
||||
[P in K]: T;
|
||||
};
|
||||
|
||||
function defaultRecord(x: Record<'a', string>, y: Record<string, string>) {
|
||||
>defaultRecord : (x: Record<"a", string>, y: Record<string, string>) => void
|
||||
>x : Record<"a", string>
|
||||
>y : Record<string, string>
|
||||
|
||||
x = y; // no error, but error expected.
|
||||
>x = y : Record<string, string>
|
||||
>x : Record<"a", string>
|
||||
>y : Record<string, string>
|
||||
}
|
||||
|
||||
function customRecord(x: Record2<'a', string>, y: Record2<string, string>) {
|
||||
>customRecord : (x: Record2<"a", string>, y: Record2<string, string>) => void
|
||||
>x : Record2<"a", string>
|
||||
>y : Record2<string, string>
|
||||
|
||||
x = y; // no error, but error expected.
|
||||
>x = y : Record2<string, string>
|
||||
>x : Record2<"a", string>
|
||||
>y : Record2<string, string>
|
||||
}
|
||||
|
||||
function mixed1(x: Record2<'a', string>, y: Record<string, string>) {
|
||||
>mixed1 : (x: Record2<"a", string>, y: Record<string, string>) => void
|
||||
>x : Record2<"a", string>
|
||||
>y : Record<string, string>
|
||||
|
||||
x = y; // error
|
||||
>x = y : Record<string, string>
|
||||
>x : Record2<"a", string>
|
||||
>y : Record<string, string>
|
||||
}
|
||||
|
||||
function mixed2(x: Record<'a', string>, y: Record2<string, string>) {
|
||||
>mixed2 : (x: Record<"a", string>, y: Record2<string, string>) => void
|
||||
>x : Record<"a", string>
|
||||
>y : Record2<string, string>
|
||||
|
||||
x = y; // error
|
||||
>x = y : Record2<string, string>
|
||||
>x : Record<"a", string>
|
||||
>y : Record2<string, string>
|
||||
}
|
||||
|
||||
function defaultRecord2<T>(x: Record<'a', T>, y: Record<string, T>) {
|
||||
>defaultRecord2 : <T>(x: Record<"a", T>, y: Record<string, T>) => void
|
||||
>x : Record<"a", T>
|
||||
>y : Record<string, T>
|
||||
|
||||
x = y; // no error, but error expected.
|
||||
>x = y : Record<string, T>
|
||||
>x : Record<"a", T>
|
||||
>y : Record<string, T>
|
||||
}
|
||||
|
||||
function customRecord2<T>(x: Record2<'a', T>, y: Record2<string, T>) {
|
||||
>customRecord2 : <T>(x: Record2<"a", T>, y: Record2<string, T>) => void
|
||||
>x : Record2<"a", T>
|
||||
>y : Record2<string, T>
|
||||
|
||||
x = y; // no error, but error expected.
|
||||
>x = y : Record2<string, T>
|
||||
>x : Record2<"a", T>
|
||||
>y : Record2<string, T>
|
||||
}
|
||||
|
||||
function mixed3<T>(x: Record2<'a', T>, y: Record<string, T>) {
|
||||
>mixed3 : <T>(x: Record2<"a", T>, y: Record<string, T>) => void
|
||||
>x : Record2<"a", T>
|
||||
>y : Record<string, T>
|
||||
|
||||
x = y; // error
|
||||
>x = y : Record<string, T>
|
||||
>x : Record2<"a", T>
|
||||
>y : Record<string, T>
|
||||
}
|
||||
|
||||
function mixed4<T>(x: Record<'a', T>, y: Record2<string, T>) {
|
||||
>mixed4 : <T>(x: Record<"a", T>, y: Record2<string, T>) => void
|
||||
>x : Record<"a", T>
|
||||
>y : Record2<string, T>
|
||||
|
||||
x = y; // error
|
||||
>x = y : Record2<string, T>
|
||||
>x : Record<"a", T>
|
||||
>y : Record2<string, T>
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}());
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user