From dc78c4f4de381e3afbb0066b3ee42afa0812bdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Sun, 8 Apr 2018 16:14:29 +0800 Subject: [PATCH 001/163] improve parser and error message if definite assignment assertions in object short hand --- src/compiler/checker.ts | 15 ++++++++++-- src/compiler/parser.ts | 6 ++++- src/compiler/types.ts | 2 ++ .../reference/api/tsserverlibrary.d.ts | 2 ++ tests/baselines/reference/api/typescript.d.ts | 2 ++ ...ntAssertionsWithObjectShortHand.errors.txt | 15 ++++++++++++ ...AssignmentAssertionsWithObjectShortHand.js | 23 +++++++++++++++++++ ...nmentAssertionsWithObjectShortHand.symbols | 14 +++++++++++ ...ignmentAssertionsWithObjectShortHand.types | 17 ++++++++++++++ ...AssignmentAssertionsWithObjectShortHand.ts | 9 ++++++++ 10 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.errors.txt create mode 100644 tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.js create mode 100644 tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.symbols create mode 100644 tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.types create mode 100644 tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1e6a16aa75f..45eed69974f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26871,12 +26871,18 @@ namespace ts { } } - function checkGrammarForInvalidQuestionMark(questionToken: Node, message: DiagnosticMessage): boolean { + function checkGrammarForInvalidQuestionMark(questionToken: QuestionToken, message: DiagnosticMessage): boolean { if (questionToken) { return grammarErrorOnNode(questionToken, message); } } + function checkGrammarForInvalidExclamationToken(exclamationToken: ExclamationToken, message: DiagnosticMessage): boolean { + if (exclamationToken) { + return grammarErrorOnNode(exclamationToken, message); + } + } + function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) { const enum Flags { Property = 1, @@ -26921,8 +26927,10 @@ namespace ts { // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields let currentKind: Flags; switch (prop.kind) { - case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: + checkGrammarForInvalidExclamationToken(prop.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context); + /* tslint:disable:no-switch-case-fall-through */ + case SyntaxKind.PropertyAssignment: // Grammar checking for computedPropertyName and shorthandPropertyAssignment checkGrammarForInvalidQuestionMark(prop.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional); if (name.kind === SyntaxKind.NumericLiteral) { @@ -27162,6 +27170,9 @@ namespace ts { else if (checkGrammarForInvalidQuestionMark(node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) { return true; } + else if (checkGrammarForInvalidExclamationToken(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context)) { + return true; + } else if (node.body === undefined) { return grammarErrorAtPos(node, node.end - 1, ";".length, Diagnostics._0_expected, "{"); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3c118d943a2..dbc989e0c51 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -90,6 +90,7 @@ namespace ts { visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, (node).name) || visitNode(cbNode, (node).questionToken) || + visitNode(cbNode, (node).exclamationToken) || visitNode(cbNode, (node).equalsToken) || visitNode(cbNode, (node).objectAssignmentInitializer); case SyntaxKind.SpreadAssignment: @@ -160,6 +161,7 @@ namespace ts { visitNode(cbNode, (node).asteriskToken) || visitNode(cbNode, (node).name) || visitNode(cbNode, (node).questionToken) || + visitNode(cbNode, (node).exclamationToken) || visitNodes(cbNode, cbNodes, (node).typeParameters) || visitNodes(cbNode, cbNodes, (node).parameters) || visitNode(cbNode, (node).type) || @@ -4580,8 +4582,10 @@ namespace ts { const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); const tokenIsIdentifier = isIdentifier(); node.name = parsePropertyName(); - // Disallowing of optional property assignments happens in the grammar checker. + // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker. (node).questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + (node).exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken); + if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { return parseMethodDeclaration(node, asteriskToken); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4edfc29a2a1..085d2c95acf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -912,6 +912,7 @@ namespace ts { kind: SyntaxKind.ShorthandPropertyAssignment; name: Identifier; questionToken?: QuestionToken; + exclamationToken?: ExclamationToken; // used when ObjectLiteralExpression is used in ObjectAssignmentPattern // it is grammar error to appear in actual object initializer equalsToken?: Token; @@ -970,6 +971,7 @@ namespace ts { asteriskToken?: AsteriskToken; questionToken?: QuestionToken; + exclamationToken?: ExclamationToken; body?: Block | Expression; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index aca4e956181..1ac5055e0c7 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -608,6 +608,7 @@ declare namespace ts { kind: SyntaxKind.ShorthandPropertyAssignment; name: Identifier; questionToken?: QuestionToken; + exclamationToken?: ExclamationToken; equalsToken?: Token; objectAssignmentInitializer?: Expression; } @@ -644,6 +645,7 @@ declare namespace ts { _functionLikeDeclarationBrand: any; asteriskToken?: AsteriskToken; questionToken?: QuestionToken; + exclamationToken?: ExclamationToken; body?: Block | Expression; } type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index aa77372db45..4def1db34f8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -608,6 +608,7 @@ declare namespace ts { kind: SyntaxKind.ShorthandPropertyAssignment; name: Identifier; questionToken?: QuestionToken; + exclamationToken?: ExclamationToken; equalsToken?: Token; objectAssignmentInitializer?: Expression; } @@ -644,6 +645,7 @@ declare namespace ts { _functionLikeDeclarationBrand: any; asteriskToken?: AsteriskToken; questionToken?: QuestionToken; + exclamationToken?: ExclamationToken; body?: Block | Expression; } type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction; diff --git a/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.errors.txt b/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.errors.txt new file mode 100644 index 00000000000..30a1cc39aeb --- /dev/null +++ b/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts(2,16): error TS1255: A definite assignment assertion '!' is not permitted in this context. +tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts(5,7): error TS1162: An object member cannot be declared optional. + + +==== tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts (2 errors) ==== + const a: string | undefined = 'ff'; + const foo = { a! } + ~ +!!! error TS1255: A definite assignment assertion '!' is not permitted in this context. + + const bar = { + a ? () { } + ~ +!!! error TS1162: An object member cannot be declared optional. + } \ No newline at end of file diff --git a/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.js b/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.js new file mode 100644 index 00000000000..c3bfe922374 --- /dev/null +++ b/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.js @@ -0,0 +1,23 @@ +//// [definiteAssignmentAssertionsWithObjectShortHand.ts] +const a: string | undefined = 'ff'; +const foo = { a! } + +const bar = { + a ? () { } +} + +//// [definiteAssignmentAssertionsWithObjectShortHand.js] +"use strict"; +var a = 'ff'; +var foo = { a: a }; +var bar = { + a: function () { } +}; + + +//// [definiteAssignmentAssertionsWithObjectShortHand.d.ts] +declare const a: string | undefined; +declare const foo: { + a: string; +}; +declare const bar: {}; diff --git a/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.symbols b/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.symbols new file mode 100644 index 00000000000..7b8afc1d657 --- /dev/null +++ b/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts === +const a: string | undefined = 'ff'; +>a : Symbol(a, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 0, 5)) + +const foo = { a! } +>foo : Symbol(foo, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 1, 5)) +>a : Symbol(a, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 1, 13)) + +const bar = { +>bar : Symbol(bar, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 3, 5)) + + a ? () { } +>a : Symbol(a, Decl(definiteAssignmentAssertionsWithObjectShortHand.ts, 3, 13)) +} diff --git a/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.types b/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.types new file mode 100644 index 00000000000..73c3edfdaa5 --- /dev/null +++ b/tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts === +const a: string | undefined = 'ff'; +>a : string | undefined +>'ff' : "ff" + +const foo = { a! } +>foo : { a: string; } +>{ a! } : { a: string; } +>a : string + +const bar = { +>bar : {} +>{ a ? () { }} : {} + + a ? () { } +>a : (() => void) | undefined +} diff --git a/tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts b/tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts new file mode 100644 index 00000000000..56c22310433 --- /dev/null +++ b/tests/cases/conformance/controlFlow/definiteAssignmentAssertionsWithObjectShortHand.ts @@ -0,0 +1,9 @@ +// @strict: true +// @declaration: true + +const a: string | undefined = 'ff'; +const foo = { a! } + +const bar = { + a ? () { } +} \ No newline at end of file From 0d79831ead51bda2fd38dd169e0bf04a0cdb4e72 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Tue, 13 Feb 2018 01:14:47 +0000 Subject: [PATCH 002/163] Add typeof-for-switch Initial draft that works for union types First draft of PR ready code with tests Revert changed line for testing Add exhaustiveness checking and move narrowByTypeOfWitnesses Try caching mechanism Comment out exhaustiveness checking to find perf regression Re-enable exhaustiveness checking for typeof switches Check if changes to narrowByTypeOfWitnesses fix perf alone. Improve switch narrowing: + Take into account repeated clauses in the switch. + Handle unions of constrained type parameters. Add more tests Comments Revert back to if-like behaviour Remove redundant checks and simplify exhaustiveness checks Change comment for narrowBySwitchOnTypeOf Reduce implied type with getAssignmentReducedType Remove any annotations --- src/compiler/binder.ts | 2 + src/compiler/checker.ts | 119 +++ .../reference/narrowingByTypeofInSwitch.js | 427 +++++++++++ .../narrowingByTypeofInSwitch.symbols | 542 ++++++++++++++ .../reference/narrowingByTypeofInSwitch.types | 695 ++++++++++++++++++ .../compiler/narrowingByTypeofInSwitch.ts | 190 +++++ 6 files changed, 1975 insertions(+) create mode 100644 tests/baselines/reference/narrowingByTypeofInSwitch.js create mode 100644 tests/baselines/reference/narrowingByTypeofInSwitch.symbols create mode 100644 tests/baselines/reference/narrowingByTypeofInSwitch.types create mode 100644 tests/cases/compiler/narrowingByTypeofInSwitch.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e6e3364840d..555c13f1f61 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -737,6 +737,8 @@ namespace ts { return isNarrowingBinaryExpression(expr); case SyntaxKind.PrefixUnaryExpression: return (expr).operator === SyntaxKind.ExclamationToken && isNarrowingExpression((expr).operand); + case SyntaxKind.TypeOfExpression: + return isNarrowingExpression((expr).expression); } return false; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f497ba82e47..ab2cc1f3b85 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12840,6 +12840,21 @@ namespace ts { return links.switchTypes; } + function getSwitchClauseTypeOfWitnesses(switchStatement: SwitchStatement): (string | undefined)[] { + const witnesses: (string | undefined)[] = []; + for (const clause of switchStatement.caseBlock.clauses) { + if (clause.kind === SyntaxKind.CaseClause) { + if (clause.expression.kind === SyntaxKind.StringLiteral) { + witnesses.push((clause.expression as StringLiteral).text); + continue; + } + return emptyArray; + } + witnesses.push(/*explicitDefaultStatement*/ undefined); + } + return witnesses; + } + function eachTypeContainedIn(source: Type, types: Type[]) { return source.flags & TypeFlags.Union ? !forEach((source).types, t => !contains(types, t)) : contains(types, source); } @@ -13253,6 +13268,9 @@ namespace ts { else if (isMatchingReferenceDiscriminant(expr, type)) { type = narrowTypeByDiscriminant(type, expr, t => narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd)); } + else if (expr.kind === SyntaxKind.TypeOfExpression && isMatchingReference(reference, (expr as TypeOfExpression).expression)) { + type = narrowBySwitchOnTypeOf(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd); + } return createFlowType(type, isIncomplete(flowType)); } @@ -13549,6 +13567,57 @@ namespace ts { return caseType.flags & TypeFlags.Never ? defaultType : getUnionType([caseType, defaultType]); } + function narrowBySwitchOnTypeOf(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): Type { + const switchWitnesses = getSwitchClauseTypeOfWitnesses(switchStatement); + if (!switchWitnesses.length) { + return type; + } + const clauseWitnesses = switchWitnesses.slice(clauseStart, clauseEnd); + // Equal start and end denotes implicit fallthrough; undefined marks explicit default clause + const hasDefaultClause = clauseStart === clauseEnd || contains(clauseWitnesses, /*explicitDefaultStatement*/ undefined); + const switchFacts = getFactsFromTypeofSwitch(clauseStart, clauseEnd, switchWitnesses, hasDefaultClause); + // The implied type is the raw type suggested by a + // value being caught in this clause. + // - If there is a default the implied type is not used. + // - Otherwise, take the union of the types in the + // clause. We narrow the union using facts to remove + // types that appear multiple types and are + // unreachable. + // Example: + // + // switch (typeof x) { + // case 'number': + // case 'string': break; + // default: break; + // case 'number': + // case 'boolean': break + // } + // + // The implied type of the first clause number | string. + // The implied type of the second clause is string (but this doesn't get used). + // The implied type of the third clause is boolean (number has already be caught). + if (!(hasDefaultClause || (type.flags & TypeFlags.Union))) { + let impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(text => typeofTypesByName.get(text) || neverType)), switchFacts); + if (impliedType.flags & TypeFlags.Union) { + impliedType = getAssignmentReducedType(impliedType as UnionType, getBaseConstraintOfType(type) || type); + } + if (!(impliedType.flags & TypeFlags.Never)) { + if (isTypeSubtypeOf(impliedType, type)) { + return impliedType; + } + if (type.flags & TypeFlags.Instantiable) { + const constraint = getBaseConstraintOfType(type) || anyType; + if (isTypeSubtypeOf(impliedType, constraint)) { + return getIntersectionType([type, impliedType]); + } + } + } + } + return hasDefaultClause ? + filterType(type, t => (getTypeFacts(t) & switchFacts) === switchFacts) : + getTypeWithFacts(type, switchFacts); + } + function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { const left = getReferenceCandidate(expr.left); if (!isMatchingReference(reference, left)) { @@ -18944,10 +19013,60 @@ namespace ts { : Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } + /** + * Collect the TypeFacts learned from a typeof switch with + * total clauses `witnesses`, and the active clause ranging + * from `start` to `end`. Parameter `hasDefault` denotes + * whether the active clause contains a default clause. + */ + function getFactsFromTypeofSwitch(start: number, end: number, witnesses: (string | undefined)[], hasDefault: boolean): TypeFacts { + let facts: TypeFacts = TypeFacts.None; + // When in the default we only collect inequality facts + // because default is 'in theory' a set of infinite + // equalities. + if (hasDefault) { + // Value is not equal to any types after the active clause. + for (let i = end; i < witnesses.length; i++) { + facts |= typeofNEFacts.get(witnesses[i]) || TypeFacts.TypeofNEHostObject; + } + // Remove inequalities for types that appear in the + // active clause because they appear before other + // types collected so far. + for (let i = start; i < end; i++) { + facts &= ~(typeofNEFacts.get(witnesses[i]) || 0); + } + // Add inequalities for types before the active clause unconditionally. + for (let i = 0; i < start; i++) { + facts |= typeofNEFacts.get(witnesses[i]) || TypeFacts.TypeofNEHostObject; + } + } + // When in an active clause without default the set of + // equalities is finite. + else { + // Add equalities for all types in the active clause. + for (let i = start; i < end; i++) { + facts |= typeofEQFacts.get(witnesses[i]) || TypeFacts.TypeofEQHostObject; + } + // Remove equalities for types that appear before the + // active clause. + for (let i = 0; i < start; i++) { + facts &= ~(typeofEQFacts.get(witnesses[i]) || 0); + } + } + return facts; + } + function isExhaustiveSwitchStatement(node: SwitchStatement): boolean { if (!node.possiblyExhaustive) { return false; } + if (node.expression.kind === SyntaxKind.TypeOfExpression) { + const operandType = getTypeOfExpression((node.expression as TypeOfExpression).expression); + // Type is not equal to every type in the switch. + const notEqualFacts = getFactsFromTypeofSwitch(0, 0, getSwitchClauseTypeOfWitnesses(node), /*hasDefault*/ true); + const type = getBaseConstraintOfType(operandType) || operandType; + return !!(filterType(type, t => (getTypeFacts(t) & notEqualFacts) === notEqualFacts).flags & TypeFlags.Never); + } const type = getTypeOfExpression(node.expression); if (!isLiteralType(type)) { return false; diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.js b/tests/baselines/reference/narrowingByTypeofInSwitch.js new file mode 100644 index 00000000000..2cf4b9027c2 --- /dev/null +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.js @@ -0,0 +1,427 @@ +//// [narrowingByTypeofInSwitch.ts] +function assertNever(x: never) { + return x; +} + +function assertNumber(x: number) { + return x; +} + +function assertBoolean(x: boolean) { + return x; +} + +function assertString(x: string) { + return x; +} + +function assertSymbol(x: symbol) { + return x; +} + +function assertFunction(x: Function) { + return x; +} + +function assertObject(x: object) { + return x; +} + +function assertUndefined(x: undefined) { + return x; +} + +function assertAll(x: Basic) { + return x; +} + +type Basic = number | boolean | string | symbol | object | Function | undefined; + +function testUnion(x: Basic) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertFunction(x); return; + case 'symbol': assertSymbol(x); return; + case 'object': assertObject(x); return; + case 'string': assertString(x); return; + case 'undefined': assertUndefined(x); return; + } + assertNever(x); +} + +function testExtendsUnion(x: T) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertAll(x); return; + case 'symbol': assertSymbol(x); return; + case 'object': assertAll(x); return; + case 'string': assertString(x); return; + case 'undefined': assertUndefined(x); return; + } + assertAll(x); +} + +function testAny(x: any) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertFunction(x); return; + case 'symbol': assertSymbol(x); return; + case 'object': assertObject(x); return; + case 'string': assertString(x); return; + case 'undefined': assertUndefined(x); return; + } + assertAll(x); // is any +} + +function a1(x: string | object | undefined) { + return x; +} + +function testUnionExplicitDefault(x: Basic) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertFunction(x); return; + case 'symbol': assertSymbol(x); return; + default: a1(x); return; + } +} + +function testUnionImplicitDefault(x: Basic) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertFunction(x); return; + case 'symbol': assertSymbol(x); return; + } + return a1(x); +} + +function testExtendsExplicitDefault(x: T) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertAll(x); return; + case 'symbol': assertSymbol(x); return; + default: assertAll(x); return; + + } +} + +function testExtendsImplicitDefault(x: T) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertAll(x); return; + case 'symbol': assertSymbol(x); return; + } + return assertAll(x); +} + +type L = (x: number) => string; +type R = { x: string, y: number } + +function exhaustiveChecks(x: number | string | L | R): string { + switch (typeof x) { + case 'number': return x.toString(2); + case 'string': return x; + case 'function': return x(42); + case 'object': return x.x; + } +} + +function exhaustiveChecksGenerics(x: T): string { + switch (typeof x) { + case 'number': return x.toString(2); + case 'string': return x; + case 'function': return (x as L)(42); // Can't narrow generic + case 'object': return (x as R).x; // Can't narrow generic + } +} + +function multipleGeneric(xy: X | Y): [X, string] | [Y, number] { + switch (typeof xy) { + case 'function': return [xy, xy(42)]; + case 'object': return [xy, xy.y]; + default: return assertNever(xy); + } +} + +function multipleGenericFuse(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { + switch (typeof xy) { + case 'function': return [xy, 1]; + case 'object': return [xy, 'two']; + case 'number': return [xy] + } +} + +function multipleGenericExhaustive(xy: X | Y): [X, string] | [Y, number] { + switch (typeof xy) { + case 'object': return [xy, xy.y]; + case 'function': return [xy, xy(42)]; + } +} + +function switchOrdering(x: string | number | boolean) { + switch (typeof x) { + case 'string': return assertString(x); + case 'number': return assertNumber(x); + case 'boolean': return assertBoolean(x); + case 'number': return assertNever(x); + } +} + +function switchOrderingWithDefault(x: string | number | boolean) { + function local(y: string | number | boolean) { + return x; + } + switch (typeof x) { + case 'string': + case 'number': + default: return local(x) + case 'string': return assertNever(x); + case 'number': return assertNever(x); + } +} + + +//// [narrowingByTypeofInSwitch.js] +function assertNever(x) { + return x; +} +function assertNumber(x) { + return x; +} +function assertBoolean(x) { + return x; +} +function assertString(x) { + return x; +} +function assertSymbol(x) { + return x; +} +function assertFunction(x) { + return x; +} +function assertObject(x) { + return x; +} +function assertUndefined(x) { + return x; +} +function assertAll(x) { + return x; +} +function testUnion(x) { + switch (typeof x) { + case 'number': + assertNumber(x); + return; + case 'boolean': + assertBoolean(x); + return; + case 'function': + assertFunction(x); + return; + case 'symbol': + assertSymbol(x); + return; + case 'object': + assertObject(x); + return; + case 'string': + assertString(x); + return; + case 'undefined': + assertUndefined(x); + return; + } + assertNever(x); +} +function testExtendsUnion(x) { + switch (typeof x) { + case 'number': + assertNumber(x); + return; + case 'boolean': + assertBoolean(x); + return; + case 'function': + assertAll(x); + return; + case 'symbol': + assertSymbol(x); + return; + case 'object': + assertAll(x); + return; + case 'string': + assertString(x); + return; + case 'undefined': + assertUndefined(x); + return; + } + assertAll(x); +} +function testAny(x) { + switch (typeof x) { + case 'number': + assertNumber(x); + return; + case 'boolean': + assertBoolean(x); + return; + case 'function': + assertFunction(x); + return; + case 'symbol': + assertSymbol(x); + return; + case 'object': + assertObject(x); + return; + case 'string': + assertString(x); + return; + case 'undefined': + assertUndefined(x); + return; + } + assertAll(x); // is any +} +function a1(x) { + return x; +} +function testUnionExplicitDefault(x) { + switch (typeof x) { + case 'number': + assertNumber(x); + return; + case 'boolean': + assertBoolean(x); + return; + case 'function': + assertFunction(x); + return; + case 'symbol': + assertSymbol(x); + return; + default: + a1(x); + return; + } +} +function testUnionImplicitDefault(x) { + switch (typeof x) { + case 'number': + assertNumber(x); + return; + case 'boolean': + assertBoolean(x); + return; + case 'function': + assertFunction(x); + return; + case 'symbol': + assertSymbol(x); + return; + } + return a1(x); +} +function testExtendsExplicitDefault(x) { + switch (typeof x) { + case 'number': + assertNumber(x); + return; + case 'boolean': + assertBoolean(x); + return; + case 'function': + assertAll(x); + return; + case 'symbol': + assertSymbol(x); + return; + default: + assertAll(x); + return; + } +} +function testExtendsImplicitDefault(x) { + switch (typeof x) { + case 'number': + assertNumber(x); + return; + case 'boolean': + assertBoolean(x); + return; + case 'function': + assertAll(x); + return; + case 'symbol': + assertSymbol(x); + return; + } + return assertAll(x); +} +function exhaustiveChecks(x) { + switch (typeof x) { + case 'number': return x.toString(2); + case 'string': return x; + case 'function': return x(42); + case 'object': return x.x; + } +} +function exhaustiveChecksGenerics(x) { + switch (typeof x) { + case 'number': return x.toString(2); + case 'string': return x; + case 'function': return x(42); // Can't narrow generic + case 'object': return x.x; // Can't narrow generic + } +} +function multipleGeneric(xy) { + switch (typeof xy) { + case 'function': return [xy, xy(42)]; + case 'object': return [xy, xy.y]; + default: return assertNever(xy); + } +} +function multipleGenericFuse(xy) { + switch (typeof xy) { + case 'function': return [xy, 1]; + case 'object': return [xy, 'two']; + case 'number': return [xy]; + } +} +function multipleGenericExhaustive(xy) { + switch (typeof xy) { + case 'object': return [xy, xy.y]; + case 'function': return [xy, xy(42)]; + } +} +function switchOrdering(x) { + switch (typeof x) { + case 'string': return assertString(x); + case 'number': return assertNumber(x); + case 'boolean': return assertBoolean(x); + case 'number': return assertNever(x); + } +} +function switchOrderingWithDefault(x) { + function local(y) { + return x; + } + switch (typeof x) { + case 'string': + case 'number': + default: return local(x); + case 'string': return assertNever(x); + case 'number': return assertNever(x); + } +} diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.symbols b/tests/baselines/reference/narrowingByTypeofInSwitch.symbols new file mode 100644 index 00000000000..2d1bd06baba --- /dev/null +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.symbols @@ -0,0 +1,542 @@ +=== tests/cases/compiler/narrowingByTypeofInSwitch.ts === +function assertNever(x: never) { +>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 0, 21)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 0, 21)) +} + +function assertNumber(x: number) { +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 4, 22)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 4, 22)) +} + +function assertBoolean(x: boolean) { +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 8, 23)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 8, 23)) +} + +function assertString(x: string) { +>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 12, 22)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 12, 22)) +} + +function assertSymbol(x: symbol) { +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 16, 22)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 16, 22)) +} + +function assertFunction(x: Function) { +>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 20, 24)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 20, 24)) +} + +function assertObject(x: object) { +>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 24, 22)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 24, 22)) +} + +function assertUndefined(x: undefined) { +>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 28, 25)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 28, 25)) +} + +function assertAll(x: Basic) { +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 19)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 19)) +} + +type Basic = number | boolean | string | symbol | object | Function | undefined; +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +function testUnion(x: Basic) { +>testUnion : Symbol(testUnion, Decl(narrowingByTypeofInSwitch.ts, 36, 80)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) + + case 'number': assertNumber(x); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) + + case 'boolean': assertBoolean(x); return; +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) + + case 'function': assertFunction(x); return; +>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) + + case 'symbol': assertSymbol(x); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) + + case 'object': assertObject(x); return; +>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) + + case 'string': assertString(x); return; +>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) + + case 'undefined': assertUndefined(x); return; +>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) + } + assertNever(x); +>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +} + +function testExtendsUnion(x: T) { +>testExtendsUnion : Symbol(testExtendsUnion, Decl(narrowingByTypeofInSwitch.ts, 49, 1)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 51, 26)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 51, 26)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) + + case 'number': assertNumber(x); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) + + case 'boolean': assertBoolean(x); return; +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) + + case 'function': assertAll(x); return; +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) + + case 'symbol': assertSymbol(x); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) + + case 'object': assertAll(x); return; +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) + + case 'string': assertString(x); return; +>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) + + case 'undefined': assertUndefined(x); return; +>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) + } + assertAll(x); +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +} + +function testAny(x: any) { +>testAny : Symbol(testAny, Decl(narrowingByTypeofInSwitch.ts, 62, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + + case 'number': assertNumber(x); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + + case 'boolean': assertBoolean(x); return; +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + + case 'function': assertFunction(x); return; +>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + + case 'symbol': assertSymbol(x); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + + case 'object': assertObject(x); return; +>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + + case 'string': assertString(x); return; +>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + + case 'undefined': assertUndefined(x); return; +>assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) + } + assertAll(x); // is any +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +} + +function a1(x: string | object | undefined) { +>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 77, 12)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 77, 12)) +} + +function testUnionExplicitDefault(x: Basic) { +>testUnionExplicitDefault : Symbol(testUnionExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 79, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) + + case 'number': assertNumber(x); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) + + case 'boolean': assertBoolean(x); return; +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) + + case 'function': assertFunction(x); return; +>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) + + case 'symbol': assertSymbol(x); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) + + default: a1(x); return; +>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) + } +} + +function testUnionImplicitDefault(x: Basic) { +>testUnionImplicitDefault : Symbol(testUnionImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 89, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) + + case 'number': assertNumber(x); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) + + case 'boolean': assertBoolean(x); return; +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) + + case 'function': assertFunction(x); return; +>assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) + + case 'symbol': assertSymbol(x); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) + } + return a1(x); +>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) +} + +function testExtendsExplicitDefault(x: T) { +>testExtendsExplicitDefault : Symbol(testExtendsExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 99, 1)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 101, 36)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 101, 36)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) + + case 'number': assertNumber(x); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) + + case 'boolean': assertBoolean(x); return; +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) + + case 'function': assertAll(x); return; +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) + + case 'symbol': assertSymbol(x); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) + + default: assertAll(x); return; +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) + + } +} + +function testExtendsImplicitDefault(x: T) { +>testExtendsImplicitDefault : Symbol(testExtendsImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 110, 1)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 112, 36)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 112, 36)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) + + case 'number': assertNumber(x); return; +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) + + case 'boolean': assertBoolean(x); return; +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) + + case 'function': assertAll(x); return; +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) + + case 'symbol': assertSymbol(x); return; +>assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) + } + return assertAll(x); +>assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) +} + +type L = (x: number) => string; +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 122, 10)) + +type R = { x: string, y: number } +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) +>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) + +function exhaustiveChecks(x: number | string | L | R): string { +>exhaustiveChecks : Symbol(exhaustiveChecks, Decl(narrowingByTypeofInSwitch.ts, 123, 33)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) + + case 'number': return x.toString(2); +>x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) +>toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) + + case 'string': return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) + + case 'function': return x(42); +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) + + case 'object': return x.x; +>x.x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) + } +} + +function exhaustiveChecksGenerics(x: T): string { +>exhaustiveChecksGenerics : Symbol(exhaustiveChecksGenerics, Decl(narrowingByTypeofInSwitch.ts, 132, 1)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 134, 34)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 134, 34)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) + + case 'number': return x.toString(2); +>x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --) ... and 2 more) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) +>toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --) ... and 2 more) + + case 'string': return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) + + case 'function': return (x as L)(42); // Can't narrow generic +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) + + case 'object': return (x as R).x; // Can't narrow generic +>(x as R).x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) + } +} + +function multipleGeneric(xy: X | Y): [X, string] | [Y, number] { +>multipleGeneric : Symbol(multipleGeneric, Decl(narrowingByTypeofInSwitch.ts, 141, 1)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37)) + + switch (typeof xy) { +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) + + case 'function': return [xy, xy(42)]; +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) + + case 'object': return [xy, xy.y]; +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) +>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) +>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) + + default: return assertNever(xy); +>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) + } +} + +function multipleGenericFuse(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { +>multipleGenericFuse : Symbol(multipleGenericFuse, Decl(narrowingByTypeofInSwitch.ts, 149, 1)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50)) + + switch (typeof xy) { +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) + + case 'function': return [xy, 1]; +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) + + case 'object': return [xy, 'two']; +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) + + case 'number': return [xy] +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) + } +} + +function multipleGenericExhaustive(xy: X | Y): [X, string] | [Y, number] { +>multipleGenericExhaustive : Symbol(multipleGenericExhaustive, Decl(narrowingByTypeofInSwitch.ts, 157, 1)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47)) + + switch (typeof xy) { +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) + + case 'object': return [xy, xy.y]; +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) +>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) +>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) + + case 'function': return [xy, xy(42)]; +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) + } +} + +function switchOrdering(x: string | number | boolean) { +>switchOrdering : Symbol(switchOrdering, Decl(narrowingByTypeofInSwitch.ts, 164, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) + + case 'string': return assertString(x); +>assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) + + case 'number': return assertNumber(x); +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) + + case 'boolean': return assertBoolean(x); +>assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) + + case 'number': return assertNever(x); +>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) + } +} + +function switchOrderingWithDefault(x: string | number | boolean) { +>switchOrderingWithDefault : Symbol(switchOrderingWithDefault, Decl(narrowingByTypeofInSwitch.ts, 173, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) + + function local(y: string | number | boolean) { +>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 175, 66)) +>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 176, 19)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) + } + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) + + case 'string': + case 'number': + default: return local(x) +>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 175, 66)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) + + case 'string': return assertNever(x); +>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) + + case 'number': return assertNever(x); +>assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) + } +} + diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.types b/tests/baselines/reference/narrowingByTypeofInSwitch.types new file mode 100644 index 00000000000..785bdd23609 --- /dev/null +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.types @@ -0,0 +1,695 @@ +=== tests/cases/compiler/narrowingByTypeofInSwitch.ts === +function assertNever(x: never) { +>assertNever : (x: never) => never +>x : never + + return x; +>x : never +} + +function assertNumber(x: number) { +>assertNumber : (x: number) => number +>x : number + + return x; +>x : number +} + +function assertBoolean(x: boolean) { +>assertBoolean : (x: boolean) => boolean +>x : boolean + + return x; +>x : boolean +} + +function assertString(x: string) { +>assertString : (x: string) => string +>x : string + + return x; +>x : string +} + +function assertSymbol(x: symbol) { +>assertSymbol : (x: symbol) => symbol +>x : symbol + + return x; +>x : symbol +} + +function assertFunction(x: Function) { +>assertFunction : (x: Function) => Function +>x : Function +>Function : Function + + return x; +>x : Function +} + +function assertObject(x: object) { +>assertObject : (x: object) => object +>x : object + + return x; +>x : object +} + +function assertUndefined(x: undefined) { +>assertUndefined : (x: undefined) => undefined +>x : undefined + + return x; +>x : undefined +} + +function assertAll(x: Basic) { +>assertAll : (x: Basic) => Basic +>x : Basic +>Basic : Basic + + return x; +>x : Basic +} + +type Basic = number | boolean | string | symbol | object | Function | undefined; +>Basic : Basic +>Function : Function + +function testUnion(x: Basic) { +>testUnion : (x: Basic) => void +>x : Basic +>Basic : Basic + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : Basic + + case 'number': assertNumber(x); return; +>'number' : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : number + + case 'boolean': assertBoolean(x); return; +>'boolean' : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : boolean + + case 'function': assertFunction(x); return; +>'function' : "function" +>assertFunction(x) : Function +>assertFunction : (x: Function) => Function +>x : Function + + case 'symbol': assertSymbol(x); return; +>'symbol' : "symbol" +>assertSymbol(x) : symbol +>assertSymbol : (x: symbol) => symbol +>x : symbol + + case 'object': assertObject(x); return; +>'object' : "object" +>assertObject(x) : object +>assertObject : (x: object) => object +>x : object + + case 'string': assertString(x); return; +>'string' : "string" +>assertString(x) : string +>assertString : (x: string) => string +>x : string + + case 'undefined': assertUndefined(x); return; +>'undefined' : "undefined" +>assertUndefined(x) : undefined +>assertUndefined : (x: undefined) => undefined +>x : undefined + } + assertNever(x); +>assertNever(x) : never +>assertNever : (x: never) => never +>x : never +} + +function testExtendsUnion(x: T) { +>testExtendsUnion : (x: T) => void +>T : T +>Basic : Basic +>x : T +>T : T + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : T + + case 'number': assertNumber(x); return; +>'number' : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : T & number + + case 'boolean': assertBoolean(x); return; +>'boolean' : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : (T & true) | (T & false) + + case 'function': assertAll(x); return; +>'function' : "function" +>assertAll(x) : Basic +>assertAll : (x: Basic) => Basic +>x : T + + case 'symbol': assertSymbol(x); return; +>'symbol' : "symbol" +>assertSymbol(x) : symbol +>assertSymbol : (x: symbol) => symbol +>x : T & symbol + + case 'object': assertAll(x); return; +>'object' : "object" +>assertAll(x) : Basic +>assertAll : (x: Basic) => Basic +>x : T + + case 'string': assertString(x); return; +>'string' : "string" +>assertString(x) : string +>assertString : (x: string) => string +>x : T & string + + case 'undefined': assertUndefined(x); return; +>'undefined' : "undefined" +>assertUndefined(x) : undefined +>assertUndefined : (x: undefined) => undefined +>x : T & undefined + } + assertAll(x); +>assertAll(x) : Basic +>assertAll : (x: Basic) => Basic +>x : T +} + +function testAny(x: any) { +>testAny : (x: any) => void +>x : any + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : any + + case 'number': assertNumber(x); return; +>'number' : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : number + + case 'boolean': assertBoolean(x); return; +>'boolean' : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : boolean + + case 'function': assertFunction(x); return; +>'function' : "function" +>assertFunction(x) : Function +>assertFunction : (x: Function) => Function +>x : any + + case 'symbol': assertSymbol(x); return; +>'symbol' : "symbol" +>assertSymbol(x) : symbol +>assertSymbol : (x: symbol) => symbol +>x : symbol + + case 'object': assertObject(x); return; +>'object' : "object" +>assertObject(x) : object +>assertObject : (x: object) => object +>x : any + + case 'string': assertString(x); return; +>'string' : "string" +>assertString(x) : string +>assertString : (x: string) => string +>x : string + + case 'undefined': assertUndefined(x); return; +>'undefined' : "undefined" +>assertUndefined(x) : undefined +>assertUndefined : (x: undefined) => undefined +>x : undefined + } + assertAll(x); // is any +>assertAll(x) : Basic +>assertAll : (x: Basic) => Basic +>x : any +} + +function a1(x: string | object | undefined) { +>a1 : (x: string | object | undefined) => string | object | undefined +>x : string | object | undefined + + return x; +>x : string | object | undefined +} + +function testUnionExplicitDefault(x: Basic) { +>testUnionExplicitDefault : (x: Basic) => void +>x : Basic +>Basic : Basic + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : Basic + + case 'number': assertNumber(x); return; +>'number' : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : number + + case 'boolean': assertBoolean(x); return; +>'boolean' : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : boolean + + case 'function': assertFunction(x); return; +>'function' : "function" +>assertFunction(x) : Function +>assertFunction : (x: Function) => Function +>x : Function + + case 'symbol': assertSymbol(x); return; +>'symbol' : "symbol" +>assertSymbol(x) : symbol +>assertSymbol : (x: symbol) => symbol +>x : symbol + + default: a1(x); return; +>a1(x) : string | object | undefined +>a1 : (x: string | object | undefined) => string | object | undefined +>x : string | object | undefined + } +} + +function testUnionImplicitDefault(x: Basic) { +>testUnionImplicitDefault : (x: Basic) => string | object | undefined +>x : Basic +>Basic : Basic + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : Basic + + case 'number': assertNumber(x); return; +>'number' : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : number + + case 'boolean': assertBoolean(x); return; +>'boolean' : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : boolean + + case 'function': assertFunction(x); return; +>'function' : "function" +>assertFunction(x) : Function +>assertFunction : (x: Function) => Function +>x : Function + + case 'symbol': assertSymbol(x); return; +>'symbol' : "symbol" +>assertSymbol(x) : symbol +>assertSymbol : (x: symbol) => symbol +>x : symbol + } + return a1(x); +>a1(x) : string | object | undefined +>a1 : (x: string | object | undefined) => string | object | undefined +>x : string | object | undefined +} + +function testExtendsExplicitDefault(x: T) { +>testExtendsExplicitDefault : (x: T) => void +>T : T +>Basic : Basic +>x : T +>T : T + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : T + + case 'number': assertNumber(x); return; +>'number' : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : T & number + + case 'boolean': assertBoolean(x); return; +>'boolean' : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : (T & true) | (T & false) + + case 'function': assertAll(x); return; +>'function' : "function" +>assertAll(x) : Basic +>assertAll : (x: Basic) => Basic +>x : T + + case 'symbol': assertSymbol(x); return; +>'symbol' : "symbol" +>assertSymbol(x) : symbol +>assertSymbol : (x: symbol) => symbol +>x : T & symbol + + default: assertAll(x); return; +>assertAll(x) : Basic +>assertAll : (x: Basic) => Basic +>x : T + + } +} + +function testExtendsImplicitDefault(x: T) { +>testExtendsImplicitDefault : (x: T) => string | number | boolean | symbol | object | undefined +>T : T +>Basic : Basic +>x : T +>T : T + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : T + + case 'number': assertNumber(x); return; +>'number' : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : T & number + + case 'boolean': assertBoolean(x); return; +>'boolean' : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : (T & true) | (T & false) + + case 'function': assertAll(x); return; +>'function' : "function" +>assertAll(x) : Basic +>assertAll : (x: Basic) => Basic +>x : T + + case 'symbol': assertSymbol(x); return; +>'symbol' : "symbol" +>assertSymbol(x) : symbol +>assertSymbol : (x: symbol) => symbol +>x : T & symbol + } + return assertAll(x); +>assertAll(x) : Basic +>assertAll : (x: Basic) => Basic +>x : T +} + +type L = (x: number) => string; +>L : L +>x : number + +type R = { x: string, y: number } +>R : R +>x : string +>y : number + +function exhaustiveChecks(x: number | string | L | R): string { +>exhaustiveChecks : (x: string | number | R | L) => string +>x : string | number | R | L +>L : L +>R : R + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : string | number | R | L + + case 'number': return x.toString(2); +>'number' : "number" +>x.toString(2) : string +>x.toString : (radix?: number | undefined) => string +>x : number +>toString : (radix?: number | undefined) => string +>2 : 2 + + case 'string': return x; +>'string' : "string" +>x : string + + case 'function': return x(42); +>'function' : "function" +>x(42) : string +>x : L +>42 : 42 + + case 'object': return x.x; +>'object' : "object" +>x.x : string +>x : R +>x : string + } +} + +function exhaustiveChecksGenerics(x: T): string { +>exhaustiveChecksGenerics : (x: T) => string +>T : T +>L : L +>R : R +>x : T +>T : T + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : T + + case 'number': return x.toString(2); +>'number' : "number" +>x.toString(2) : string +>x.toString : ((radix?: number | undefined) => string) | ((() => string) & ((radix?: number | undefined) => string)) | ((() => string) & ((radix?: number | undefined) => string)) | ((() => string) & ((radix?: number | undefined) => string)) +>x : T & number +>toString : ((radix?: number | undefined) => string) | ((() => string) & ((radix?: number | undefined) => string)) | ((() => string) & ((radix?: number | undefined) => string)) | ((() => string) & ((radix?: number | undefined) => string)) +>2 : 2 + + case 'string': return x; +>'string' : "string" +>x : T & string + + case 'function': return (x as L)(42); // Can't narrow generic +>'function' : "function" +>(x as L)(42) : string +>(x as L) : L +>x as L : L +>x : T +>L : L +>42 : 42 + + case 'object': return (x as R).x; // Can't narrow generic +>'object' : "object" +>(x as R).x : string +>(x as R) : R +>x as R : R +>x : T +>R : R +>x : string + } +} + +function multipleGeneric(xy: X | Y): [X, string] | [Y, number] { +>multipleGeneric : (xy: X | Y) => [X, string] | [Y, number] +>X : X +>L : L +>Y : Y +>R : R +>xy : X | Y +>X : X +>Y : Y +>X : X +>Y : Y + + switch (typeof xy) { +>typeof xy : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>xy : X | Y + + case 'function': return [xy, xy(42)]; +>'function' : "function" +>[xy, xy(42)] : [X, string] +>xy : X +>xy(42) : string +>xy : X +>42 : 42 + + case 'object': return [xy, xy.y]; +>'object' : "object" +>[xy, xy.y] : [Y, number] +>xy : Y +>xy.y : number +>xy : Y +>y : number + + default: return assertNever(xy); +>assertNever(xy) : never +>assertNever : (x: never) => never +>xy : never + } +} + +function multipleGenericFuse(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { +>multipleGenericFuse : (xy: X | Y) => [X, number] | [Y, string] | [X | Y] +>X : X +>L : L +>Y : Y +>R : R +>xy : X | Y +>X : X +>Y : Y +>X : X +>Y : Y +>X : X +>Y : Y + + switch (typeof xy) { +>typeof xy : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>xy : X | Y + + case 'function': return [xy, 1]; +>'function' : "function" +>[xy, 1] : [X, number] +>xy : X +>1 : 1 + + case 'object': return [xy, 'two']; +>'object' : "object" +>[xy, 'two'] : [Y, string] +>xy : Y +>'two' : "two" + + case 'number': return [xy] +>'number' : "number" +>[xy] : [X | Y] +>xy : X | Y + } +} + +function multipleGenericExhaustive(xy: X | Y): [X, string] | [Y, number] { +>multipleGenericExhaustive : (xy: X | Y) => [X, string] | [Y, number] +>X : X +>L : L +>Y : Y +>R : R +>xy : X | Y +>X : X +>Y : Y +>X : X +>Y : Y + + switch (typeof xy) { +>typeof xy : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>xy : X | Y + + case 'object': return [xy, xy.y]; +>'object' : "object" +>[xy, xy.y] : [Y, number] +>xy : Y +>xy.y : number +>xy : Y +>y : number + + case 'function': return [xy, xy(42)]; +>'function' : "function" +>[xy, xy(42)] : [X, string] +>xy : X +>xy(42) : string +>xy : X +>42 : 42 + } +} + +function switchOrdering(x: string | number | boolean) { +>switchOrdering : (x: string | number | boolean) => string | number | boolean +>x : string | number | boolean + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : string | number | boolean + + case 'string': return assertString(x); +>'string' : "string" +>assertString(x) : string +>assertString : (x: string) => string +>x : string + + case 'number': return assertNumber(x); +>'number' : "number" +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : number + + case 'boolean': return assertBoolean(x); +>'boolean' : "boolean" +>assertBoolean(x) : boolean +>assertBoolean : (x: boolean) => boolean +>x : boolean + + case 'number': return assertNever(x); +>'number' : "number" +>assertNever(x) : never +>assertNever : (x: never) => never +>x : never + } +} + +function switchOrderingWithDefault(x: string | number | boolean) { +>switchOrderingWithDefault : (x: string | number | boolean) => string | number | boolean +>x : string | number | boolean + + function local(y: string | number | boolean) { +>local : (y: string | number | boolean) => string | number | boolean +>y : string | number | boolean + + return x; +>x : string | number | boolean + } + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : string | number | boolean + + case 'string': +>'string' : "string" + + case 'number': +>'number' : "number" + + default: return local(x) +>local(x) : string | number | boolean +>local : (y: string | number | boolean) => string | number | boolean +>x : string | number | boolean + + case 'string': return assertNever(x); +>'string' : "string" +>assertNever(x) : never +>assertNever : (x: never) => never +>x : never + + case 'number': return assertNever(x); +>'number' : "number" +>assertNever(x) : never +>assertNever : (x: never) => never +>x : never + } +} + diff --git a/tests/cases/compiler/narrowingByTypeofInSwitch.ts b/tests/cases/compiler/narrowingByTypeofInSwitch.ts new file mode 100644 index 00000000000..aadd351b87e --- /dev/null +++ b/tests/cases/compiler/narrowingByTypeofInSwitch.ts @@ -0,0 +1,190 @@ +// @strictNullChecks: true +// @strictFunctionTypes: true + +function assertNever(x: never) { + return x; +} + +function assertNumber(x: number) { + return x; +} + +function assertBoolean(x: boolean) { + return x; +} + +function assertString(x: string) { + return x; +} + +function assertSymbol(x: symbol) { + return x; +} + +function assertFunction(x: Function) { + return x; +} + +function assertObject(x: object) { + return x; +} + +function assertUndefined(x: undefined) { + return x; +} + +function assertAll(x: Basic) { + return x; +} + +type Basic = number | boolean | string | symbol | object | Function | undefined; + +function testUnion(x: Basic) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertFunction(x); return; + case 'symbol': assertSymbol(x); return; + case 'object': assertObject(x); return; + case 'string': assertString(x); return; + case 'undefined': assertUndefined(x); return; + } + assertNever(x); +} + +function testExtendsUnion(x: T) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertAll(x); return; + case 'symbol': assertSymbol(x); return; + case 'object': assertAll(x); return; + case 'string': assertString(x); return; + case 'undefined': assertUndefined(x); return; + } + assertAll(x); +} + +function testAny(x: any) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertFunction(x); return; + case 'symbol': assertSymbol(x); return; + case 'object': assertObject(x); return; + case 'string': assertString(x); return; + case 'undefined': assertUndefined(x); return; + } + assertAll(x); // is any +} + +function a1(x: string | object | undefined) { + return x; +} + +function testUnionExplicitDefault(x: Basic) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertFunction(x); return; + case 'symbol': assertSymbol(x); return; + default: a1(x); return; + } +} + +function testUnionImplicitDefault(x: Basic) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertFunction(x); return; + case 'symbol': assertSymbol(x); return; + } + return a1(x); +} + +function testExtendsExplicitDefault(x: T) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertAll(x); return; + case 'symbol': assertSymbol(x); return; + default: assertAll(x); return; + + } +} + +function testExtendsImplicitDefault(x: T) { + switch (typeof x) { + case 'number': assertNumber(x); return; + case 'boolean': assertBoolean(x); return; + case 'function': assertAll(x); return; + case 'symbol': assertSymbol(x); return; + } + return assertAll(x); +} + +type L = (x: number) => string; +type R = { x: string, y: number } + +function exhaustiveChecks(x: number | string | L | R): string { + switch (typeof x) { + case 'number': return x.toString(2); + case 'string': return x; + case 'function': return x(42); + case 'object': return x.x; + } +} + +function exhaustiveChecksGenerics(x: T): string { + switch (typeof x) { + case 'number': return x.toString(2); + case 'string': return x; + case 'function': return (x as L)(42); // Can't narrow generic + case 'object': return (x as R).x; // Can't narrow generic + } +} + +function multipleGeneric(xy: X | Y): [X, string] | [Y, number] { + switch (typeof xy) { + case 'function': return [xy, xy(42)]; + case 'object': return [xy, xy.y]; + default: return assertNever(xy); + } +} + +function multipleGenericFuse(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { + switch (typeof xy) { + case 'function': return [xy, 1]; + case 'object': return [xy, 'two']; + case 'number': return [xy] + } +} + +function multipleGenericExhaustive(xy: X | Y): [X, string] | [Y, number] { + switch (typeof xy) { + case 'object': return [xy, xy.y]; + case 'function': return [xy, xy(42)]; + } +} + +function switchOrdering(x: string | number | boolean) { + switch (typeof x) { + case 'string': return assertString(x); + case 'number': return assertNumber(x); + case 'boolean': return assertBoolean(x); + case 'number': return assertNever(x); + } +} + +function switchOrderingWithDefault(x: string | number | boolean) { + function local(y: string | number | boolean) { + return x; + } + switch (typeof x) { + case 'string': + case 'number': + default: return local(x) + case 'string': return assertNever(x); + case 'number': return assertNever(x); + } +} From 9e43183884825fa3b17359ac167fdaa6aacb2530 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Wed, 23 May 2018 01:03:04 +0100 Subject: [PATCH 003/163] Add fall-through test and correct comment about implied type --- src/compiler/checker.ts | 19 +- .../reference/narrowingByTypeofInSwitch.js | 45 ++ .../narrowingByTypeofInSwitch.symbols | 415 ++++++++++-------- .../reference/narrowingByTypeofInSwitch.types | 62 +++ .../compiler/narrowingByTypeofInSwitch.ts | 24 + 5 files changed, 375 insertions(+), 190 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ab2cc1f3b85..1629717ff28 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13594,10 +13594,10 @@ namespace ts { // } // // The implied type of the first clause number | string. - // The implied type of the second clause is string (but this doesn't get used). + // The implied type of the second clause is never, but this does not get just because it includes a default case. // The implied type of the third clause is boolean (number has already be caught). if (!(hasDefaultClause || (type.flags & TypeFlags.Union))) { - let impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(text => typeofTypesByName.get(text) || neverType)), switchFacts); + let impliedType = getTypeWithFacts(getUnionType((clauseWitnesses).map(text => typeofTypesByName.get(text) || neverType)), switchFacts); if (impliedType.flags & TypeFlags.Union) { impliedType = getAssignmentReducedType(impliedType as UnionType, getBaseConstraintOfType(type) || type); } @@ -19027,17 +19027,20 @@ namespace ts { if (hasDefault) { // Value is not equal to any types after the active clause. for (let i = end; i < witnesses.length; i++) { - facts |= typeofNEFacts.get(witnesses[i]) || TypeFacts.TypeofNEHostObject; + const witness = witnesses[i]; + facts |= (witness && typeofNEFacts.get(witness)) || TypeFacts.TypeofNEHostObject; } // Remove inequalities for types that appear in the // active clause because they appear before other // types collected so far. for (let i = start; i < end; i++) { - facts &= ~(typeofNEFacts.get(witnesses[i]) || 0); + const witness = witnesses[i]; + facts &= ~((witness && typeofNEFacts.get(witness)) || 0); } // Add inequalities for types before the active clause unconditionally. for (let i = 0; i < start; i++) { - facts |= typeofNEFacts.get(witnesses[i]) || TypeFacts.TypeofNEHostObject; + const witness = witnesses[i]; + facts |= (witness && typeofNEFacts.get(witness)) || TypeFacts.TypeofNEHostObject; } } // When in an active clause without default the set of @@ -19045,12 +19048,14 @@ namespace ts { else { // Add equalities for all types in the active clause. for (let i = start; i < end; i++) { - facts |= typeofEQFacts.get(witnesses[i]) || TypeFacts.TypeofEQHostObject; + const witness = witnesses[i]; + facts |= (witness && typeofEQFacts.get(witness)) || TypeFacts.TypeofEQHostObject; } // Remove equalities for types that appear before the // active clause. for (let i = 0; i < start; i++) { - facts &= ~(typeofEQFacts.get(witnesses[i]) || 0); + const witness = witnesses[i]; + facts &= ~((witness && typeofEQFacts.get(witness)) || 0); } } return facts; diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.js b/tests/baselines/reference/narrowingByTypeofInSwitch.js index 2cf4b9027c2..95ec120a85d 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.js +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.js @@ -35,6 +35,14 @@ function assertAll(x: Basic) { return x; } +function assertStringOrNumber(x: string | number) { + return x; +} + +function assertBooleanOrObject(x: boolean | object) { + return x; +} + type Basic = number | boolean | string | symbol | object | Function | undefined; function testUnion(x: Basic) { @@ -186,6 +194,22 @@ function switchOrderingWithDefault(x: string | number | boolean) { case 'number': return assertNever(x); } } + +function fallThroughTest(x: string | number | boolean | object) { + switch (typeof x) { + case 'number': + assertNumber(x) + case 'string': + assertStringOrNumber(x) + break; + default: + assertObject(x); + case 'number': + case 'boolean': + assertBooleanOrObject(x); + break; + } +} //// [narrowingByTypeofInSwitch.js] @@ -216,6 +240,12 @@ function assertUndefined(x) { function assertAll(x) { return x; } +function assertStringOrNumber(x) { + return x; +} +function assertBooleanOrObject(x) { + return x; +} function testUnion(x) { switch (typeof x) { case 'number': @@ -425,3 +455,18 @@ function switchOrderingWithDefault(x) { case 'number': return assertNever(x); } } +function fallThroughTest(x) { + switch (typeof x) { + case 'number': + assertNumber(x); + case 'string': + assertStringOrNumber(x); + break; + default: + assertObject(x); + case 'number': + case 'boolean': + assertBooleanOrObject(x); + break; + } +} diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.symbols b/tests/baselines/reference/narrowingByTypeofInSwitch.symbols index 2d1bd06baba..b451b39ac7c 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.symbols +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.symbols @@ -67,476 +67,525 @@ function assertUndefined(x: undefined) { function assertAll(x: Basic) { >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 19)) ->Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) return x; >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 32, 19)) } +function assertStringOrNumber(x: string | number) { +>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 36, 30)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 36, 30)) +} + +function assertBooleanOrObject(x: boolean | object) { +>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 38, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 40, 31)) + + return x; +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 40, 31)) +} + type Basic = number | boolean | string | symbol | object | Function | undefined; ->Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) >Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) function testUnion(x: Basic) { ->testUnion : Symbol(testUnion, Decl(narrowingByTypeofInSwitch.ts, 36, 80)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) ->Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>testUnion : Symbol(testUnion, Decl(narrowingByTypeofInSwitch.ts, 44, 80)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) case 'number': assertNumber(x); return; >assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) case 'boolean': assertBoolean(x); return; >assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) case 'function': assertFunction(x); return; >assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) case 'symbol': assertSymbol(x); return; >assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) case 'object': assertObject(x); return; >assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) case 'string': assertString(x); return; >assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) case 'undefined': assertUndefined(x); return; >assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) } assertNever(x); >assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 38, 19)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 46, 19)) } function testExtendsUnion(x: T) { ->testExtendsUnion : Symbol(testExtendsUnion, Decl(narrowingByTypeofInSwitch.ts, 49, 1)) ->T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 51, 26)) ->Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) ->T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 51, 26)) +>testExtendsUnion : Symbol(testExtendsUnion, Decl(narrowingByTypeofInSwitch.ts, 57, 1)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 59, 26)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 59, 26)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) case 'number': assertNumber(x); return; >assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) case 'boolean': assertBoolean(x); return; >assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) case 'function': assertAll(x); return; >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) case 'symbol': assertSymbol(x); return; >assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) case 'object': assertAll(x); return; >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) case 'string': assertString(x); return; >assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) case 'undefined': assertUndefined(x); return; >assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) } assertAll(x); >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 51, 43)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 59, 43)) } function testAny(x: any) { ->testAny : Symbol(testAny, Decl(narrowingByTypeofInSwitch.ts, 62, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>testAny : Symbol(testAny, Decl(narrowingByTypeofInSwitch.ts, 70, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) case 'number': assertNumber(x); return; >assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) case 'boolean': assertBoolean(x); return; >assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) case 'function': assertFunction(x); return; >assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) case 'symbol': assertSymbol(x); return; >assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) case 'object': assertObject(x); return; >assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) case 'string': assertString(x); return; >assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) case 'undefined': assertUndefined(x); return; >assertUndefined : Symbol(assertUndefined, Decl(narrowingByTypeofInSwitch.ts, 26, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) } assertAll(x); // is any >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 64, 17)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 72, 17)) } function a1(x: string | object | undefined) { ->a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 77, 12)) +>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 85, 12)) return x; ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 77, 12)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 85, 12)) } function testUnionExplicitDefault(x: Basic) { ->testUnionExplicitDefault : Symbol(testUnionExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 79, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) ->Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>testUnionExplicitDefault : Symbol(testUnionExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 87, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34)) case 'number': assertNumber(x); return; >assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34)) case 'boolean': assertBoolean(x); return; >assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34)) case 'function': assertFunction(x); return; >assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34)) case 'symbol': assertSymbol(x); return; >assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34)) default: a1(x); return; ->a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 81, 34)) +>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 89, 34)) } } function testUnionImplicitDefault(x: Basic) { ->testUnionImplicitDefault : Symbol(testUnionImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 89, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) ->Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>testUnionImplicitDefault : Symbol(testUnionImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 97, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34)) case 'number': assertNumber(x); return; >assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34)) case 'boolean': assertBoolean(x); return; >assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34)) case 'function': assertFunction(x); return; >assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34)) case 'symbol': assertSymbol(x); return; >assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34)) } return a1(x); ->a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 75, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 91, 34)) +>a1 : Symbol(a1, Decl(narrowingByTypeofInSwitch.ts, 83, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 99, 34)) } function testExtendsExplicitDefault(x: T) { ->testExtendsExplicitDefault : Symbol(testExtendsExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 99, 1)) ->T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 101, 36)) ->Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) ->T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 101, 36)) +>testExtendsExplicitDefault : Symbol(testExtendsExplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 107, 1)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 109, 36)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 109, 36)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53)) case 'number': assertNumber(x); return; >assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53)) case 'boolean': assertBoolean(x); return; >assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53)) case 'function': assertAll(x); return; >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53)) case 'symbol': assertSymbol(x); return; >assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53)) default: assertAll(x); return; >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 101, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 109, 53)) } } function testExtendsImplicitDefault(x: T) { ->testExtendsImplicitDefault : Symbol(testExtendsImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 110, 1)) ->T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 112, 36)) ->Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) ->T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 112, 36)) +>testExtendsImplicitDefault : Symbol(testExtendsImplicitDefault, Decl(narrowingByTypeofInSwitch.ts, 118, 1)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 120, 36)) +>Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 120, 36)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53)) case 'number': assertNumber(x); return; >assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53)) case 'boolean': assertBoolean(x); return; >assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53)) case 'function': assertAll(x); return; >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53)) case 'symbol': assertSymbol(x); return; >assertSymbol : Symbol(assertSymbol, Decl(narrowingByTypeofInSwitch.ts, 14, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53)) } return assertAll(x); >assertAll : Symbol(assertAll, Decl(narrowingByTypeofInSwitch.ts, 30, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 112, 53)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 120, 53)) } type L = (x: number) => string; ->L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 122, 10)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 130, 10)) type R = { x: string, y: number } ->R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) ->y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10)) +>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21)) function exhaustiveChecks(x: number | string | L | R): string { ->exhaustiveChecks : Symbol(exhaustiveChecks, Decl(narrowingByTypeofInSwitch.ts, 123, 33)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) ->L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) ->R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) +>exhaustiveChecks : Symbol(exhaustiveChecks, Decl(narrowingByTypeofInSwitch.ts, 131, 33)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) case 'number': return x.toString(2); >x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) >toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) case 'string': return x; ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) case 'function': return x(42); ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) case 'object': return x.x; ->x.x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 125, 26)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) +>x.x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10)) } } function exhaustiveChecksGenerics(x: T): string { ->exhaustiveChecksGenerics : Symbol(exhaustiveChecksGenerics, Decl(narrowingByTypeofInSwitch.ts, 132, 1)) ->T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 134, 34)) ->L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) ->R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) ->T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 134, 34)) +>exhaustiveChecksGenerics : Symbol(exhaustiveChecksGenerics, Decl(narrowingByTypeofInSwitch.ts, 140, 1)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 142, 34)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) +>T : Symbol(T, Decl(narrowingByTypeofInSwitch.ts, 142, 34)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) case 'number': return x.toString(2); >x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --) ... and 2 more) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) >toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --) ... and 2 more) case 'string': return x; ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) case 'function': return (x as L)(42); // Can't narrow generic ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) ->L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1)) case 'object': return (x as R).x; // Can't narrow generic ->(x as R).x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 134, 69)) ->R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 123, 10)) +>(x as R).x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 131, 10)) } } function multipleGeneric(xy: X | Y): [X, string] | [Y, number] { ->multipleGeneric : Symbol(multipleGeneric, Decl(narrowingByTypeofInSwitch.ts, 141, 1)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25)) ->L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37)) ->R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 143, 25)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 143, 37)) +>multipleGeneric : Symbol(multipleGeneric, Decl(narrowingByTypeofInSwitch.ts, 149, 1)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 25)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 37)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 25)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 37)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 25)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 37)) switch (typeof xy) { ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51)) case 'function': return [xy, xy(42)]; ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51)) case 'object': return [xy, xy.y]; ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) ->xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) ->y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51)) +>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51)) +>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21)) default: return assertNever(xy); >assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 143, 51)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 51)) } } function multipleGenericFuse(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { ->multipleGenericFuse : Symbol(multipleGenericFuse, Decl(narrowingByTypeofInSwitch.ts, 149, 1)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29)) ->L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50)) ->R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 151, 29)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 151, 50)) +>multipleGenericFuse : Symbol(multipleGenericFuse, Decl(narrowingByTypeofInSwitch.ts, 157, 1)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 29)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 50)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 29)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 50)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 29)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 50)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 29)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 50)) switch (typeof xy) { ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73)) case 'function': return [xy, 1]; ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73)) case 'object': return [xy, 'two']; ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73)) case 'number': return [xy] ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 151, 73)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 73)) } } function multipleGenericExhaustive(xy: X | Y): [X, string] | [Y, number] { ->multipleGenericExhaustive : Symbol(multipleGenericExhaustive, Decl(narrowingByTypeofInSwitch.ts, 157, 1)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35)) ->L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 120, 1)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47)) ->R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 122, 31)) ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47)) ->X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 159, 35)) ->Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 159, 47)) +>multipleGenericExhaustive : Symbol(multipleGenericExhaustive, Decl(narrowingByTypeofInSwitch.ts, 165, 1)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 167, 35)) +>L : Symbol(L, Decl(narrowingByTypeofInSwitch.ts, 128, 1)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 167, 47)) +>R : Symbol(R, Decl(narrowingByTypeofInSwitch.ts, 130, 31)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 167, 35)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 167, 47)) +>X : Symbol(X, Decl(narrowingByTypeofInSwitch.ts, 167, 35)) +>Y : Symbol(Y, Decl(narrowingByTypeofInSwitch.ts, 167, 47)) switch (typeof xy) { ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61)) case 'object': return [xy, xy.y]; ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) ->xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) ->y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 123, 21)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61)) +>xy.y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61)) +>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 131, 21)) case 'function': return [xy, xy(42)]; ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) ->xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 159, 61)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61)) +>xy : Symbol(xy, Decl(narrowingByTypeofInSwitch.ts, 167, 61)) } } function switchOrdering(x: string | number | boolean) { ->switchOrdering : Symbol(switchOrdering, Decl(narrowingByTypeofInSwitch.ts, 164, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) +>switchOrdering : Symbol(switchOrdering, Decl(narrowingByTypeofInSwitch.ts, 172, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24)) switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24)) case 'string': return assertString(x); >assertString : Symbol(assertString, Decl(narrowingByTypeofInSwitch.ts, 10, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24)) case 'number': return assertNumber(x); >assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24)) case 'boolean': return assertBoolean(x); >assertBoolean : Symbol(assertBoolean, Decl(narrowingByTypeofInSwitch.ts, 6, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24)) case 'number': return assertNever(x); >assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 166, 24)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 174, 24)) } } function switchOrderingWithDefault(x: string | number | boolean) { ->switchOrderingWithDefault : Symbol(switchOrderingWithDefault, Decl(narrowingByTypeofInSwitch.ts, 173, 1)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) +>switchOrderingWithDefault : Symbol(switchOrderingWithDefault, Decl(narrowingByTypeofInSwitch.ts, 181, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35)) function local(y: string | number | boolean) { ->local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 175, 66)) ->y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 176, 19)) +>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 183, 66)) +>y : Symbol(y, Decl(narrowingByTypeofInSwitch.ts, 184, 19)) return x; ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35)) } switch (typeof x) { ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35)) case 'string': case 'number': default: return local(x) ->local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 175, 66)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) +>local : Symbol(local, Decl(narrowingByTypeofInSwitch.ts, 183, 66)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35)) case 'string': return assertNever(x); >assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35)) case 'number': return assertNever(x); >assertNever : Symbol(assertNever, Decl(narrowingByTypeofInSwitch.ts, 0, 0)) ->x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 175, 35)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 183, 35)) + } +} + +function fallThroughTest(x: string | number | boolean | object) { +>fallThroughTest : Symbol(fallThroughTest, Decl(narrowingByTypeofInSwitch.ts, 194, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25)) + + switch (typeof x) { +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25)) + + case 'number': + assertNumber(x) +>assertNumber : Symbol(assertNumber, Decl(narrowingByTypeofInSwitch.ts, 2, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25)) + + case 'string': + assertStringOrNumber(x) +>assertStringOrNumber : Symbol(assertStringOrNumber, Decl(narrowingByTypeofInSwitch.ts, 34, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25)) + + break; + default: + assertObject(x); +>assertObject : Symbol(assertObject, Decl(narrowingByTypeofInSwitch.ts, 22, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25)) + + case 'number': + case 'boolean': + assertBooleanOrObject(x); +>assertBooleanOrObject : Symbol(assertBooleanOrObject, Decl(narrowingByTypeofInSwitch.ts, 38, 1)) +>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 196, 25)) + + break; } } diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.types b/tests/baselines/reference/narrowingByTypeofInSwitch.types index 785bdd23609..8672f4c9e7d 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.types +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.types @@ -73,6 +73,22 @@ function assertAll(x: Basic) { >x : Basic } +function assertStringOrNumber(x: string | number) { +>assertStringOrNumber : (x: string | number) => string | number +>x : string | number + + return x; +>x : string | number +} + +function assertBooleanOrObject(x: boolean | object) { +>assertBooleanOrObject : (x: boolean | object) => boolean | object +>x : boolean | object + + return x; +>x : boolean | object +} + type Basic = number | boolean | string | symbol | object | Function | undefined; >Basic : Basic >Function : Function @@ -693,3 +709,49 @@ function switchOrderingWithDefault(x: string | number | boolean) { } } +function fallThroughTest(x: string | number | boolean | object) { +>fallThroughTest : (x: string | number | boolean | object) => void +>x : string | number | boolean | object + + switch (typeof x) { +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : string | number | boolean | object + + case 'number': +>'number' : "number" + + assertNumber(x) +>assertNumber(x) : number +>assertNumber : (x: number) => number +>x : number + + case 'string': +>'string' : "string" + + assertStringOrNumber(x) +>assertStringOrNumber(x) : string | number +>assertStringOrNumber : (x: string | number) => string | number +>x : string | number + + break; + default: + assertObject(x); +>assertObject(x) : object +>assertObject : (x: object) => object +>x : object + + case 'number': +>'number' : "number" + + case 'boolean': +>'boolean' : "boolean" + + assertBooleanOrObject(x); +>assertBooleanOrObject(x) : boolean | object +>assertBooleanOrObject : (x: boolean | object) => boolean | object +>x : boolean | object + + break; + } +} + diff --git a/tests/cases/compiler/narrowingByTypeofInSwitch.ts b/tests/cases/compiler/narrowingByTypeofInSwitch.ts index aadd351b87e..252c1d9445a 100644 --- a/tests/cases/compiler/narrowingByTypeofInSwitch.ts +++ b/tests/cases/compiler/narrowingByTypeofInSwitch.ts @@ -37,6 +37,14 @@ function assertAll(x: Basic) { return x; } +function assertStringOrNumber(x: string | number) { + return x; +} + +function assertBooleanOrObject(x: boolean | object) { + return x; +} + type Basic = number | boolean | string | symbol | object | Function | undefined; function testUnion(x: Basic) { @@ -188,3 +196,19 @@ function switchOrderingWithDefault(x: string | number | boolean) { case 'number': return assertNever(x); } } + +function fallThroughTest(x: string | number | boolean | object) { + switch (typeof x) { + case 'number': + assertNumber(x) + case 'string': + assertStringOrNumber(x) + break; + default: + assertObject(x); + case 'number': + case 'boolean': + assertBooleanOrObject(x); + break; + } +} From 6391742dca16cdddbf5a9fd5a5a42c216a80f92f Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Wed, 23 May 2018 03:12:50 +0100 Subject: [PATCH 004/163] Make undefined for default case less pervasive by removing once done with it --- src/compiler/checker.ts | 50 ++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1629717ff28..25a9039009e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13572,10 +13572,27 @@ namespace ts { if (!switchWitnesses.length) { return type; } - const clauseWitnesses = switchWitnesses.slice(clauseStart, clauseEnd); // Equal start and end denotes implicit fallthrough; undefined marks explicit default clause - const hasDefaultClause = clauseStart === clauseEnd || contains(clauseWitnesses, /*explicitDefaultStatement*/ undefined); - const switchFacts = getFactsFromTypeofSwitch(clauseStart, clauseEnd, switchWitnesses, hasDefaultClause); + const defaultCaseLocation = findIndex(switchWitnesses, elem => elem === undefined); + const hasDefaultClause = clauseStart === clauseEnd || (defaultCaseLocation >= clauseStart && defaultCaseLocation < clauseEnd); + let clauseWitnesses: string[]; + let switchFacts: TypeFacts; + if (defaultCaseLocation > -1) { + // We no longer need the undefined denoting an + // explicit default case. Remove the undefined and + // fix-up clauseStart and clauseEnd. This means + // that we don't have to worry about undefined + // in the witness array. + const witnesses = switchWitnesses.filter(witness => witness !== undefined); + const fixedClauseStart = defaultCaseLocation < clauseStart ? clauseStart - 1 : clauseStart; + const fixedClauseEnd = defaultCaseLocation < clauseEnd ? clauseEnd - 1 : clauseEnd; + clauseWitnesses = witnesses.slice(fixedClauseStart, fixedClauseEnd); + switchFacts = getFactsFromTypeofSwitch(fixedClauseStart, fixedClauseEnd, witnesses, hasDefaultClause); + } + else { + clauseWitnesses = switchWitnesses.slice(clauseStart, clauseEnd); + switchFacts = getFactsFromTypeofSwitch(clauseStart, clauseEnd, switchWitnesses, hasDefaultClause); + } // The implied type is the raw type suggested by a // value being caught in this clause. // - If there is a default the implied type is not used. @@ -13594,10 +13611,10 @@ namespace ts { // } // // The implied type of the first clause number | string. - // The implied type of the second clause is never, but this does not get just because it includes a default case. + // The implied type of the second clause is never, but this does not get used because it includes a default case. // The implied type of the third clause is boolean (number has already be caught). if (!(hasDefaultClause || (type.flags & TypeFlags.Union))) { - let impliedType = getTypeWithFacts(getUnionType((clauseWitnesses).map(text => typeofTypesByName.get(text) || neverType)), switchFacts); + let impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(text => typeofTypesByName.get(text) || neverType)), switchFacts); if (impliedType.flags & TypeFlags.Union) { impliedType = getAssignmentReducedType(impliedType as UnionType, getBaseConstraintOfType(type) || type); } @@ -19019,7 +19036,7 @@ namespace ts { * from `start` to `end`. Parameter `hasDefault` denotes * whether the active clause contains a default clause. */ - function getFactsFromTypeofSwitch(start: number, end: number, witnesses: (string | undefined)[], hasDefault: boolean): TypeFacts { + function getFactsFromTypeofSwitch(start: number, end: number, witnesses: string[], hasDefault: boolean): TypeFacts { let facts: TypeFacts = TypeFacts.None; // When in the default we only collect inequality facts // because default is 'in theory' a set of infinite @@ -19027,20 +19044,17 @@ namespace ts { if (hasDefault) { // Value is not equal to any types after the active clause. for (let i = end; i < witnesses.length; i++) { - const witness = witnesses[i]; - facts |= (witness && typeofNEFacts.get(witness)) || TypeFacts.TypeofNEHostObject; + facts |= typeofNEFacts.get(witnesses[i]) || TypeFacts.TypeofNEHostObject; } // Remove inequalities for types that appear in the // active clause because they appear before other // types collected so far. for (let i = start; i < end; i++) { - const witness = witnesses[i]; - facts &= ~((witness && typeofNEFacts.get(witness)) || 0); + facts &= ~(typeofNEFacts.get(witnesses[i]) || 0); } // Add inequalities for types before the active clause unconditionally. for (let i = 0; i < start; i++) { - const witness = witnesses[i]; - facts |= (witness && typeofNEFacts.get(witness)) || TypeFacts.TypeofNEHostObject; + facts |= typeofNEFacts.get(witnesses[i]) || TypeFacts.TypeofNEHostObject; } } // When in an active clause without default the set of @@ -19048,14 +19062,12 @@ namespace ts { else { // Add equalities for all types in the active clause. for (let i = start; i < end; i++) { - const witness = witnesses[i]; - facts |= (witness && typeofEQFacts.get(witness)) || TypeFacts.TypeofEQHostObject; + facts |= typeofEQFacts.get(witnesses[i]) || TypeFacts.TypeofEQHostObject; } // Remove equalities for types that appear before the // active clause. for (let i = 0; i < start; i++) { - const witness = witnesses[i]; - facts &= ~((witness && typeofEQFacts.get(witness)) || 0); + facts &= ~(typeofEQFacts.get(witnesses[i]) || 0); } } return facts; @@ -19067,8 +19079,10 @@ namespace ts { } if (node.expression.kind === SyntaxKind.TypeOfExpression) { const operandType = getTypeOfExpression((node.expression as TypeOfExpression).expression); - // Type is not equal to every type in the switch. - const notEqualFacts = getFactsFromTypeofSwitch(0, 0, getSwitchClauseTypeOfWitnesses(node), /*hasDefault*/ true); + // This cast is safe because the switch is possibly exhaustive and does not contain a default case, so there can be no undefined. + const witnesses = getSwitchClauseTypeOfWitnesses(node); + // notEqualFacts states that the type of the switched value is not equal to every type in the switch. + const notEqualFacts = getFactsFromTypeofSwitch(0, 0, witnesses, /*hasDefault*/ true); const type = getBaseConstraintOfType(operandType) || operandType; return !!(filterType(type, t => (getTypeFacts(t) & notEqualFacts) === notEqualFacts).flags & TypeFlags.Never); } From 4d8529c9eb6c1cab39eabe4636525d4e79cfdc70 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Wed, 11 Jul 2018 11:00:44 +0100 Subject: [PATCH 005/163] Improve comments in narrowBySwitchOnTypeOf --- src/compiler/checker.ts | 51 +++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 25a9039009e..539430c2642 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12840,6 +12840,8 @@ namespace ts { return links.switchTypes; } + // Get the types from all cases in a switch on `typeof`. An + // `undefined` element denotes an explicit `default` clause. function getSwitchClauseTypeOfWitnesses(switchStatement: SwitchStatement): (string | undefined)[] { const witnesses: (string | undefined)[] = []; for (const clause of switchStatement.caseBlock.clauses) { @@ -13584,6 +13586,7 @@ namespace ts { // that we don't have to worry about undefined // in the witness array. const witnesses = switchWitnesses.filter(witness => witness !== undefined); + // The adjust clause start and end after removing the `default` statement. const fixedClauseStart = defaultCaseLocation < clauseStart ? clauseStart - 1 : clauseStart; const fixedClauseEnd = defaultCaseLocation < clauseEnd ? clauseEnd - 1 : clauseEnd; clauseWitnesses = witnesses.slice(fixedClauseStart, fixedClauseEnd); @@ -13593,26 +13596,34 @@ namespace ts { clauseWitnesses = switchWitnesses.slice(clauseStart, clauseEnd); switchFacts = getFactsFromTypeofSwitch(clauseStart, clauseEnd, switchWitnesses, hasDefaultClause); } - // The implied type is the raw type suggested by a - // value being caught in this clause. - // - If there is a default the implied type is not used. - // - Otherwise, take the union of the types in the - // clause. We narrow the union using facts to remove - // types that appear multiple types and are - // unreachable. - // Example: - // - // switch (typeof x) { - // case 'number': - // case 'string': break; - // default: break; - // case 'number': - // case 'boolean': break - // } - // - // The implied type of the first clause number | string. - // The implied type of the second clause is never, but this does not get used because it includes a default case. - // The implied type of the third clause is boolean (number has already be caught). + /* + The implied type is the raw type suggested by a + value being caught in this clause. + + When the clause contains a default case we ignore + the implied type and try to narrow using any facts + we can learn: see `switchFacts`. + + Example: + switch (typeof x) { + case 'number': + case 'string': break; + default: break; + case 'number': + case 'boolean': break + } + + In the first clause (case `number` and `string`) the + implied type is number | string. + + In the default clause we de not compute an implied type. + + In the third clause (case `number` and `boolean`) + the naive implied type is number | boolean, however + we use the type facts to narrow the implied type to + boolean. We know that number cannot be selected + because it is caught in the first clause. + */ if (!(hasDefaultClause || (type.flags & TypeFlags.Union))) { let impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(text => typeofTypesByName.get(text) || neverType)), switchFacts); if (impliedType.flags & TypeFlags.Union) { From 5aaf1e6b7a13955bcaa67413715581bd53c88d52 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Wed, 11 Jul 2018 17:45:22 +0100 Subject: [PATCH 006/163] Accept new baselines --- .../reference/narrowingByTypeofInSwitch.symbols | 12 ++++++------ .../reference/narrowingByTypeofInSwitch.types | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.symbols b/tests/baselines/reference/narrowingByTypeofInSwitch.symbols index b451b39ac7c..80246251815 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.symbols +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.symbols @@ -42,7 +42,7 @@ function assertSymbol(x: symbol) { function assertFunction(x: Function) { >assertFunction : Symbol(assertFunction, Decl(narrowingByTypeofInSwitch.ts, 18, 1)) >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 20, 24)) ->Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) return x; >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 20, 24)) @@ -91,7 +91,7 @@ function assertBooleanOrObject(x: boolean | object) { type Basic = number | boolean | string | symbol | object | Function | undefined; >Basic : Symbol(Basic, Decl(narrowingByTypeofInSwitch.ts, 42, 1)) ->Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) function testUnion(x: Basic) { >testUnion : Symbol(testUnion, Decl(narrowingByTypeofInSwitch.ts, 44, 80)) @@ -367,9 +367,9 @@ function exhaustiveChecks(x: number | string | L | R): string { >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) case 'number': return x.toString(2); ->x.toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>x.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) ->toString : Symbol(Number.toString, Decl(lib.d.ts, --, --)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) case 'string': return x; >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 133, 26)) @@ -396,9 +396,9 @@ function exhaustiveChecksGenerics(x: T): stri >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) case 'number': return x.toString(2); ->x.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --) ... and 2 more) +>x.toString : Symbol(toString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 2 more) >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) ->toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --) ... and 2 more) +>toString : Symbol(toString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 2 more) case 'string': return x; >x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 142, 69)) diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.types b/tests/baselines/reference/narrowingByTypeofInSwitch.types index 8672f4c9e7d..a2aef98feb4 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.types +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.types @@ -171,7 +171,7 @@ function testExtendsUnion(x: T) { >'boolean' : "boolean" >assertBoolean(x) : boolean >assertBoolean : (x: boolean) => boolean ->x : (T & true) | (T & false) +>x : (T & false) | (T & true) case 'function': assertAll(x); return; >'function' : "function" @@ -373,7 +373,7 @@ function testExtendsExplicitDefault(x: T) { >'boolean' : "boolean" >assertBoolean(x) : boolean >assertBoolean : (x: boolean) => boolean ->x : (T & true) | (T & false) +>x : (T & false) | (T & true) case 'function': assertAll(x); return; >'function' : "function" @@ -416,7 +416,7 @@ function testExtendsImplicitDefault(x: T) { >'boolean' : "boolean" >assertBoolean(x) : boolean >assertBoolean : (x: boolean) => boolean ->x : (T & true) | (T & false) +>x : (T & false) | (T & true) case 'function': assertAll(x); return; >'function' : "function" From cdfef4fa571a87b39d44622026108cc16868b927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Fri, 13 Jul 2018 15:07:38 +0800 Subject: [PATCH 007/163] add use strict and simple parameter check --- src/compiler/checker.ts | 40 +++++- src/compiler/diagnosticMessages.json | 12 ++ src/compiler/factory.ts | 27 +++-- ...tionWithUseStrictAndSimpleParameterList.js | 101 ++++++++++++++++ ...ithUseStrictAndSimpleParameterList.symbols | 83 +++++++++++++ ...nWithUseStrictAndSimpleParameterList.types | 109 +++++++++++++++++ ...ctAndSimpleParameterList_es2016.errors.txt | 114 ++++++++++++++++++ ...hUseStrictAndSimpleParameterList_es2016.js | 83 +++++++++++++ ...trictAndSimpleParameterList_es2016.symbols | 83 +++++++++++++ ...eStrictAndSimpleParameterList_es2016.types | 109 +++++++++++++++++ ...tionWithUseStrictAndSimpleParameterList.ts | 44 +++++++ ...hUseStrictAndSimpleParameterList_es2016.ts | 46 +++++++ 12 files changed, 838 insertions(+), 13 deletions(-) create mode 100644 tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.js create mode 100644 tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.symbols create mode 100644 tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.types create mode 100644 tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt create mode 100644 tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.js create mode 100644 tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.symbols create mode 100644 tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.types create mode 100644 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts create mode 100644 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cd91f427248..e97fc933839 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28515,11 +28515,49 @@ namespace ts { } } + function getNonSimpleParameters(parameters: ReadonlyArray): ReadonlyArray { + // ECMA-262 14.1.13 + if (parameters.length === 0) return []; + + const last = lastOrUndefined(parameters); + if (last && isRestParameter(last)) return [last]; + + return filter(parameters, parameter => { + // ECMA-262 13.3.3.4 + return !!parameter.initializer || isBindingPattern(parameter.name); + }); + } + + function checkGrammarForUseStrictSimpleParameterList(node: FunctionLikeDeclaration): boolean { + if (languageVersion >= ScriptTarget.ES2016) { + const useStrictDirective = node.body && isBlock(node.body) && findUseStrictPrologue(node.body.statements); + if (useStrictDirective) { + const nonSimpleParameters = getNonSimpleParameters(node.parameters); + if (length(nonSimpleParameters)) { + forEach(nonSimpleParameters, parameter => { + addRelatedInfo( + error(parameter, Diagnostics.This_parameter_is_not_allowed_with_use_strict_directive), + createDiagnosticForNode(useStrictDirective, Diagnostics._0_is_here, "use strict directive") + ); + }); + + const diagnostics = nonSimpleParameters.map((parameter, index) => ( + index === 0 ? createDiagnosticForNode(parameter, Diagnostics._0_is_here, "parameter") : createDiagnosticForNode(parameter, Diagnostics.and_here) + )) as [DiagnosticWithLocation, ...DiagnosticWithLocation[]]; + addRelatedInfo(error(useStrictDirective, Diagnostics.use_strict_directive_cannot_be_used_with_non_simple_parameter_list), ...diagnostics); + return true; + } + } + } + return false; + } + function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration | MethodSignature): boolean { // Prevent cascading error by short-circuit const file = getSourceFileOfNode(node); return checkGrammarDecoratorsAndModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) || - checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file); + checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file) || + (isFunctionLikeDeclaration(node) && checkGrammarForUseStrictSimpleParameterList(node)); } function checkGrammarClassLikeDeclaration(node: ClassLikeDeclaration): boolean { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 73be2b46b79..9a1690ebe55 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -983,6 +983,18 @@ "category": "Error", "code": 1343 }, + "This parameter is not allowed with 'use strict' directive.": { + "category": "Error", + "code": 1344 + }, + "'use strict' directive cannot be used with non simple parameter list.": { + "category": "Error", + "code": 1345 + }, + "{0} is here.": { + "category": "Error", + "code": 1346 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 86911417cb6..09b3386d24e 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -3934,6 +3934,20 @@ namespace ts { return statementOffset; } + export function findUseStrictPrologue(statements: ReadonlyArray): Statement | undefined { + for (const statement of statements) { + if (isPrologueDirective(statement)) { + if (isUseStrictPrologue(statement)) { + return statement; + } + } + else { + break; + } + } + return undefined; + } + export function startsWithUseStrict(statements: ReadonlyArray) { const firstStatement = firstOrUndefined(statements); return firstStatement !== undefined @@ -3947,18 +3961,7 @@ namespace ts { * @param statements An array of statements */ export function ensureUseStrict(statements: NodeArray): NodeArray { - let foundUseStrict = false; - for (const statement of statements) { - if (isPrologueDirective(statement)) { - if (isUseStrictPrologue(statement as ExpressionStatement)) { - foundUseStrict = true; - break; - } - } - else { - break; - } - } + const foundUseStrict = findUseStrictPrologue(statements); if (!foundUseStrict) { return setTextRange( diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.js b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.js new file mode 100644 index 00000000000..260f0df874a --- /dev/null +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.js @@ -0,0 +1,101 @@ +//// [functionWithUseStrictAndSimpleParameterList.ts] +function a(a = 10) { + "use strict"; +} + +export var foo = 10; +function b(a = 10) { +} + +function container() { + "use strict"; + function f(a = 10) { + } +} + +function rest(...args: any[]) { + 'use strict'; +} + +function paramDefault(param = 1) { + 'use strict'; +} + +function objectBindingPattern({foo}: any) { + 'use strict'; +} + +function arrayBindingPattern([foo]: any[]) { + 'use strict'; +} + +function manyParameter(a = 10, b = 20) { + "use strict"; +} + +function manyPrologue(a = 10, b = 20) { + "foo"; + "use strict"; +} + +function invalidPrologue(a = 10, b = 20) { + "foo"; + const c = 1; + "use strict"; +} + + +//// [functionWithUseStrictAndSimpleParameterList.js] +"use strict"; +exports.__esModule = true; +function a(a) { + "use strict"; + if (a === void 0) { a = 10; } +} +exports.foo = 10; +function b(a) { + if (a === void 0) { a = 10; } +} +function container() { + "use strict"; + function f(a) { + if (a === void 0) { a = 10; } + } +} +function rest() { + 'use strict'; + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } +} +function paramDefault(param) { + 'use strict'; + if (param === void 0) { param = 1; } +} +function objectBindingPattern(_a) { + 'use strict'; + var foo = _a.foo; +} +function arrayBindingPattern(_a) { + 'use strict'; + var foo = _a[0]; +} +function manyParameter(a, b) { + "use strict"; + if (a === void 0) { a = 10; } + if (b === void 0) { b = 20; } +} +function manyPrologue(a, b) { + "foo"; + "use strict"; + if (a === void 0) { a = 10; } + if (b === void 0) { b = 20; } +} +function invalidPrologue(a, b) { + "foo"; + if (a === void 0) { a = 10; } + if (b === void 0) { b = 20; } + var c = 1; + "use strict"; +} diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.symbols b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.symbols new file mode 100644 index 00000000000..59c8190883f --- /dev/null +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.symbols @@ -0,0 +1,83 @@ +=== tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts === +function a(a = 10) { +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 0, 0)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 0, 11)) + + "use strict"; +} + +export var foo = 10; +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList.ts, 4, 10)) + +function b(a = 10) { +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 4, 20)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 5, 11)) +} + +function container() { +>container : Symbol(container, Decl(functionWithUseStrictAndSimpleParameterList.ts, 6, 1)) + + "use strict"; + function f(a = 10) { +>f : Symbol(f, Decl(functionWithUseStrictAndSimpleParameterList.ts, 9, 17)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 10, 15)) + } +} + +function rest(...args: any[]) { +>rest : Symbol(rest, Decl(functionWithUseStrictAndSimpleParameterList.ts, 12, 1)) +>args : Symbol(args, Decl(functionWithUseStrictAndSimpleParameterList.ts, 14, 14)) + + 'use strict'; +} + +function paramDefault(param = 1) { +>paramDefault : Symbol(paramDefault, Decl(functionWithUseStrictAndSimpleParameterList.ts, 16, 1)) +>param : Symbol(param, Decl(functionWithUseStrictAndSimpleParameterList.ts, 18, 22)) + + 'use strict'; +} + +function objectBindingPattern({foo}: any) { +>objectBindingPattern : Symbol(objectBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList.ts, 20, 1)) +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList.ts, 22, 31)) + + 'use strict'; +} + +function arrayBindingPattern([foo]: any[]) { +>arrayBindingPattern : Symbol(arrayBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList.ts, 24, 1)) +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList.ts, 26, 30)) + + 'use strict'; +} + +function manyParameter(a = 10, b = 20) { +>manyParameter : Symbol(manyParameter, Decl(functionWithUseStrictAndSimpleParameterList.ts, 28, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 30, 23)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 30, 30)) + + "use strict"; +} + +function manyPrologue(a = 10, b = 20) { +>manyPrologue : Symbol(manyPrologue, Decl(functionWithUseStrictAndSimpleParameterList.ts, 32, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 34, 22)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 34, 29)) + + "foo"; + "use strict"; +} + +function invalidPrologue(a = 10, b = 20) { +>invalidPrologue : Symbol(invalidPrologue, Decl(functionWithUseStrictAndSimpleParameterList.ts, 37, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 39, 25)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 39, 32)) + + "foo"; + const c = 1; +>c : Symbol(c, Decl(functionWithUseStrictAndSimpleParameterList.ts, 41, 9)) + + "use strict"; +} + diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.types b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.types new file mode 100644 index 00000000000..c64c3c30036 --- /dev/null +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.types @@ -0,0 +1,109 @@ +=== tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts === +function a(a = 10) { +>a : (a?: number) => void +>a : number +>10 : 10 + + "use strict"; +>"use strict" : "use strict" +} + +export var foo = 10; +>foo : number +>10 : 10 + +function b(a = 10) { +>b : (a?: number) => void +>a : number +>10 : 10 +} + +function container() { +>container : () => void + + "use strict"; +>"use strict" : "use strict" + + function f(a = 10) { +>f : (a?: number) => void +>a : number +>10 : 10 + } +} + +function rest(...args: any[]) { +>rest : (...args: any[]) => void +>args : any[] + + 'use strict'; +>'use strict' : "use strict" +} + +function paramDefault(param = 1) { +>paramDefault : (param?: number) => void +>param : number +>1 : 1 + + 'use strict'; +>'use strict' : "use strict" +} + +function objectBindingPattern({foo}: any) { +>objectBindingPattern : ({ foo }: any) => void +>foo : any + + 'use strict'; +>'use strict' : "use strict" +} + +function arrayBindingPattern([foo]: any[]) { +>arrayBindingPattern : ([foo]: any[]) => void +>foo : any + + 'use strict'; +>'use strict' : "use strict" +} + +function manyParameter(a = 10, b = 20) { +>manyParameter : (a?: number, b?: number) => void +>a : number +>10 : 10 +>b : number +>20 : 20 + + "use strict"; +>"use strict" : "use strict" +} + +function manyPrologue(a = 10, b = 20) { +>manyPrologue : (a?: number, b?: number) => void +>a : number +>10 : 10 +>b : number +>20 : 20 + + "foo"; +>"foo" : "foo" + + "use strict"; +>"use strict" : "use strict" +} + +function invalidPrologue(a = 10, b = 20) { +>invalidPrologue : (a?: number, b?: number) => void +>a : number +>10 : 10 +>b : number +>20 : 20 + + "foo"; +>"foo" : "foo" + + const c = 1; +>c : 1 +>1 : 1 + + "use strict"; +>"use strict" : "use strict" +} + diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt new file mode 100644 index 00000000000..84d69721c61 --- /dev/null +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt @@ -0,0 +1,114 @@ +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(1,12): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(2,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(15,15): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(16,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(19,23): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(20,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(23,31): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(24,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(27,30): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(28,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(31,24): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(31,32): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(32,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,23): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,31): error TS1344: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(37,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. + + +==== tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts (16 errors) ==== + function a(a = 10) { + ~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:2:5: use strict directive is here. + "use strict"; + ~~~~~~~~~~~~~ +!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:1:12: parameter is here. + } + + export var foo = 10; + function b(a = 10) { + } + + function container() { + "use strict"; + function f(a = 10) { + } + } + + function rest(...args: any[]) { + ~~~~~~~~~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:16:5: use strict directive is here. + 'use strict'; + ~~~~~~~~~~~~~ +!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:15:15: parameter is here. + } + + function paramDefault(param = 1) { + ~~~~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:20:5: use strict directive is here. + 'use strict'; + ~~~~~~~~~~~~~ +!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:19:23: parameter is here. + } + + function objectBindingPattern({foo}: any) { + ~~~~~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:24:5: use strict directive is here. + 'use strict'; + ~~~~~~~~~~~~~ +!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:23:31: parameter is here. + } + + function arrayBindingPattern([foo]: any[]) { + ~~~~~~~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:28:5: use strict directive is here. + 'use strict'; + ~~~~~~~~~~~~~ +!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:27:30: parameter is here. + } + + function manyParameter(a = 10, b = 20) { + ~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:32:5: use strict directive is here. + ~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:32:5: use strict directive is here. + "use strict"; + ~~~~~~~~~~~~~ +!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:31:24: parameter is here. +!!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:31:32: and here. + } + + function manyPrologue(a = 10, b = 20) { + ~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:37:5: use strict directive is here. + ~~~~~~ +!!! error TS1344: This parameter is not allowed with 'use strict' directive. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:37:5: use strict directive is here. + "foo"; + "use strict"; + ~~~~~~~~~~~~~ +!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. +!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:23: parameter is here. +!!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:31: and here. + } + + function invalidPrologue(a = 10, b = 20) { + "foo"; + const c = 1; + "use strict"; + } + \ No newline at end of file diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.js b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.js new file mode 100644 index 00000000000..d8e50e9d1b6 --- /dev/null +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.js @@ -0,0 +1,83 @@ +//// [functionWithUseStrictAndSimpleParameterList_es2016.ts] +function a(a = 10) { + "use strict"; +} + +export var foo = 10; +function b(a = 10) { +} + +function container() { + "use strict"; + function f(a = 10) { + } +} + +function rest(...args: any[]) { + 'use strict'; +} + +function paramDefault(param = 1) { + 'use strict'; +} + +function objectBindingPattern({foo}: any) { + 'use strict'; +} + +function arrayBindingPattern([foo]: any[]) { + 'use strict'; +} + +function manyParameter(a = 10, b = 20) { + "use strict"; +} + +function manyPrologue(a = 10, b = 20) { + "foo"; + "use strict"; +} + +function invalidPrologue(a = 10, b = 20) { + "foo"; + const c = 1; + "use strict"; +} + + +//// [functionWithUseStrictAndSimpleParameterList_es2016.js] +function a(a = 10) { + "use strict"; +} +export var foo = 10; +function b(a = 10) { +} +function container() { + "use strict"; + function f(a = 10) { + } +} +function rest(...args) { + 'use strict'; +} +function paramDefault(param = 1) { + 'use strict'; +} +function objectBindingPattern({ foo }) { + 'use strict'; +} +function arrayBindingPattern([foo]) { + 'use strict'; +} +function manyParameter(a = 10, b = 20) { + "use strict"; +} +function manyPrologue(a = 10, b = 20) { + "foo"; + "use strict"; +} +function invalidPrologue(a = 10, b = 20) { + "foo"; + const c = 1; + "use strict"; +} diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.symbols b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.symbols new file mode 100644 index 00000000000..444f219ab2f --- /dev/null +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.symbols @@ -0,0 +1,83 @@ +=== tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts === +function a(a = 10) { +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 0, 0)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 0, 11)) + + "use strict"; +} + +export var foo = 10; +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 4, 10)) + +function b(a = 10) { +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 4, 20)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 5, 11)) +} + +function container() { +>container : Symbol(container, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 6, 1)) + + "use strict"; + function f(a = 10) { +>f : Symbol(f, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 9, 17)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 10, 15)) + } +} + +function rest(...args: any[]) { +>rest : Symbol(rest, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 12, 1)) +>args : Symbol(args, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 14, 14)) + + 'use strict'; +} + +function paramDefault(param = 1) { +>paramDefault : Symbol(paramDefault, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 16, 1)) +>param : Symbol(param, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 18, 22)) + + 'use strict'; +} + +function objectBindingPattern({foo}: any) { +>objectBindingPattern : Symbol(objectBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 20, 1)) +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 22, 31)) + + 'use strict'; +} + +function arrayBindingPattern([foo]: any[]) { +>arrayBindingPattern : Symbol(arrayBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 24, 1)) +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 26, 30)) + + 'use strict'; +} + +function manyParameter(a = 10, b = 20) { +>manyParameter : Symbol(manyParameter, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 28, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 30, 23)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 30, 30)) + + "use strict"; +} + +function manyPrologue(a = 10, b = 20) { +>manyPrologue : Symbol(manyPrologue, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 32, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 34, 22)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 34, 29)) + + "foo"; + "use strict"; +} + +function invalidPrologue(a = 10, b = 20) { +>invalidPrologue : Symbol(invalidPrologue, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 37, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 39, 25)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 39, 32)) + + "foo"; + const c = 1; +>c : Symbol(c, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 41, 9)) + + "use strict"; +} + diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.types b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.types new file mode 100644 index 00000000000..19f3d7f015b --- /dev/null +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.types @@ -0,0 +1,109 @@ +=== tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts === +function a(a = 10) { +>a : (a?: number) => void +>a : number +>10 : 10 + + "use strict"; +>"use strict" : "use strict" +} + +export var foo = 10; +>foo : number +>10 : 10 + +function b(a = 10) { +>b : (a?: number) => void +>a : number +>10 : 10 +} + +function container() { +>container : () => void + + "use strict"; +>"use strict" : "use strict" + + function f(a = 10) { +>f : (a?: number) => void +>a : number +>10 : 10 + } +} + +function rest(...args: any[]) { +>rest : (...args: any[]) => void +>args : any[] + + 'use strict'; +>'use strict' : "use strict" +} + +function paramDefault(param = 1) { +>paramDefault : (param?: number) => void +>param : number +>1 : 1 + + 'use strict'; +>'use strict' : "use strict" +} + +function objectBindingPattern({foo}: any) { +>objectBindingPattern : ({ foo }: any) => void +>foo : any + + 'use strict'; +>'use strict' : "use strict" +} + +function arrayBindingPattern([foo]: any[]) { +>arrayBindingPattern : ([foo]: any[]) => void +>foo : any + + 'use strict'; +>'use strict' : "use strict" +} + +function manyParameter(a = 10, b = 20) { +>manyParameter : (a?: number, b?: number) => void +>a : number +>10 : 10 +>b : number +>20 : 20 + + "use strict"; +>"use strict" : "use strict" +} + +function manyPrologue(a = 10, b = 20) { +>manyPrologue : (a?: number, b?: number) => void +>a : number +>10 : 10 +>b : number +>20 : 20 + + "foo"; +>"foo" : "foo" + + "use strict"; +>"use strict" : "use strict" +} + +function invalidPrologue(a = 10, b = 20) { +>invalidPrologue : (a?: number, b?: number) => void +>a : number +>10 : 10 +>b : number +>20 : 20 + + "foo"; +>"foo" : "foo" + + const c = 1; +>c : 1 +>1 : 1 + + "use strict"; +>"use strict" : "use strict" +} + diff --git a/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts b/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts new file mode 100644 index 00000000000..65be76d500c --- /dev/null +++ b/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts @@ -0,0 +1,44 @@ +function a(a = 10) { + "use strict"; +} + +export var foo = 10; +function b(a = 10) { +} + +function container() { + "use strict"; + function f(a = 10) { + } +} + +function rest(...args: any[]) { + 'use strict'; +} + +function paramDefault(param = 1) { + 'use strict'; +} + +function objectBindingPattern({foo}: any) { + 'use strict'; +} + +function arrayBindingPattern([foo]: any[]) { + 'use strict'; +} + +function manyParameter(a = 10, b = 20) { + "use strict"; +} + +function manyPrologue(a = 10, b = 20) { + "foo"; + "use strict"; +} + +function invalidPrologue(a = 10, b = 20) { + "foo"; + const c = 1; + "use strict"; +} diff --git a/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts b/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts new file mode 100644 index 00000000000..ed17746931a --- /dev/null +++ b/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts @@ -0,0 +1,46 @@ +// @target: es2016 + +function a(a = 10) { + "use strict"; +} + +export var foo = 10; +function b(a = 10) { +} + +function container() { + "use strict"; + function f(a = 10) { + } +} + +function rest(...args: any[]) { + 'use strict'; +} + +function paramDefault(param = 1) { + 'use strict'; +} + +function objectBindingPattern({foo}: any) { + 'use strict'; +} + +function arrayBindingPattern([foo]: any[]) { + 'use strict'; +} + +function manyParameter(a = 10, b = 20) { + "use strict"; +} + +function manyPrologue(a = 10, b = 20) { + "foo"; + "use strict"; +} + +function invalidPrologue(a = 10, b = 20) { + "foo"; + const c = 1; + "use strict"; +} From 1c522a6e994b83eda2aec3223c0850e8ac6fe0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Fri, 20 Jul 2018 15:48:26 +0800 Subject: [PATCH 008/163] improve enum rechability check --- src/compiler/binder.ts | 6 ++--- src/compiler/checker.ts | 15 ++++++----- ...ScopedEnumVariablesUseBeforeDef.errors.txt | 16 ++++++++++++ .../blockScopedEnumVariablesUseBeforeDef.js | 22 ++++++++++++++++ ...ockScopedEnumVariablesUseBeforeDef.symbols | 26 +++++++++++++++++++ ...blockScopedEnumVariablesUseBeforeDef.types | 26 +++++++++++++++++++ ...mVariablesUseBeforeDef_preserve.errors.txt | 20 ++++++++++++++ ...copedEnumVariablesUseBeforeDef_preserve.js | 26 +++++++++++++++++++ ...EnumVariablesUseBeforeDef_preserve.symbols | 26 +++++++++++++++++++ ...edEnumVariablesUseBeforeDef_preserve.types | 26 +++++++++++++++++++ ...lockScopedVariablesUseBeforeDef.errors.txt | 3 ++- .../blockScopedVariablesUseBeforeDef.js | 3 ++- .../blockScopedVariablesUseBeforeDef.symbols | 1 + .../blockScopedVariablesUseBeforeDef.types | 1 + .../reference/reachabilityChecks1.errors.txt | 12 +-------- .../blockScopedEnumVariablesUseBeforeDef.ts | 10 +++++++ ...copedEnumVariablesUseBeforeDef_preserve.ts | 12 +++++++++ .../blockScopedVariablesUseBeforeDef.ts | 2 +- .../cases/fourslash/codeFixUnreachableCode.ts | 18 ++++++++++--- 19 files changed, 244 insertions(+), 27 deletions(-) create mode 100644 tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.errors.txt create mode 100644 tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.js create mode 100644 tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.symbols create mode 100644 tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.types create mode 100644 tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.errors.txt create mode 100644 tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.js create mode 100644 tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.symbols create mode 100644 tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.types create mode 100644 tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts create mode 100644 tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 7fb79b2efa2..abc4d2fc66d 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2789,9 +2789,7 @@ namespace ts { // report error on class declarations node.kind === SyntaxKind.ClassDeclaration || // report error on instantiated modules or const-enums only modules if preserveConstEnums is set - (node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node)) || - // report error on regular enums and const enums if preserveConstEnums is set - (isEnumDeclaration(node) && (!isEnumConst(node) || options.preserveConstEnums)); + (node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(node)); if (reportError) { currentFlow = reportedUnreachableFlow; @@ -2836,7 +2834,7 @@ namespace ts { // As opposed to a pure declaration like an `interface` function isExecutableStatement(s: Statement): boolean { // Don't remove statements that can validly be used before they appear. - return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && + return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !isEnumDeclaration(s) && // `var x;` may declare a variable used above !(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer)); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e01c97af492..9d2c133704a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1679,6 +1679,9 @@ namespace ts { } else { Debug.assert(!!(result.flags & SymbolFlags.ConstEnum)); + if (compilerOptions.preserveConstEnums) { + diagnosticMessage = error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationName); + } } if (diagnosticMessage) { @@ -22786,6 +22789,12 @@ namespace ts { } } + const enum DeclarationSpaces { + None = 0, + ExportValue = 1 << 0, + ExportType = 1 << 1, + ExportNamespace = 1 << 2, + } function checkExportsOnMergedDeclarations(node: Node): void { if (!produceDiagnostics) { return; @@ -22850,12 +22859,6 @@ namespace ts { } } - const enum DeclarationSpaces { - None = 0, - ExportValue = 1 << 0, - ExportType = 1 << 1, - ExportNamespace = 1 << 2, - } function getDeclarationSpaces(decl: Declaration): DeclarationSpaces { let d = decl as Node; switch (d.kind) { diff --git a/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.errors.txt b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.errors.txt new file mode 100644 index 00000000000..5927caba434 --- /dev/null +++ b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.errors.txt @@ -0,0 +1,16 @@ +tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts(2,12): error TS2450: Enum 'E' used before its declaration. + + +==== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts (1 errors) ==== + function foo1() { + return E.A + ~ +!!! error TS2450: Enum 'E' used before its declaration. +!!! related TS2728 tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts:3:10: 'E' is declared here. + enum E { A } + } + + function foo2() { + return E.A + const enum E { A } + } \ No newline at end of file diff --git a/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.js b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.js new file mode 100644 index 00000000000..552d099b07c --- /dev/null +++ b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.js @@ -0,0 +1,22 @@ +//// [blockScopedEnumVariablesUseBeforeDef.ts] +function foo1() { + return E.A + enum E { A } +} + +function foo2() { + return E.A + const enum E { A } +} + +//// [blockScopedEnumVariablesUseBeforeDef.js] +function foo1() { + return E.A; + var E; + (function (E) { + E[E["A"] = 0] = "A"; + })(E || (E = {})); +} +function foo2() { + return 0 /* A */; +} diff --git a/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.symbols b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.symbols new file mode 100644 index 00000000000..73f8419c8c1 --- /dev/null +++ b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts === +function foo1() { +>foo1 : Symbol(foo1, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 0, 0)) + + return E.A +>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 2, 12)) +>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 1, 14)) +>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 2, 12)) + + enum E { A } +>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 1, 14)) +>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 2, 12)) +} + +function foo2() { +>foo2 : Symbol(foo2, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 3, 1)) + + return E.A +>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 7, 18)) +>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 6, 14)) +>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 7, 18)) + + const enum E { A } +>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 6, 14)) +>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 7, 18)) +} diff --git a/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.types b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.types new file mode 100644 index 00000000000..5c4dc43f774 --- /dev/null +++ b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts === +function foo1() { +>foo1 : () => E + + return E.A +>E.A : E +>E : typeof E +>A : E + + enum E { A } +>E : E +>A : E +} + +function foo2() { +>foo2 : () => E + + return E.A +>E.A : E +>E : typeof E +>A : E + + const enum E { A } +>E : E +>A : E +} diff --git a/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.errors.txt b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.errors.txt new file mode 100644 index 00000000000..94b2ff97d9f --- /dev/null +++ b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts(2,12): error TS2450: Enum 'E' used before its declaration. +tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts(7,12): error TS2449: Class 'E' used before its declaration. + + +==== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts (2 errors) ==== + function foo1() { + return E.A + ~ +!!! error TS2450: Enum 'E' used before its declaration. +!!! related TS2728 tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts:3:10: 'E' is declared here. + enum E { A } + } + + function foo2() { + return E.A + ~ +!!! error TS2449: Class 'E' used before its declaration. +!!! related TS2728 tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts:8:16: 'E' is declared here. + const enum E { A } + } \ No newline at end of file diff --git a/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.js b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.js new file mode 100644 index 00000000000..239a87f0042 --- /dev/null +++ b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.js @@ -0,0 +1,26 @@ +//// [blockScopedEnumVariablesUseBeforeDef_preserve.ts] +function foo1() { + return E.A + enum E { A } +} + +function foo2() { + return E.A + const enum E { A } +} + +//// [blockScopedEnumVariablesUseBeforeDef_preserve.js] +function foo1() { + return E.A; + var E; + (function (E) { + E[E["A"] = 0] = "A"; + })(E || (E = {})); +} +function foo2() { + return 0 /* A */; + var E; + (function (E) { + E[E["A"] = 0] = "A"; + })(E || (E = {})); +} diff --git a/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.symbols b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.symbols new file mode 100644 index 00000000000..b76089c0a0f --- /dev/null +++ b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts === +function foo1() { +>foo1 : Symbol(foo1, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 0, 0)) + + return E.A +>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 2, 12)) +>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 1, 14)) +>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 2, 12)) + + enum E { A } +>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 1, 14)) +>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 2, 12)) +} + +function foo2() { +>foo2 : Symbol(foo2, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 3, 1)) + + return E.A +>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 7, 18)) +>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 6, 14)) +>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 7, 18)) + + const enum E { A } +>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 6, 14)) +>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_preserve.ts, 7, 18)) +} diff --git a/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.types b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.types new file mode 100644 index 00000000000..5194114112e --- /dev/null +++ b/tests/baselines/reference/blockScopedEnumVariablesUseBeforeDef_preserve.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts === +function foo1() { +>foo1 : () => E + + return E.A +>E.A : E +>E : typeof E +>A : E + + enum E { A } +>E : E +>A : E +} + +function foo2() { +>foo2 : () => E + + return E.A +>E.A : E +>E : typeof E +>A : E + + const enum E { A } +>E : E +>A : E +} diff --git a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.errors.txt b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.errors.txt index 4de97fa02a4..91bd5dde00c 100644 --- a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.errors.txt +++ b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.errors.txt @@ -119,4 +119,5 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448: !!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:102:9: 'x' is declared here. } let x - } \ No newline at end of file + } + \ No newline at end of file diff --git a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.js b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.js index b14ea2a3069..7e6b452302b 100644 --- a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.js +++ b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.js @@ -101,7 +101,8 @@ function foo14() { a: x } let x -} +} + //// [blockScopedVariablesUseBeforeDef.js] function foo0() { diff --git a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.symbols b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.symbols index 9dcb26712fb..83cb91db1d0 100644 --- a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.symbols +++ b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.symbols @@ -212,3 +212,4 @@ function foo14() { let x >x : Symbol(x, Decl(blockScopedVariablesUseBeforeDef.ts, 101, 7)) } + diff --git a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.types b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.types index 771518e5901..3098b8c0f91 100644 --- a/tests/baselines/reference/blockScopedVariablesUseBeforeDef.types +++ b/tests/baselines/reference/blockScopedVariablesUseBeforeDef.types @@ -224,3 +224,4 @@ function foo14() { let x >x : any } + diff --git a/tests/baselines/reference/reachabilityChecks1.errors.txt b/tests/baselines/reference/reachabilityChecks1.errors.txt index 041d10bfecd..97fd5302d45 100644 --- a/tests/baselines/reference/reachabilityChecks1.errors.txt +++ b/tests/baselines/reference/reachabilityChecks1.errors.txt @@ -3,11 +3,9 @@ tests/cases/compiler/reachabilityChecks1.ts(6,5): error TS7027: Unreachable code tests/cases/compiler/reachabilityChecks1.ts(18,5): error TS7027: Unreachable code detected. tests/cases/compiler/reachabilityChecks1.ts(30,5): error TS7027: Unreachable code detected. tests/cases/compiler/reachabilityChecks1.ts(47,5): error TS7027: Unreachable code detected. -tests/cases/compiler/reachabilityChecks1.ts(60,5): error TS7027: Unreachable code detected. -tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable code detected. -==== tests/cases/compiler/reachabilityChecks1.ts (7 errors) ==== +==== tests/cases/compiler/reachabilityChecks1.ts (5 errors) ==== while (true); var x = 1; ~~~~~~~~~~ @@ -83,12 +81,8 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod do { } while (true); enum E { - ~~~~~~~~ X = 1 - ~~~~~~~~~~~~~ } - ~~~~~ -!!! error TS7027: Unreachable code detected. } function f4() { @@ -96,12 +90,8 @@ tests/cases/compiler/reachabilityChecks1.ts(69,5): error TS7027: Unreachable cod throw new Error(); } const enum E { - ~~~~~~~~~~~~~~ X = 1 - ~~~~~~~~~~~~~ } - ~~~~~ -!!! error TS7027: Unreachable code detected. } \ No newline at end of file diff --git a/tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts b/tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts new file mode 100644 index 00000000000..84eff340164 --- /dev/null +++ b/tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef.ts @@ -0,0 +1,10 @@ +// @target: ES5 +function foo1() { + return E.A + enum E { A } +} + +function foo2() { + return E.A + const enum E { A } +} \ No newline at end of file diff --git a/tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts b/tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts new file mode 100644 index 00000000000..0d7cb73b3ad --- /dev/null +++ b/tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_preserve.ts @@ -0,0 +1,12 @@ +// @target: ES5 +// @preserveConstEnums: true + +function foo1() { + return E.A + enum E { A } +} + +function foo2() { + return E.A + const enum E { A } +} \ No newline at end of file diff --git a/tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts b/tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts index 956705bd7d3..351bdde122e 100644 --- a/tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts +++ b/tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts @@ -101,4 +101,4 @@ function foo14() { a: x } let x -} \ No newline at end of file +} diff --git a/tests/cases/fourslash/codeFixUnreachableCode.ts b/tests/cases/fourslash/codeFixUnreachableCode.ts index 9c9eea6dae4..eb5731081e7 100644 --- a/tests/cases/fourslash/codeFixUnreachableCode.ts +++ b/tests/cases/fourslash/codeFixUnreachableCode.ts @@ -3,12 +3,12 @@ ////function f() { //// return f(); //// [|return 1;|] -//// function f() {} +//// function f(a?: EE) { return a; } //// [|return 2;|] //// type T = number; //// interface I {} //// const enum E {} -//// [|enum E {}|] +//// enum EE {} //// namespace N { export type T = number; } //// [|namespace N { export const x: T = 0; }|] //// var x: I; @@ -29,11 +29,23 @@ verify.codeFixAll({ newFileContent: `function f() { return f(); - function f() {} + function f(a?: EE) { return a; } type T = number; interface I {} const enum E {} + enum EE {} namespace N { export type T = number; } var x: I; }`, }); + +function f() { + return f(); + function f(a?: EE) { return a; } + type T = number; + interface I {} + const enum E {} + enum EE {} + namespace N { export type T = number; } + var x: I; +} \ No newline at end of file From 02f5365e080686c9b89b3dc55abf27267eaf2a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Wed, 1 Aug 2018 10:21:50 +0800 Subject: [PATCH 009/163] improve error message and update testcase --- src/compiler/checker.ts | 15 +-- src/compiler/diagnosticMessages.json | 8 +- ...tionWithUseStrictAndSimpleParameterList.js | 12 ++ ...ithUseStrictAndSimpleParameterList.symbols | 40 +++--- ...nWithUseStrictAndSimpleParameterList.types | 10 ++ ...ctAndSimpleParameterList_es2016.errors.txt | 119 ++++++++++-------- ...hUseStrictAndSimpleParameterList_es2016.js | 7 ++ ...trictAndSimpleParameterList_es2016.symbols | 40 +++--- ...eStrictAndSimpleParameterList_es2016.types | 10 ++ ...tionWithUseStrictAndSimpleParameterList.ts | 4 + ...hUseStrictAndSimpleParameterList_es2016.ts | 4 + 11 files changed, 172 insertions(+), 97 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index de9521031f6..eaf18a5078f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28717,16 +28717,7 @@ namespace ts { } function getNonSimpleParameters(parameters: ReadonlyArray): ReadonlyArray { - // ECMA-262 14.1.13 - if (parameters.length === 0) return []; - - const last = lastOrUndefined(parameters); - if (last && isRestParameter(last)) return [last]; - - return filter(parameters, parameter => { - // ECMA-262 13.3.3.4 - return !!parameter.initializer || isBindingPattern(parameter.name); - }); + return filter(parameters, parameter => !!parameter.initializer || isBindingPattern(parameter.name) || isRestParameter(parameter)); } function checkGrammarForUseStrictSimpleParameterList(node: FunctionLikeDeclaration): boolean { @@ -28738,12 +28729,12 @@ namespace ts { forEach(nonSimpleParameters, parameter => { addRelatedInfo( error(parameter, Diagnostics.This_parameter_is_not_allowed_with_use_strict_directive), - createDiagnosticForNode(useStrictDirective, Diagnostics._0_is_here, "use strict directive") + createDiagnosticForNode(useStrictDirective, Diagnostics.use_strict_directive_used_here) ); }); const diagnostics = nonSimpleParameters.map((parameter, index) => ( - index === 0 ? createDiagnosticForNode(parameter, Diagnostics._0_is_here, "parameter") : createDiagnosticForNode(parameter, Diagnostics.and_here) + index === 0 ? createDiagnosticForNode(parameter, Diagnostics.Non_simple_parameter_declared_here) : createDiagnosticForNode(parameter, Diagnostics.and_here) )) as [DiagnosticWithLocation, ...DiagnosticWithLocation[]]; addRelatedInfo(error(useStrictDirective, Diagnostics.use_strict_directive_cannot_be_used_with_non_simple_parameter_list), ...diagnostics); return true; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0831ab7fba2..0a35bb0e85b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -991,14 +991,18 @@ "category": "Error", "code": 1345 }, - "'use strict' directive cannot be used with non simple parameter list.": { + "'use strict' directive cannot be used with non-simple parameter list.": { "category": "Error", "code": 1346 }, - "{0} is here.": { + "Non-simple parameter declared here.": { "category": "Error", "code": 1347 }, + "'use strict' directive used here.": { + "category": "Error", + "code": 1348 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.js b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.js index 260f0df874a..1cf35579976 100644 --- a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.js +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.js @@ -17,6 +17,10 @@ function rest(...args: any[]) { 'use strict'; } +function rest1(a = 1, ...args) { + 'use strict'; +} + function paramDefault(param = 1) { 'use strict'; } @@ -69,6 +73,14 @@ function rest() { args[_i] = arguments[_i]; } } +function rest1(a) { + 'use strict'; + if (a === void 0) { a = 1; } + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } +} function paramDefault(param) { 'use strict'; if (param === void 0) { param = 1; } diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.symbols b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.symbols index 59c8190883f..9c2ad86d974 100644 --- a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.symbols +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.symbols @@ -31,52 +31,60 @@ function rest(...args: any[]) { 'use strict'; } +function rest1(a = 1, ...args) { +>rest1 : Symbol(rest1, Decl(functionWithUseStrictAndSimpleParameterList.ts, 16, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 18, 15)) +>args : Symbol(args, Decl(functionWithUseStrictAndSimpleParameterList.ts, 18, 21)) + + 'use strict'; +} + function paramDefault(param = 1) { ->paramDefault : Symbol(paramDefault, Decl(functionWithUseStrictAndSimpleParameterList.ts, 16, 1)) ->param : Symbol(param, Decl(functionWithUseStrictAndSimpleParameterList.ts, 18, 22)) +>paramDefault : Symbol(paramDefault, Decl(functionWithUseStrictAndSimpleParameterList.ts, 20, 1)) +>param : Symbol(param, Decl(functionWithUseStrictAndSimpleParameterList.ts, 22, 22)) 'use strict'; } function objectBindingPattern({foo}: any) { ->objectBindingPattern : Symbol(objectBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList.ts, 20, 1)) ->foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList.ts, 22, 31)) +>objectBindingPattern : Symbol(objectBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList.ts, 24, 1)) +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList.ts, 26, 31)) 'use strict'; } function arrayBindingPattern([foo]: any[]) { ->arrayBindingPattern : Symbol(arrayBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList.ts, 24, 1)) ->foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList.ts, 26, 30)) +>arrayBindingPattern : Symbol(arrayBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList.ts, 28, 1)) +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList.ts, 30, 30)) 'use strict'; } function manyParameter(a = 10, b = 20) { ->manyParameter : Symbol(manyParameter, Decl(functionWithUseStrictAndSimpleParameterList.ts, 28, 1)) ->a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 30, 23)) ->b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 30, 30)) +>manyParameter : Symbol(manyParameter, Decl(functionWithUseStrictAndSimpleParameterList.ts, 32, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 34, 23)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 34, 30)) "use strict"; } function manyPrologue(a = 10, b = 20) { ->manyPrologue : Symbol(manyPrologue, Decl(functionWithUseStrictAndSimpleParameterList.ts, 32, 1)) ->a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 34, 22)) ->b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 34, 29)) +>manyPrologue : Symbol(manyPrologue, Decl(functionWithUseStrictAndSimpleParameterList.ts, 36, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 38, 22)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 38, 29)) "foo"; "use strict"; } function invalidPrologue(a = 10, b = 20) { ->invalidPrologue : Symbol(invalidPrologue, Decl(functionWithUseStrictAndSimpleParameterList.ts, 37, 1)) ->a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 39, 25)) ->b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 39, 32)) +>invalidPrologue : Symbol(invalidPrologue, Decl(functionWithUseStrictAndSimpleParameterList.ts, 41, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList.ts, 43, 25)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList.ts, 43, 32)) "foo"; const c = 1; ->c : Symbol(c, Decl(functionWithUseStrictAndSimpleParameterList.ts, 41, 9)) +>c : Symbol(c, Decl(functionWithUseStrictAndSimpleParameterList.ts, 45, 9)) "use strict"; } diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.types b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.types index c64c3c30036..462086d28ad 100644 --- a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.types +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList.types @@ -39,6 +39,16 @@ function rest(...args: any[]) { >'use strict' : "use strict" } +function rest1(a = 1, ...args) { +>rest1 : (a?: number, ...args: any[]) => void +>a : number +>1 : 1 +>args : any[] + + 'use strict'; +>'use strict' : "use strict" +} + function paramDefault(param = 1) { >paramDefault : (param?: number) => void >param : number diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt index 84d69721c61..4887cb4f07a 100644 --- a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt @@ -1,30 +1,33 @@ -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(1,12): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(2,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(15,15): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(16,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(19,23): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(20,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(23,31): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(24,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(27,30): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(28,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(31,24): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(31,32): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(32,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,23): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,31): error TS1344: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(37,5): error TS1345: 'use strict' directive cannot be used with non simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(1,12): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(2,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(15,15): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(16,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(19,16): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(19,23): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(20,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(23,23): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(24,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(27,31): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(28,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(31,30): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(32,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,24): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,32): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(36,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(39,23): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(39,31): error TS1345: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(41,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -==== tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts (16 errors) ==== +==== tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts (19 errors) ==== function a(a = 10) { ~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:2:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:2:5: 'use strict' directive used here. "use strict"; ~~~~~~~~~~~~~ -!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:1:12: parameter is here. +!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:1:12: Non-simple parameter declared here. } export var foo = 10; @@ -39,71 +42,85 @@ tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es function rest(...args: any[]) { ~~~~~~~~~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:16:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:16:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:15:15: parameter is here. +!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:15:15: Non-simple parameter declared here. + } + + function rest1(a = 1, ...args) { + ~~~~~ +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:20:5: 'use strict' directive used here. + ~~~~~~~ +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:20:5: 'use strict' directive used here. + 'use strict'; + ~~~~~~~~~~~~~ +!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:19:16: Non-simple parameter declared here. +!!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:19:23: and here. } function paramDefault(param = 1) { ~~~~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:20:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:24:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:19:23: parameter is here. +!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:23:23: Non-simple parameter declared here. } function objectBindingPattern({foo}: any) { ~~~~~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:24:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:28:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:23:31: parameter is here. +!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:27:31: Non-simple parameter declared here. } function arrayBindingPattern([foo]: any[]) { ~~~~~~~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:28:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:32:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:27:30: parameter is here. +!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:31:30: Non-simple parameter declared here. } function manyParameter(a = 10, b = 20) { ~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:32:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:36:5: 'use strict' directive used here. ~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:32:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:36:5: 'use strict' directive used here. "use strict"; ~~~~~~~~~~~~~ -!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:31:24: parameter is here. -!!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:31:32: and here. +!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:24: Non-simple parameter declared here. +!!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:32: and here. } function manyPrologue(a = 10, b = 20) { ~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:37:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:41:5: 'use strict' directive used here. ~~~~~~ -!!! error TS1344: This parameter is not allowed with 'use strict' directive. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:37:5: use strict directive is here. +!!! error TS1345: This parameter is not allowed with 'use strict' directive. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:41:5: 'use strict' directive used here. "foo"; "use strict"; ~~~~~~~~~~~~~ -!!! error TS1345: 'use strict' directive cannot be used with non simple parameter list. -!!! related TS1346 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:23: parameter is here. -!!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:31: and here. +!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:39:23: Non-simple parameter declared here. +!!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:39:31: and here. } function invalidPrologue(a = 10, b = 20) { diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.js b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.js index d8e50e9d1b6..f9e07fc96ea 100644 --- a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.js +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.js @@ -17,6 +17,10 @@ function rest(...args: any[]) { 'use strict'; } +function rest1(a = 1, ...args) { + 'use strict'; +} + function paramDefault(param = 1) { 'use strict'; } @@ -60,6 +64,9 @@ function container() { function rest(...args) { 'use strict'; } +function rest1(a = 1, ...args) { + 'use strict'; +} function paramDefault(param = 1) { 'use strict'; } diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.symbols b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.symbols index 444f219ab2f..8f3d1366ad2 100644 --- a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.symbols +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.symbols @@ -31,52 +31,60 @@ function rest(...args: any[]) { 'use strict'; } +function rest1(a = 1, ...args) { +>rest1 : Symbol(rest1, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 16, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 18, 15)) +>args : Symbol(args, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 18, 21)) + + 'use strict'; +} + function paramDefault(param = 1) { ->paramDefault : Symbol(paramDefault, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 16, 1)) ->param : Symbol(param, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 18, 22)) +>paramDefault : Symbol(paramDefault, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 20, 1)) +>param : Symbol(param, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 22, 22)) 'use strict'; } function objectBindingPattern({foo}: any) { ->objectBindingPattern : Symbol(objectBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 20, 1)) ->foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 22, 31)) +>objectBindingPattern : Symbol(objectBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 24, 1)) +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 26, 31)) 'use strict'; } function arrayBindingPattern([foo]: any[]) { ->arrayBindingPattern : Symbol(arrayBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 24, 1)) ->foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 26, 30)) +>arrayBindingPattern : Symbol(arrayBindingPattern, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 28, 1)) +>foo : Symbol(foo, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 30, 30)) 'use strict'; } function manyParameter(a = 10, b = 20) { ->manyParameter : Symbol(manyParameter, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 28, 1)) ->a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 30, 23)) ->b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 30, 30)) +>manyParameter : Symbol(manyParameter, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 32, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 34, 23)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 34, 30)) "use strict"; } function manyPrologue(a = 10, b = 20) { ->manyPrologue : Symbol(manyPrologue, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 32, 1)) ->a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 34, 22)) ->b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 34, 29)) +>manyPrologue : Symbol(manyPrologue, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 36, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 38, 22)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 38, 29)) "foo"; "use strict"; } function invalidPrologue(a = 10, b = 20) { ->invalidPrologue : Symbol(invalidPrologue, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 37, 1)) ->a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 39, 25)) ->b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 39, 32)) +>invalidPrologue : Symbol(invalidPrologue, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 41, 1)) +>a : Symbol(a, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 43, 25)) +>b : Symbol(b, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 43, 32)) "foo"; const c = 1; ->c : Symbol(c, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 41, 9)) +>c : Symbol(c, Decl(functionWithUseStrictAndSimpleParameterList_es2016.ts, 45, 9)) "use strict"; } diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.types b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.types index 19f3d7f015b..c5268cd8e48 100644 --- a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.types +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.types @@ -39,6 +39,16 @@ function rest(...args: any[]) { >'use strict' : "use strict" } +function rest1(a = 1, ...args) { +>rest1 : (a?: number, ...args: any[]) => void +>a : number +>1 : 1 +>args : any[] + + 'use strict'; +>'use strict' : "use strict" +} + function paramDefault(param = 1) { >paramDefault : (param?: number) => void >param : number diff --git a/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts b/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts index 65be76d500c..d4b8ced9b42 100644 --- a/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts +++ b/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList.ts @@ -16,6 +16,10 @@ function rest(...args: any[]) { 'use strict'; } +function rest1(a = 1, ...args) { + 'use strict'; +} + function paramDefault(param = 1) { 'use strict'; } diff --git a/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts b/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts index ed17746931a..6c9fadd1ac1 100644 --- a/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts +++ b/tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts @@ -18,6 +18,10 @@ function rest(...args: any[]) { 'use strict'; } +function rest1(a = 1, ...args) { + 'use strict'; +} + function paramDefault(param = 1) { 'use strict'; } From 23640d971b09c8cf931cb59292b40ce96692a5db Mon Sep 17 00:00:00 2001 From: Rhys van der Waerden Date: Wed, 1 Aug 2018 16:44:53 +1000 Subject: [PATCH 010/163] Fix issue with Array#flatMap callback return type Closes #22685 --- src/lib/esnext.array.d.ts | 4 +-- tests/baselines/reference/arrayFlatMap.js | 12 +++++++++ .../baselines/reference/arrayFlatMap.symbols | 20 +++++++++++++++ tests/baselines/reference/arrayFlatMap.types | 25 +++++++++++++++++++ tests/cases/compiler/arrayFlatMap.ts | 6 +++++ 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/arrayFlatMap.js create mode 100644 tests/baselines/reference/arrayFlatMap.symbols create mode 100644 tests/baselines/reference/arrayFlatMap.types create mode 100644 tests/cases/compiler/arrayFlatMap.ts diff --git a/src/lib/esnext.array.d.ts b/src/lib/esnext.array.d.ts index b602e8cc0e8..33bee0c205e 100644 --- a/src/lib/esnext.array.d.ts +++ b/src/lib/esnext.array.d.ts @@ -11,7 +11,7 @@ interface ReadonlyArray { * thisArg is omitted, undefined is used as the this value. */ flatMap ( - callback: (this: This, value: T, index: number, array: T[]) => U|U[], + callback: (this: This, value: T, index: number, array: T[]) => U|ReadonlyArray, thisArg?: This ): U[] @@ -125,7 +125,7 @@ interface Array { * thisArg is omitted, undefined is used as the this value. */ flatMap ( - callback: (this: This, value: T, index: number, array: T[]) => U|U[], + callback: (this: This, value: T, index: number, array: T[]) => U|ReadonlyArray, thisArg?: This ): U[] diff --git a/tests/baselines/reference/arrayFlatMap.js b/tests/baselines/reference/arrayFlatMap.js new file mode 100644 index 00000000000..3c35cedc1f3 --- /dev/null +++ b/tests/baselines/reference/arrayFlatMap.js @@ -0,0 +1,12 @@ +//// [arrayFlatMap.ts] +const array: number[] = []; +const readonlyArray: ReadonlyArray = []; +array.flatMap((): ReadonlyArray => []); // ok +readonlyArray.flatMap((): ReadonlyArray => []); // ok + + +//// [arrayFlatMap.js] +var array = []; +var readonlyArray = []; +array.flatMap(function () { return []; }); // ok +readonlyArray.flatMap(function () { return []; }); // ok diff --git a/tests/baselines/reference/arrayFlatMap.symbols b/tests/baselines/reference/arrayFlatMap.symbols new file mode 100644 index 00000000000..0a97341657b --- /dev/null +++ b/tests/baselines/reference/arrayFlatMap.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/arrayFlatMap.ts === +const array: number[] = []; +>array : Symbol(array, Decl(arrayFlatMap.ts, 0, 5)) + +const readonlyArray: ReadonlyArray = []; +>readonlyArray : Symbol(readonlyArray, Decl(arrayFlatMap.ts, 1, 5)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --), Decl(lib.esnext.array.d.ts, --, --)) + +array.flatMap((): ReadonlyArray => []); // ok +>array.flatMap : Symbol(Array.flatMap, Decl(lib.esnext.array.d.ts, --, --)) +>array : Symbol(array, Decl(arrayFlatMap.ts, 0, 5)) +>flatMap : Symbol(Array.flatMap, Decl(lib.esnext.array.d.ts, --, --)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --), Decl(lib.esnext.array.d.ts, --, --)) + +readonlyArray.flatMap((): ReadonlyArray => []); // ok +>readonlyArray.flatMap : Symbol(ReadonlyArray.flatMap, Decl(lib.esnext.array.d.ts, --, --)) +>readonlyArray : Symbol(readonlyArray, Decl(arrayFlatMap.ts, 1, 5)) +>flatMap : Symbol(ReadonlyArray.flatMap, Decl(lib.esnext.array.d.ts, --, --)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --), Decl(lib.esnext.array.d.ts, --, --)) + diff --git a/tests/baselines/reference/arrayFlatMap.types b/tests/baselines/reference/arrayFlatMap.types new file mode 100644 index 00000000000..7eb4d444ecf --- /dev/null +++ b/tests/baselines/reference/arrayFlatMap.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/arrayFlatMap.ts === +const array: number[] = []; +>array : number[] +>[] : undefined[] + +const readonlyArray: ReadonlyArray = []; +>readonlyArray : ReadonlyArray +>[] : undefined[] + +array.flatMap((): ReadonlyArray => []); // ok +>array.flatMap((): ReadonlyArray => []) : number[] +>array.flatMap : (callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray, thisArg?: This) => U[] +>array : number[] +>flatMap : (callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray, thisArg?: This) => U[] +>(): ReadonlyArray => [] : () => ReadonlyArray +>[] : undefined[] + +readonlyArray.flatMap((): ReadonlyArray => []); // ok +>readonlyArray.flatMap((): ReadonlyArray => []) : number[] +>readonlyArray.flatMap : (callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray, thisArg?: This) => U[] +>readonlyArray : ReadonlyArray +>flatMap : (callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray, thisArg?: This) => U[] +>(): ReadonlyArray => [] : () => ReadonlyArray +>[] : undefined[] + diff --git a/tests/cases/compiler/arrayFlatMap.ts b/tests/cases/compiler/arrayFlatMap.ts new file mode 100644 index 00000000000..dc67bf02490 --- /dev/null +++ b/tests/cases/compiler/arrayFlatMap.ts @@ -0,0 +1,6 @@ +// @lib: esnext + +const array: number[] = []; +const readonlyArray: ReadonlyArray = []; +array.flatMap((): ReadonlyArray => []); // ok +readonlyArray.flatMap((): ReadonlyArray => []); // ok From 6df61272f3058db3c13f820009f8a2595d47a5a7 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Fri, 3 Aug 2018 17:54:15 +0200 Subject: [PATCH 011/163] createProgram: don't use TypeChecker Avoids using the TypeChecker when trying to reuse the Program structure. This allows SourceFiles contained in the old Program to be updated using ts.updateSourceFile Fixes: #26166 --- src/compiler/program.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index c70477b4a17..14063029c59 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -951,8 +951,11 @@ namespace ts { // If we change our policy of rechecking failed lookups on each program create, // we should adjust the value returned here. function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string, oldProgramState: OldProgramState): boolean { + if (!oldProgramState.program) { + return false; + } const resolutionToFile = getResolvedModule(oldProgramState.oldSourceFile!, moduleName); // TODO: GH#18217 - const resolvedFile = resolutionToFile && oldProgramState.program && oldProgramState.program.getSourceFile(resolutionToFile.resolvedFileName); + const resolvedFile = resolutionToFile && oldProgramState.program.getSourceFile(resolutionToFile.resolvedFileName); if (resolutionToFile && resolvedFile && !resolvedFile.externalModuleIndicator) { // In the old program, we resolved to an ambient module that was in the same // place as we expected to find an actual module file. @@ -960,16 +963,11 @@ namespace ts { // because the normal module resolution algorithm will find this anyway. return false; } - const ambientModule = oldProgramState.program && oldProgramState.program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName); - if (!(ambientModule && ambientModule.declarations)) { - return false; - } // at least one of declarations should come from non-modified source file - const firstUnmodifiedFile = forEach(ambientModule.declarations, d => { - const f = getSourceFileOfNode(d); - return !contains(oldProgramState.modifiedFilePaths, f.path) && f; - }); + const firstUnmodifiedFile = oldProgramState.program.getSourceFiles().find( + f => !contains(oldProgramState.modifiedFilePaths, f.path) && contains(f.ambientModuleNames, moduleName) + ); if (!firstUnmodifiedFile) { return false; From a1978eb8a1e2d6697230299fb29d250582af124d Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Fri, 3 Aug 2018 22:09:53 +0200 Subject: [PATCH 012/163] add test --- .../unittests/reuseProgramStructure.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index 44082f3a302..cf0881dfefa 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -399,6 +399,29 @@ namespace ts { assert.isDefined(program2.getSourceFile("/a.ts")!.resolvedModules!.get("a"), "'a' is not an unresolved module after re-use"); }); + it("works with updated SourceFiles", () => { + const files = [ + { name: "/a.ts", text: SourceText.New("", "", 'import * as a from "a";a;') }, + { name: "/types/zzz/index.d.ts", text: SourceText.New("", "", 'declare module "a" { }') }, + ]; + const host = createTestCompilerHost(files, target); + const options: CompilerOptions = { target, typeRoots: ["/types"] }; + const program1 = createProgram(["/a.ts"], options, host); + let sourceFile = program1.getSourceFile("/a.ts")!; + assert.isDefined(sourceFile, "'/a.ts' is included in the program"); + sourceFile = updateSourceFile(sourceFile, "'use strict';" + sourceFile.text, { newLength: "'use strict';".length, span: { start: 0, length: 0 } }); + assert.strictEqual(sourceFile.statements[2].getSourceFile(), sourceFile, "parent pointers are updated"); + const updateHost: TestCompilerHost = { + ...host, + getSourceFile(fileName) { + return fileName === sourceFile.fileName ? sourceFile : program1.getSourceFile(fileName); + } + }; + const program2 = createProgram(["/a.ts"], options, updateHost, program1); + assert.isDefined(program2.getSourceFile("/a.ts")!.resolvedModules!.get("a"), "'a' is not an unresolved module after re-use"); + assert.strictEqual(sourceFile.statements[2].getSourceFile(), sourceFile, "parent pointers are not altered"); + }); + it("resolved type directives cache follows type directives", () => { const files = [ { name: "/a.ts", text: SourceText.New("/// ", "", "var x = $") }, From 3b022a4e6633e79a1cf79e0b4bb13132864a9668 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Fri, 3 Aug 2018 23:19:04 +0200 Subject: [PATCH 013/163] add link to issue --- src/testRunner/unittests/reuseProgramStructure.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index cf0881dfefa..23d658ad483 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -400,6 +400,7 @@ namespace ts { }); it("works with updated SourceFiles", () => { + // adapted repro from https://github.com/Microsoft/TypeScript/issues/26166 const files = [ { name: "/a.ts", text: SourceText.New("", "", 'import * as a from "a";a;') }, { name: "/types/zzz/index.d.ts", text: SourceText.New("", "", 'declare module "a" { }') }, From 711b5660cbe1cb715d34713461821733a6af0e40 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Wed, 8 Aug 2018 21:16:09 +0200 Subject: [PATCH 014/163] unittests/moduleResolution: actually assert in checkResolvedModule this change uncovered a bug in testPreserveSymlinks which always silently failed --- src/testRunner/unittests/moduleResolution.ts | 29 +++++++++++++------ .../unittests/reuseProgramStructure.ts | 13 +++------ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/testRunner/unittests/moduleResolution.ts b/src/testRunner/unittests/moduleResolution.ts index e97a3f5fc42..52c11d04fd9 100644 --- a/src/testRunner/unittests/moduleResolution.ts +++ b/src/testRunner/unittests/moduleResolution.ts @@ -1,14 +1,21 @@ namespace ts { - export function checkResolvedModule(expected: ResolvedModuleFull | undefined, actual: ResolvedModuleFull): boolean { - if (!expected === !actual) { - if (expected) { - assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`); - assert.isTrue(expected.extension === actual.extension, `'ext': expected '${expected.extension}' to be equal to '${actual.extension}'`); - assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`); + export function checkResolvedModule(actual: ResolvedModuleFull | undefined, expected: ResolvedModuleFull | undefined): boolean { + if (!expected) { + if (actual) { + assert.fail(actual, expected, "expected resolved module to be undefined"); + return false; } return true; } - return false; + else if (!actual) { + assert.fail(actual, expected, "expected resolved module to be defined"); + return false; + } + + assert.isTrue(actual.resolvedFileName === expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`); + assert.isTrue(actual.extension === expected.extension, `'ext': expected '${actual.extension}' to be equal to '${expected.extension}'`); + assert.isTrue(actual.isExternalLibraryImport === expected.isExternalLibraryImport, `'isExternalLibraryImport': expected '${actual.isExternalLibraryImport}' to be equal to '${expected.isExternalLibraryImport}'`); + return true; } export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModuleFull, expectedFailedLookupLocations: string[]): void { @@ -314,8 +321,12 @@ namespace ts { function testPreserveSymlinks(preserveSymlinks: boolean) { it(`preserveSymlinks: ${preserveSymlinks}`, () => { const realFileName = "/linked/index.d.ts"; - const symlinkFileName = "/app/node_modulex/linked/index.d.ts"; - const host = createModuleResolutionHost(/*hasDirectoryExists*/ true, { name: realFileName, symlinks: [symlinkFileName] }); + const symlinkFileName = "/app/node_modules/linked/index.d.ts"; + const host = createModuleResolutionHost( + /*hasDirectoryExists*/ true, + { name: realFileName, symlinks: [symlinkFileName] }, + { name: "/app/node_modules/linked/package.json", content: '{"version": "0.0.0", "main": "./index"}' }, + ); const resolution = nodeModuleNameResolver("linked", "/app/app.ts", { preserveSymlinks }, host); const resolvedFileName = preserveSymlinks ? symlinkFileName : realFileName; checkResolvedModule(resolution.resolvedModule, createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/ true)); diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index 44082f3a302..63095e3c018 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -177,15 +177,10 @@ namespace ts { file.text = file.text.updateProgram(newProgramText); } - function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): boolean { - if (!expected === !actual) { - if (expected) { - assert.equal(expected.resolvedFileName, actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`); - assert.equal(expected.primary, actual.primary, `'primary': expected '${expected.primary}' to be equal to '${actual.primary}'`); - } - return true; - } - return false; + function checkResolvedTypeDirective(actual: ResolvedTypeReferenceDirective, expected: ResolvedTypeReferenceDirective) { + assert.equal(actual.resolvedFileName, expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`); + assert.equal(actual.primary, expected.primary, `'primary': expected '${actual.primary}' to be equal to '${expected.primary}'`); + return true; } function checkCache(caption: string, program: Program, fileName: string, expectedContent: Map | undefined, getCache: (f: SourceFile) => Map | undefined, entryChecker: (expected: T, original: T) => boolean): void { From 6432bd9defc25917a0f55b9440a9321e61e81482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Wed, 8 Aug 2018 16:01:15 +0800 Subject: [PATCH 015/163] check index access for fixed length tuple --- src/compiler/checker.ts | 7 +++ src/compiler/diagnosticMessages.json | 4 ++ .../bestCommonTypeOfTuple.errors.txt | 40 +++++++++++++++ .../bestCommonTypeOfTuple2.errors.txt | 40 +++++++++++++++ .../reference/castingTuple.errors.txt | 5 +- .../emptyTuplesTypeAssertion01.errors.txt | 8 +++ .../emptyTuplesTypeAssertion02.errors.txt | 8 +++ .../genericCallWithTupleType.errors.txt | 11 ++++- .../reference/indexerWithTuple.errors.txt | 47 ++++++++++++++++++ .../reference/tupleLengthCheck.errors.txt | 21 ++++++++ tests/baselines/reference/tupleLengthCheck.js | 22 +++++++++ .../reference/tupleLengthCheck.symbols | 37 ++++++++++++++ .../reference/tupleLengthCheck.types | 49 +++++++++++++++++++ .../baselines/reference/tupleTypes.errors.txt | 8 ++- .../types/tuple/tupleLengthCheck.ts | 11 +++++ 15 files changed, 315 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/bestCommonTypeOfTuple.errors.txt create mode 100644 tests/baselines/reference/bestCommonTypeOfTuple2.errors.txt create mode 100644 tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt create mode 100644 tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt create mode 100644 tests/baselines/reference/indexerWithTuple.errors.txt create mode 100644 tests/baselines/reference/tupleLengthCheck.errors.txt create mode 100644 tests/baselines/reference/tupleLengthCheck.js create mode 100644 tests/baselines/reference/tupleLengthCheck.symbols create mode 100644 tests/baselines/reference/tupleLengthCheck.types create mode 100644 tests/cases/conformance/types/tuple/tupleLengthCheck.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2a38d425afb..2e3b37d2a16 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18293,6 +18293,13 @@ namespace ts { error(indexExpression, Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal); return errorType; } + if (isTupleType(objectType) && !objectType.target.hasRestElement && isNumericLiteral(indexExpression)) { + const index = +indexExpression.text; + const maximumIndex = length(objectType.target.typeParameters); + if (index >= maximumIndex) { + error(indexExpression, Diagnostics.Index_0_is_out_of_bounds_in_tuple_of_length_1, index, maximumIndex); + } + } return checkIndexedAccessIndexType(getIndexedAccessType(objectType, indexType, node), node); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ae6ec40fd93..83cf6db75e8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2437,6 +2437,10 @@ "category": "Error", "code": 2732 }, + "Index '{0}' is out-of-bounds in tuple of length {1}.": { + "category": "Error", + "code": 2733 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/bestCommonTypeOfTuple.errors.txt b/tests/baselines/reference/bestCommonTypeOfTuple.errors.txt new file mode 100644 index 00000000000..2c57099c3e8 --- /dev/null +++ b/tests/baselines/reference/bestCommonTypeOfTuple.errors.txt @@ -0,0 +1,40 @@ +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(22,13): error TS2733: Index '2' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(23,13): error TS2733: Index '2' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(24,13): error TS2733: Index '2' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts(25,13): error TS2733: Index '3' is out-of-bounds in tuple of length 3. + + +==== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts (4 errors) ==== + function f1(x: number): string { return "foo"; } + + function f2(x: number): number { return 10; } + + function f3(x: number): boolean { return true; } + + enum E1 { one } + + enum E2 { two } + + + var t1: [(x: number) => string, (x: number) => number]; + var t2: [E1, E2]; + var t3: [number, any]; + var t4: [E1, E2, number]; + + // no error + t1 = [f1, f2]; + t2 = [E1.one, E2.two]; + t3 = [5, undefined]; + t4 = [E1.one, E2.two, 20]; + var e1 = t1[2]; // {} + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + var e2 = t2[2]; // {} + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + var e3 = t3[2]; // any + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + var e4 = t4[3]; // number + ~ +!!! error TS2733: Index '3' is out-of-bounds in tuple of length 3. \ No newline at end of file diff --git a/tests/baselines/reference/bestCommonTypeOfTuple2.errors.txt b/tests/baselines/reference/bestCommonTypeOfTuple2.errors.txt new file mode 100644 index 00000000000..80f40c74a07 --- /dev/null +++ b/tests/baselines/reference/bestCommonTypeOfTuple2.errors.txt @@ -0,0 +1,40 @@ +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(17,14): error TS2733: Index '4' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(18,14): error TS2733: Index '4' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(19,14): error TS2733: Index '4' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(20,14): error TS2733: Index '2' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts(21,14): error TS2733: Index '2' is out-of-bounds in tuple of length 2. + + +==== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts (5 errors) ==== + interface base { } + interface base1 { i } + class C implements base { c } + class D implements base { d } + class E implements base { e } + class F extends C { f } + + class C1 implements base1 { i = "foo"; c } + class D1 extends C1 { i = "bar"; d } + + var t1: [C, base]; + var t2: [C, D]; + var t3: [C1, D1]; + var t4: [base1, C1]; + var t5: [C1, F] + + var e11 = t1[4]; // base + ~ +!!! error TS2733: Index '4' is out-of-bounds in tuple of length 2. + var e21 = t2[4]; // {} + ~ +!!! error TS2733: Index '4' is out-of-bounds in tuple of length 2. + var e31 = t3[4]; // C1 + ~ +!!! error TS2733: Index '4' is out-of-bounds in tuple of length 2. + var e41 = t4[2]; // base1 + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + var e51 = t5[2]; // {} + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + \ No newline at end of file diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt index c7b00e2a0ca..e8bc9133a8a 100644 --- a/tests/baselines/reference/castingTuple.errors.txt +++ b/tests/baselines/reference/castingTuple.errors.txt @@ -6,6 +6,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(14,15): error TS2352: Conver tests/cases/conformance/types/tuple/castingTuple.ts(15,14): error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Conversion of type '[C, D]' to type '[C, D, A]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Property '2' is missing in type '[C, D]'. +tests/cases/conformance/types/tuple/castingTuple.ts(20,33): error TS2733: Index '5' is out-of-bounds in tuple of length 3. tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Conversion of type '[number, string]' to type '[number, number]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Type 'string' is not comparable to type 'number'. tests/cases/conformance/types/tuple/castingTuple.ts(31,10): error TS2352: Conversion of type '[C, D]' to type '[A, I]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. @@ -15,7 +16,7 @@ tests/cases/conformance/types/tuple/castingTuple.ts(32,5): error TS2403: Subsequ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot find name 't4'. -==== tests/cases/conformance/types/tuple/castingTuple.ts (8 errors) ==== +==== tests/cases/conformance/types/tuple/castingTuple.ts (9 errors) ==== interface I { } class A { a = 10; } class C implements I { c }; @@ -48,6 +49,8 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot !!! error TS2352: Property '2' is missing in type '[C, D]'. var eleFromCDA1 = classCDATuple[2]; // A var eleFromCDA2 = classCDATuple[5]; // C | D | A + ~ +!!! error TS2733: Index '5' is out-of-bounds in tuple of length 3. var t10: [E1, E2] = [E1.one, E2.one]; var t11 = <[number, number]>t10; var array1 = <{}[]>emptyObjTuple; diff --git a/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt b/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt new file mode 100644 index 00000000000..4b85b821a89 --- /dev/null +++ b/tests/baselines/reference/emptyTuplesTypeAssertion01.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts(2,11): error TS2733: Index '0' is out-of-bounds in tuple of length 0. + + +==== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion01.ts (1 errors) ==== + let x = <[]>[]; + let y = x[0]; + ~ +!!! error TS2733: Index '0' is out-of-bounds in tuple of length 0. \ No newline at end of file diff --git a/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt b/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt new file mode 100644 index 00000000000..3969ed0fc2d --- /dev/null +++ b/tests/baselines/reference/emptyTuplesTypeAssertion02.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts(2,11): error TS2733: Index '0' is out-of-bounds in tuple of length 0. + + +==== tests/cases/conformance/types/tuple/emptyTuples/emptyTuplesTypeAssertion02.ts (1 errors) ==== + let x = [] as []; + let y = x[0]; + ~ +!!! error TS2733: Index '0' is out-of-bounds in tuple of length 0. \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithTupleType.errors.txt b/tests/baselines/reference/genericCallWithTupleType.errors.txt index 1136022e2fe..6e6732ebb09 100644 --- a/tests/baselines/reference/genericCallWithTupleType.errors.txt +++ b/tests/baselines/reference/genericCallWithTupleType.errors.txt @@ -1,8 +1,11 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(12,1): error TS2322: Type '[string, number, boolean, boolean]' is not assignable to type '[string, number]'. Types of property 'length' are incompatible. Type '4' is not assignable to type '2'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(13,20): error TS2733: Index '2' is out-of-bounds in tuple of length 2. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,1): error TS2322: Type '{ a: string; }' is not assignable to type 'string | number'. Type '{ a: string; }' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(14,11): error TS2733: Index '3' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(15,20): error TS2733: Index '3' is out-of-bounds in tuple of length 2. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,14): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,17): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(23,14): error TS2322: Type '{}' is not assignable to type 'string'. @@ -11,7 +14,7 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup Property '1' is missing in type '[{}]'. -==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts (7 errors) ==== +==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts (10 errors) ==== interface I { tuple1: [T, U]; } @@ -29,11 +32,17 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTup !!! error TS2322: Types of property 'length' are incompatible. !!! error TS2322: Type '4' is not assignable to type '2'. var e3 = i1.tuple1[2]; // {} + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. i1.tuple1[3] = { a: "string" }; ~~~~~~~~~~~~ !!! error TS2322: Type '{ a: string; }' is not assignable to type 'string | number'. !!! error TS2322: Type '{ a: string; }' is not assignable to type 'number'. + ~ +!!! error TS2733: Index '3' is out-of-bounds in tuple of length 2. var e4 = i1.tuple1[3]; // {} + ~ +!!! error TS2733: Index '3' is out-of-bounds in tuple of length 2. i2.tuple1 = ["foo", 5]; i2.tuple1 = ["foo", "bar"]; i2.tuple1 = [5, "bar"]; diff --git a/tests/baselines/reference/indexerWithTuple.errors.txt b/tests/baselines/reference/indexerWithTuple.errors.txt new file mode 100644 index 00000000000..4e931a3ad6e --- /dev/null +++ b/tests/baselines/reference/indexerWithTuple.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/types/tuple/indexerWithTuple.ts(11,25): error TS2733: Index '2' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/tuple/indexerWithTuple.ts(17,27): error TS2733: Index '2' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/tuple/indexerWithTuple.ts(20,30): error TS2733: Index '2' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/tuple/indexerWithTuple.ts(28,30): error TS2733: Index '2' is out-of-bounds in tuple of length 2. + + +==== tests/cases/conformance/types/tuple/indexerWithTuple.ts (4 errors) ==== + var strNumTuple: [string, number] = ["foo", 10]; + var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; + var unionTuple1: [number, string| number] = [10, "foo"]; + var unionTuple2: [boolean, string| number] = [true, "foo"]; + + // no error + var idx0 = 0; + var idx1 = 1; + var ele10 = strNumTuple[0]; // string + var ele11 = strNumTuple[1]; // number + var ele12 = strNumTuple[2]; // string | number + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + var ele13 = strNumTuple[idx0]; // string | number + var ele14 = strNumTuple[idx1]; // string | number + var ele15 = strNumTuple["0"]; // string + var ele16 = strNumTuple["1"]; // number + var strNumTuple1 = numTupleTuple[1]; //[string, number]; + var ele17 = numTupleTuple[2]; // number | [string, number] + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + var eleUnion10 = unionTuple1[0]; // number + var eleUnion11 = unionTuple1[1]; // string | number + var eleUnion12 = unionTuple1[2]; // string | number + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + var eleUnion13 = unionTuple1[idx0]; // string | number + var eleUnion14 = unionTuple1[idx1]; // string | number + var eleUnion15 = unionTuple1["0"]; // number + var eleUnion16 = unionTuple1["1"]; // string | number + + var eleUnion20 = unionTuple2[0]; // boolean + var eleUnion21 = unionTuple2[1]; // string | number + var eleUnion22 = unionTuple2[2]; // string | number | boolean + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + var eleUnion23 = unionTuple2[idx0]; // string | number | boolean + var eleUnion24 = unionTuple2[idx1]; // string | number | boolean + var eleUnion25 = unionTuple2["0"]; // boolean + var eleUnion26 = unionTuple2["1"]; // string | number \ No newline at end of file diff --git a/tests/baselines/reference/tupleLengthCheck.errors.txt b/tests/baselines/reference/tupleLengthCheck.errors.txt new file mode 100644 index 00000000000..f90adbf3525 --- /dev/null +++ b/tests/baselines/reference/tupleLengthCheck.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/types/tuple/tupleLengthCheck.ts(5,14): error TS2733: Index '2' is out-of-bounds in tuple of length 2. +tests/cases/conformance/types/tuple/tupleLengthCheck.ts(6,14): error TS2733: Index '1000' is out-of-bounds in tuple of length 2. + + +==== tests/cases/conformance/types/tuple/tupleLengthCheck.ts (2 errors) ==== + declare const a: [number, string] + declare const rest: [number, string, ...boolean[]] + + const a1 = a[1] + const a2 = a[2] + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. + const a3 = a[1000] + ~~~~ +!!! error TS2733: Index '1000' is out-of-bounds in tuple of length 2. + + const a4 = rest[1] + const a5 = rest[2] + const a6 = rest[3] + const a7 = rest[1000] + \ No newline at end of file diff --git a/tests/baselines/reference/tupleLengthCheck.js b/tests/baselines/reference/tupleLengthCheck.js new file mode 100644 index 00000000000..23e97c47593 --- /dev/null +++ b/tests/baselines/reference/tupleLengthCheck.js @@ -0,0 +1,22 @@ +//// [tupleLengthCheck.ts] +declare const a: [number, string] +declare const rest: [number, string, ...boolean[]] + +const a1 = a[1] +const a2 = a[2] +const a3 = a[1000] + +const a4 = rest[1] +const a5 = rest[2] +const a6 = rest[3] +const a7 = rest[1000] + + +//// [tupleLengthCheck.js] +var a1 = a[1]; +var a2 = a[2]; +var a3 = a[1000]; +var a4 = rest[1]; +var a5 = rest[2]; +var a6 = rest[3]; +var a7 = rest[1000]; diff --git a/tests/baselines/reference/tupleLengthCheck.symbols b/tests/baselines/reference/tupleLengthCheck.symbols new file mode 100644 index 00000000000..ffa524e3ca4 --- /dev/null +++ b/tests/baselines/reference/tupleLengthCheck.symbols @@ -0,0 +1,37 @@ +=== tests/cases/conformance/types/tuple/tupleLengthCheck.ts === +declare const a: [number, string] +>a : Symbol(a, Decl(tupleLengthCheck.ts, 0, 13)) + +declare const rest: [number, string, ...boolean[]] +>rest : Symbol(rest, Decl(tupleLengthCheck.ts, 1, 13)) + +const a1 = a[1] +>a1 : Symbol(a1, Decl(tupleLengthCheck.ts, 3, 5)) +>a : Symbol(a, Decl(tupleLengthCheck.ts, 0, 13)) +>1 : Symbol(1) + +const a2 = a[2] +>a2 : Symbol(a2, Decl(tupleLengthCheck.ts, 4, 5)) +>a : Symbol(a, Decl(tupleLengthCheck.ts, 0, 13)) + +const a3 = a[1000] +>a3 : Symbol(a3, Decl(tupleLengthCheck.ts, 5, 5)) +>a : Symbol(a, Decl(tupleLengthCheck.ts, 0, 13)) + +const a4 = rest[1] +>a4 : Symbol(a4, Decl(tupleLengthCheck.ts, 7, 5)) +>rest : Symbol(rest, Decl(tupleLengthCheck.ts, 1, 13)) +>1 : Symbol(1) + +const a5 = rest[2] +>a5 : Symbol(a5, Decl(tupleLengthCheck.ts, 8, 5)) +>rest : Symbol(rest, Decl(tupleLengthCheck.ts, 1, 13)) + +const a6 = rest[3] +>a6 : Symbol(a6, Decl(tupleLengthCheck.ts, 9, 5)) +>rest : Symbol(rest, Decl(tupleLengthCheck.ts, 1, 13)) + +const a7 = rest[1000] +>a7 : Symbol(a7, Decl(tupleLengthCheck.ts, 10, 5)) +>rest : Symbol(rest, Decl(tupleLengthCheck.ts, 1, 13)) + diff --git a/tests/baselines/reference/tupleLengthCheck.types b/tests/baselines/reference/tupleLengthCheck.types new file mode 100644 index 00000000000..be4372c669c --- /dev/null +++ b/tests/baselines/reference/tupleLengthCheck.types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/types/tuple/tupleLengthCheck.ts === +declare const a: [number, string] +>a : [number, string] + +declare const rest: [number, string, ...boolean[]] +>rest : [number, string, ...boolean[]] + +const a1 = a[1] +>a1 : string +>a[1] : string +>a : [number, string] +>1 : 1 + +const a2 = a[2] +>a2 : string | number +>a[2] : string | number +>a : [number, string] +>2 : 2 + +const a3 = a[1000] +>a3 : string | number +>a[1000] : string | number +>a : [number, string] +>1000 : 1000 + +const a4 = rest[1] +>a4 : string +>rest[1] : string +>rest : [number, string, ...boolean[]] +>1 : 1 + +const a5 = rest[2] +>a5 : boolean +>rest[2] : boolean +>rest : [number, string, ...boolean[]] +>2 : 2 + +const a6 = rest[3] +>a6 : boolean +>rest[3] : boolean +>rest : [number, string, ...boolean[]] +>3 : 3 + +const a7 = rest[1000] +>a7 : boolean +>rest[1000] : boolean +>rest : [number, string, ...boolean[]] +>1000 : 1000 + diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index 87e17e14d3c..7e4e926492d 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -1,3 +1,4 @@ +tests/cases/compiler/tupleTypes.ts(11,12): error TS2733: Index '2' is out-of-bounds in tuple of length 2. tests/cases/compiler/tupleTypes.ts(14,1): error TS2322: Type '[]' is not assignable to type '[number, string]'. Property '0' is missing in type '[]'. tests/cases/compiler/tupleTypes.ts(15,1): error TS2322: Type '[number]' is not assignable to type '[number, string]'. @@ -7,6 +8,7 @@ tests/cases/compiler/tupleTypes.ts(17,15): error TS2322: Type 'number' is not as tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, number]' is not assignable to type '[number, string]'. Types of property 'length' are incompatible. Type '3' is not assignable to type '2'. +tests/cases/compiler/tupleTypes.ts(35,14): error TS2733: Index '2' is out-of-bounds in tuple of length 2. tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type '[]' is not assignable to type '[number, string]'. tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. Types of property 'pop' are incompatible. @@ -24,7 +26,7 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n Type '{}' is not assignable to type 'string'. -==== tests/cases/compiler/tupleTypes.ts (10 errors) ==== +==== tests/cases/compiler/tupleTypes.ts (12 errors) ==== var v1: []; // Error var v2: [number]; var v3: [number, string]; @@ -36,6 +38,8 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n var t1 = t[1]; // string var t1: string; var t2 = t[2]; // number|string + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. var t2: number|string; t = []; // Error @@ -74,6 +78,8 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n var tt1 = tt[1]; var tt1: string; var tt2 = tt[2]; + ~ +!!! error TS2733: Index '2' is out-of-bounds in tuple of length 2. var tt2: number | string; tt = tuple2(1, undefined); diff --git a/tests/cases/conformance/types/tuple/tupleLengthCheck.ts b/tests/cases/conformance/types/tuple/tupleLengthCheck.ts new file mode 100644 index 00000000000..593c47ee3b2 --- /dev/null +++ b/tests/cases/conformance/types/tuple/tupleLengthCheck.ts @@ -0,0 +1,11 @@ +declare const a: [number, string] +declare const rest: [number, string, ...boolean[]] + +const a1 = a[1] +const a2 = a[2] +const a3 = a[1000] + +const a4 = rest[1] +const a5 = rest[2] +const a6 = rest[3] +const a7 = rest[1000] From beed179f58a9557b194f1975accab9b21ba4fd7a Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Tue, 14 Aug 2018 22:38:03 +0200 Subject: [PATCH 016/163] disallow abstract property access in property initializer Fixes: #26407 --- src/compiler/checker.ts | 8 ++--- .../abstractPropertyInConstructor.errors.txt | 8 ++++- .../abstractPropertyInConstructor.js | 5 ++++ .../abstractPropertyInConstructor.symbols | 30 +++++++++++++------ .../abstractPropertyInConstructor.types | 13 ++++++++ .../compiler/abstractPropertyInConstructor.ts | 3 ++ 6 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f2c1c71eb6c..118963df145 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17779,7 +17779,7 @@ namespace ts { // Referencing abstract properties within their own constructors is not allowed if ((flags & ModifierFlags.Abstract) && isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) { const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!); - if (declaringClassDeclaration && isNodeWithinConstructorOfClass(node, declaringClassDeclaration)) { + if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node, declaringClassDeclaration)) { error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!)); // TODO: GH#18217 return false; } @@ -27146,9 +27146,9 @@ namespace ts { return result; } - function isNodeWithinConstructorOfClass(node: Node, classDeclaration: ClassLikeDeclaration) { - return findAncestor(node, element => { - if (isConstructorDeclaration(element) && nodeIsPresent(element.body) && element.parent === classDeclaration) { + function isNodeUsedDuringClassInitialization(node: Node, classDeclaration: ClassLikeDeclaration) { + return !!findAncestor(node, element => { + if ((isConstructorDeclaration(element) && nodeIsPresent(element.body) || isPropertyDeclaration(element)) && element.parent === classDeclaration) { return true; } else if (element === classDeclaration || isFunctionLikeDeclaration(element)) { diff --git a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt index 0798d91ce78..5337bfc538a 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.errors.txt +++ b/tests/baselines/reference/abstractPropertyInConstructor.errors.txt @@ -1,9 +1,10 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(4,24): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor. tests/cases/compiler/abstractPropertyInConstructor.ts(7,18): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor. tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor. +tests/cases/compiler/abstractPropertyInConstructor.ts(25,18): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor. -==== tests/cases/compiler/abstractPropertyInConstructor.ts (3 errors) ==== +==== tests/cases/compiler/abstractPropertyInConstructor.ts (4 errors) ==== abstract class AbstractClass { constructor(str: string, other: AbstractClass) { this.method(parseInt(str)); @@ -34,6 +35,11 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstr abstract method(num: number): void; + other = this.prop; + ~~~~ +!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor. + fn = () => this.prop; + method2() { this.prop = this.prop + "!"; } diff --git a/tests/baselines/reference/abstractPropertyInConstructor.js b/tests/baselines/reference/abstractPropertyInConstructor.js index 5a4feda110f..782419ac67b 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.js +++ b/tests/baselines/reference/abstractPropertyInConstructor.js @@ -23,6 +23,9 @@ abstract class AbstractClass { abstract method(num: number): void; + other = this.prop; + fn = () => this.prop; + method2() { this.prop = this.prop + "!"; } @@ -42,6 +45,8 @@ class User { var AbstractClass = /** @class */ (function () { function AbstractClass(str, other) { var _this = this; + this.other = this.prop; + this.fn = function () { return _this.prop; }; this.method(parseInt(str)); var val = this.prop.toLowerCase(); if (!str) { diff --git a/tests/baselines/reference/abstractPropertyInConstructor.symbols b/tests/baselines/reference/abstractPropertyInConstructor.symbols index f1baa962072..71f897118c8 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.symbols +++ b/tests/baselines/reference/abstractPropertyInConstructor.symbols @@ -67,8 +67,20 @@ abstract class AbstractClass { >method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37)) >num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 22, 20)) + other = this.prop; +>other : Symbol(AbstractClass.other, Decl(abstractPropertyInConstructor.ts, 22, 39)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) + + fn = () => this.prop; +>fn : Symbol(AbstractClass.fn, Decl(abstractPropertyInConstructor.ts, 24, 22)) +>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) +>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) +>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) + method2() { ->method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39)) +>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 25, 25)) this.prop = this.prop + "!"; >this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) @@ -81,31 +93,31 @@ abstract class AbstractClass { } class User { ->User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 27, 1)) +>User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 30, 1)) constructor(a: AbstractClass) { ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16)) >AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0)) a.prop; >a.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16)) >prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5)) a.cb("hi"); >a.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16)) >cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26)) a.method(12); >a.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37)) ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16)) >method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37)) a.method2(); ->a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39)) ->a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16)) ->method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39)) +>a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 25, 25)) +>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16)) +>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 25, 25)) } } diff --git a/tests/baselines/reference/abstractPropertyInConstructor.types b/tests/baselines/reference/abstractPropertyInConstructor.types index 23e1aac50f7..465e0fb2f04 100644 --- a/tests/baselines/reference/abstractPropertyInConstructor.types +++ b/tests/baselines/reference/abstractPropertyInConstructor.types @@ -75,6 +75,19 @@ abstract class AbstractClass { >method : (num: number) => void >num : number + other = this.prop; +>other : string +>this.prop : string +>this : this +>prop : string + + fn = () => this.prop; +>fn : () => string +>() => this.prop : () => string +>this.prop : string +>this : this +>prop : string + method2() { >method2 : () => void diff --git a/tests/cases/compiler/abstractPropertyInConstructor.ts b/tests/cases/compiler/abstractPropertyInConstructor.ts index b8386f56e1e..5ea3569e20d 100644 --- a/tests/cases/compiler/abstractPropertyInConstructor.ts +++ b/tests/cases/compiler/abstractPropertyInConstructor.ts @@ -22,6 +22,9 @@ abstract class AbstractClass { abstract method(num: number): void; + other = this.prop; + fn = () => this.prop; + method2() { this.prop = this.prop + "!"; } From 6835a489173ca19c6fa0186c40f9f0dfc41486e8 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Tue, 21 Aug 2018 12:19:05 -0400 Subject: [PATCH 017/163] Fixes to the advice for untyped module imports from unknown packages: - For a sub-module, the `declare module` statement needs to refer to the sub-module. - For an import of "./node_modules/foo", don't show advice to install "@types/foo" or `declare module "foo"` because it won't help. Fixes #26581. --- src/compiler/checker.ts | 19 +++++++++++-------- ...port_noImplicitAny_relativePath.errors.txt | 2 -- ...mplicitAny_typesForPackageExist.errors.txt | 8 ++++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0b357bd771d..db717c107a9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2248,14 +2248,17 @@ namespace ts { } function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void { - const errorInfo = packageId - ? chainDiagnosticMessages( - /*details*/ undefined, - typesPackageExists(packageId.name) - ? Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1 - : Diagnostics.Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, - packageId.name, - getMangledNameForScopedPackage(packageId.name)) + const errorInfo = !isExternalModuleNameRelative(moduleReference) && packageId + ? typesPackageExists(packageId.name) + ? chainDiagnosticMessages( + /*details*/ undefined, + Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, + packageId.name, getMangledNameForScopedPackage(packageId.name)) + : chainDiagnosticMessages( + /*details*/ undefined, + Diagnostics.Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, + moduleReference, + getMangledNameForScopedPackage(packageId.name)) : undefined; errorOrSuggestion(isError, errorNode, chainDiagnosticMessages( errorInfo, diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.errors.txt b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.errors.txt index 1aeb8489b8d..6047cfa6a69 100644 --- a/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.errors.txt +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.errors.txt @@ -1,12 +1,10 @@ /a.ts(1,22): error TS7016: Could not find a declaration file for module './node_modules/foo'. '/node_modules/foo/index.js' implicitly has an 'any' type. - Try `npm install @types/foo` if it exists or add a new declaration (.d.ts) file containing `declare module 'foo';` ==== /a.ts (1 errors) ==== import * as foo from "./node_modules/foo"; ~~~~~~~~~~~~~~~~~~~~ !!! error TS7016: Could not find a declaration file for module './node_modules/foo'. '/node_modules/foo/index.js' implicitly has an 'any' type. -!!! error TS7016: Try `npm install @types/foo` if it exists or add a new declaration (.d.ts) file containing `declare module 'foo';` ==== /node_modules/foo/package.json (0 errors) ==== { "name": "foo", "version": "1.2.3" } diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.errors.txt b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.errors.txt index db93cf044c8..1881345fc2d 100644 --- a/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.errors.txt +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.errors.txt @@ -1,11 +1,11 @@ /a.ts(2,25): error TS7016: Could not find a declaration file for module 'foo/sub'. '/node_modules/foo/sub.js' implicitly has an 'any' type. If the 'foo' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/foo` /a.ts(3,25): error TS7016: Could not find a declaration file for module 'bar/sub'. '/node_modules/bar/sub.js' implicitly has an 'any' type. - Try `npm install @types/bar` if it exists or add a new declaration (.d.ts) file containing `declare module 'bar';` + Try `npm install @types/bar` if it exists or add a new declaration (.d.ts) file containing `declare module 'bar/sub';` /a.ts(5,30): error TS7016: Could not find a declaration file for module '@scope/foo/sub'. '/node_modules/@scope/foo/sub.js' implicitly has an 'any' type. If the '@scope/foo' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/scope__foo` /a.ts(6,30): error TS7016: Could not find a declaration file for module '@scope/bar/sub'. '/node_modules/@scope/bar/sub.js' implicitly has an 'any' type. - Try `npm install @types/scope__bar` if it exists or add a new declaration (.d.ts) file containing `declare module '@scope/bar';` + Try `npm install @types/scope__bar` if it exists or add a new declaration (.d.ts) file containing `declare module '@scope/bar/sub';` ==== /a.ts (4 errors) ==== @@ -17,7 +17,7 @@ import * as barSub from "bar/sub"; ~~~~~~~~~ !!! error TS7016: Could not find a declaration file for module 'bar/sub'. '/node_modules/bar/sub.js' implicitly has an 'any' type. -!!! error TS7016: Try `npm install @types/bar` if it exists or add a new declaration (.d.ts) file containing `declare module 'bar';` +!!! error TS7016: Try `npm install @types/bar` if it exists or add a new declaration (.d.ts) file containing `declare module 'bar/sub';` import * as scopeFoo from "@scope/foo"; import * as scopeFooSub from "@scope/foo/sub"; ~~~~~~~~~~~~~~~~ @@ -26,7 +26,7 @@ import * as scopeBarSub from "@scope/bar/sub"; ~~~~~~~~~~~~~~~~ !!! error TS7016: Could not find a declaration file for module '@scope/bar/sub'. '/node_modules/@scope/bar/sub.js' implicitly has an 'any' type. -!!! error TS7016: Try `npm install @types/scope__bar` if it exists or add a new declaration (.d.ts) file containing `declare module '@scope/bar';` +!!! error TS7016: Try `npm install @types/scope__bar` if it exists or add a new declaration (.d.ts) file containing `declare module '@scope/bar/sub';` ==== /node_modules/@types/foo/index.d.ts (0 errors) ==== export const foo: number; From 17ee9231b7cd3cf27ee2d9d923bb4482cb798665 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 17 Aug 2018 14:05:05 -0700 Subject: [PATCH 018/163] Write first test with --build and --watch --- src/compiler/program.ts | 50 +++++++------- src/harness/virtualFileSystemWithWatch.ts | 14 +++- src/testRunner/tsconfig.json | 1 + src/testRunner/unittests/tsbuildWatchMode.ts | 69 +++++++++++++++++++ src/testRunner/unittests/tscWatchMode.ts | 25 ++++--- .../unittests/tsserverProjectSystem.ts | 6 +- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 8 files changed, 123 insertions(+), 46 deletions(-) create mode 100644 src/testRunner/unittests/tsbuildWatchMode.ts diff --git a/src/compiler/program.ts b/src/compiler/program.ts index abbc935cf65..1c7430e3300 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -66,20 +66,20 @@ namespace ts { mtime: Date; } - export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost { + export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost { const existingDirectories = createMap(); function getCanonicalFileName(fileName: string): string { // if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form. // otherwise use toLowerCase as a canonical form. - return sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); + return system.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); } function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile | undefined { let text: string | undefined; try { performance.mark("beforeIORead"); - text = sys.readFile(fileName, options.charset); + text = system.readFile(fileName, options.charset); performance.mark("afterIORead"); performance.measure("I/O Read", "beforeIORead", "afterIORead"); } @@ -97,7 +97,7 @@ namespace ts { if (existingDirectories.has(directoryPath)) { return true; } - if (sys.directoryExists(directoryPath)) { + if (system.directoryExists(directoryPath)) { existingDirectories.set(directoryPath, true); return true; } @@ -108,7 +108,7 @@ namespace ts { if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) { const parentDirectory = getDirectoryPath(directoryPath); ensureDirectoriesExist(parentDirectory); - sys.createDirectory(directoryPath); + system.createDirectory(directoryPath); } } @@ -119,8 +119,8 @@ namespace ts { outputFingerprints = createMap(); } - const hash = sys.createHash!(data); // TODO: GH#18217 - const mtimeBefore = sys.getModifiedTime!(fileName); // TODO: GH#18217 + const hash = system.createHash!(data); // TODO: GH#18217 + const mtimeBefore = system.getModifiedTime!(fileName); // TODO: GH#18217 if (mtimeBefore) { const fingerprint = outputFingerprints.get(fileName); @@ -133,9 +133,9 @@ namespace ts { } } - sys.writeFile(fileName, data, writeByteOrderMark); + system.writeFile(fileName, data, writeByteOrderMark); - const mtimeAfter = sys.getModifiedTime!(fileName) || missingFileModifiedTime; // TODO: GH#18217 + const mtimeAfter = system.getModifiedTime!(fileName) || missingFileModifiedTime; // TODO: GH#18217 outputFingerprints.set(fileName, { hash, @@ -149,11 +149,11 @@ namespace ts { performance.mark("beforeIOWrite"); ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName))); - if (isWatchSet(options) && sys.createHash && sys.getModifiedTime) { + if (isWatchSet(options) && system.createHash && system.getModifiedTime) { writeFileIfUpdated(fileName, data, writeByteOrderMark); } else { - sys.writeFile(fileName, data, writeByteOrderMark); + system.writeFile(fileName, data, writeByteOrderMark); } performance.mark("afterIOWrite"); @@ -167,32 +167,32 @@ namespace ts { } function getDefaultLibLocation(): string { - return getDirectoryPath(normalizePath(sys.getExecutingFilePath())); + return getDirectoryPath(normalizePath(system.getExecutingFilePath())); } const newLine = getNewLineCharacter(options); - const realpath = sys.realpath && ((path: string) => sys.realpath!(path)); + const realpath = system.realpath && ((path: string) => system.realpath!(path)); return { getSourceFile, getDefaultLibLocation, getDefaultLibFileName: options => combinePaths(getDefaultLibLocation(), getDefaultLibFileName(options)), writeFile, - getCurrentDirectory: memoize(() => sys.getCurrentDirectory()), - useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames, + getCurrentDirectory: memoize(() => system.getCurrentDirectory()), + useCaseSensitiveFileNames: () => system.useCaseSensitiveFileNames, getCanonicalFileName, getNewLine: () => newLine, - fileExists: fileName => sys.fileExists(fileName), - readFile: fileName => sys.readFile(fileName), - trace: (s: string) => sys.write(s + newLine), - directoryExists: directoryName => sys.directoryExists(directoryName), - getEnvironmentVariable: name => sys.getEnvironmentVariable ? sys.getEnvironmentVariable(name) : "", - getDirectories: (path: string) => sys.getDirectories(path), + fileExists: fileName => system.fileExists(fileName), + readFile: fileName => system.readFile(fileName), + trace: (s: string) => system.write(s + newLine), + directoryExists: directoryName => system.directoryExists(directoryName), + getEnvironmentVariable: name => system.getEnvironmentVariable ? system.getEnvironmentVariable(name) : "", + getDirectories: (path: string) => system.getDirectories(path), realpath, - readDirectory: (path, extensions, include, exclude, depth) => sys.readDirectory(path, extensions, include, exclude, depth), - getModifiedTime: sys.getModifiedTime && (path => sys.getModifiedTime!(path)), - setModifiedTime: sys.setModifiedTime && ((path, date) => sys.setModifiedTime!(path, date)), - deleteFile: sys.deleteFile && (path => sys.deleteFile!(path)) + readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth), + getModifiedTime: system.getModifiedTime && (path => system.getModifiedTime!(path)), + setModifiedTime: system.setModifiedTime && ((path, date) => system.setModifiedTime!(path, date)), + deleteFile: system.deleteFile && (path => system.deleteFile!(path)) }; } diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 2a2ed4ef7dc..57fa33a84c2 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -620,14 +620,14 @@ interface Array {}` } } - removeFile(filePath: string) { + deleteFile(filePath: string) { const path = this.toFullPath(filePath); const currentEntry = this.fs.get(path) as FsFile; Debug.assert(isFsFile(currentEntry)); this.removeFileOrFolder(currentEntry, returnFalse); } - removeFolder(folderPath: string, recursive?: boolean) { + deleteFolder(folderPath: string, recursive?: boolean) { const path = this.toFullPath(folderPath); const currentEntry = this.fs.get(path) as FsFolder; Debug.assert(isFsFolder(currentEntry)); @@ -635,7 +635,7 @@ interface Array {}` const subEntries = currentEntry.entries.slice(); subEntries.forEach(fsEntry => { if (isFsFolder(fsEntry)) { - this.removeFolder(fsEntry.fullPath, recursive); + this.deleteFolder(fsEntry.fullPath, recursive); } else { this.removeFileOrFolder(fsEntry, returnFalse); @@ -766,6 +766,14 @@ interface Array {}` return (fsEntry && fsEntry.modifiedTime)!; // TODO: GH#18217 } + setModifiedTime(s: string, date: Date) { + const path = this.toFullPath(s); + const fsEntry = this.fs.get(path); + if (fsEntry) { + fsEntry.modifiedTime = date; + } + } + readFile(s: string): string | undefined { const fsEntry = this.getRealFile(this.toFullPath(s)); return fsEntry ? fsEntry.content : undefined; diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 12c671f9cf0..fa7900f1ca3 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -80,6 +80,7 @@ "unittests/transform.ts", "unittests/transpile.ts", "unittests/tsbuild.ts", + "unittests/tsbuildWatchMode.ts", "unittests/tsconfigParsing.ts", "unittests/tscWatchMode.ts", "unittests/versionCache.ts", diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts new file mode 100644 index 00000000000..9f608180d03 --- /dev/null +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -0,0 +1,69 @@ +namespace ts.tscWatch { + export import libFile = TestFSWithWatch.libFile; + function createSolutionBuilder(host: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { + const compilerHost = createCompilerHost({}, /*setParentNodes*/ undefined, host); + const reportDiag = createDiagnosticReporter(host); + const report = (message: DiagnosticMessage, ...args: string[]) => reportDiag(createCompilerDiagnostic(message, ...args)); + const buildHost: BuildHost = { + error: report, + verbose: report, + message: report, + errorDiagnostic: d => reportDiag(d) + }; + return ts.createSolutionBuilder(compilerHost, buildHost, rootNames, defaultOptions || { dry: false, force: false, verbose: false }, host); + } + + function createSolutionBuilderWithWatch(host: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { + const solutionBuilder = createSolutionBuilder(host, rootNames, defaultOptions); + solutionBuilder.buildAllProjects(); + solutionBuilder.startWatching(); + return solutionBuilder; + } + + describe("tsbuild-watch program updates", () => { + const projectsLocation = "/user/username/projects"; + const project = "sample1"; + const enum SubProject { + core = "core", + logic = "logic", + tests = "tests", + ui = "ui" + } + type ReadonlyFile = Readonly; + /** [tsconfig, index] | [tsconfig, index, anotherModule, someDecl] */ + type SubProjectFiles = [ReadonlyFile, ReadonlyFile] | [ReadonlyFile, ReadonlyFile, ReadonlyFile, ReadonlyFile]; + const root = Harness.IO.getWorkspaceRoot(); + function projectFile(subProject: SubProject, baseFileName: string): File { + return { + path: `${projectsLocation}/${project}/${subProject}/${baseFileName.toLowerCase()}`, + content: Harness.IO.readFile(`${root}/tests/projects/${project}/${subProject}/${baseFileName}`)! + }; + } + function subProjectFiles(subProject: SubProject, anotherModuleAndSomeDecl?: true): SubProjectFiles { + const tsconfig = projectFile(subProject, "tsconfig.json"); + const index = projectFile(subProject, "index.ts"); + if (!anotherModuleAndSomeDecl) { + return [tsconfig, index]; + } + const anotherModule = projectFile(SubProject.core, "anotherModule.ts"); + const someDecl = projectFile(SubProject.core, "some_decl.ts"); + return [tsconfig, index, anotherModule, someDecl]; + } + + const core = subProjectFiles(SubProject.core, /*anotherModuleAndSomeDecl*/ true); + const logic = subProjectFiles(SubProject.logic); + const tests = subProjectFiles(SubProject.tests); + const ui = subProjectFiles(SubProject.ui); + const allFiles: ReadonlyArray = [libFile, ...core, ...logic, ...tests, ...ui]; + const testProjectExpectedWatchedFiles = [core[0], core[1], core[2], ...logic, ...tests].map(f => f.path); + it("creates solution in watch mode", () => { + const host = createWatchedSystem(allFiles, { currentDirectory: projectsLocation }); + const originalWrite = host.write; + host.write = s => { console.log(s); originalWrite.call(host, s); }; + createSolutionBuilderWithWatch(host, [`${project}/${SubProject.tests}`]); + checkWatchedFiles(host, testProjectExpectedWatchedFiles); + checkWatchedDirectories(host, emptyArray, /*recursive*/ false); + checkWatchedDirectories(host, emptyArray, /*recursive*/ true); // TODO: #26524 + }); + }); +} diff --git a/src/testRunner/unittests/tscWatchMode.ts b/src/testRunner/unittests/tscWatchMode.ts index d91559c72fc..51c0d888f0b 100644 --- a/src/testRunner/unittests/tscWatchMode.ts +++ b/src/testRunner/unittests/tscWatchMode.ts @@ -1,17 +1,16 @@ namespace ts.tscWatch { - import WatchedSystem = TestFSWithWatch.TestServerHost; - type File = TestFSWithWatch.File; - type SymLink = TestFSWithWatch.SymLink; - import createWatchedSystem = TestFSWithWatch.createWatchedSystem; - import checkArray = TestFSWithWatch.checkArray; - import libFile = TestFSWithWatch.libFile; - import checkWatchedFiles = TestFSWithWatch.checkWatchedFiles; - import checkWatchedFilesDetailed = TestFSWithWatch.checkWatchedFilesDetailed; - import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories; - import checkWatchedDirectoriesDetailed = TestFSWithWatch.checkWatchedDirectoriesDetailed; - import checkOutputContains = TestFSWithWatch.checkOutputContains; - import checkOutputDoesNotContain = TestFSWithWatch.checkOutputDoesNotContain; - import Tsc_WatchDirectory = TestFSWithWatch.Tsc_WatchDirectory; + export import WatchedSystem = TestFSWithWatch.TestServerHost; + export type File = TestFSWithWatch.File; + export type SymLink = TestFSWithWatch.SymLink; + export import createWatchedSystem = TestFSWithWatch.createWatchedSystem; + export import checkArray = TestFSWithWatch.checkArray; + export import checkWatchedFiles = TestFSWithWatch.checkWatchedFiles; + export import checkWatchedFilesDetailed = TestFSWithWatch.checkWatchedFilesDetailed; + export import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories; + export import checkWatchedDirectoriesDetailed = TestFSWithWatch.checkWatchedDirectoriesDetailed; + export import checkOutputContains = TestFSWithWatch.checkOutputContains; + export import checkOutputDoesNotContain = TestFSWithWatch.checkOutputDoesNotContain; + export import Tsc_WatchDirectory = TestFSWithWatch.Tsc_WatchDirectory; export function checkProgramActualFiles(program: Program, expectedFiles: string[]) { checkArray(`Program actual files`, program.getSourceFiles().map(file => file.fileName), expectedFiles); diff --git a/src/testRunner/unittests/tsserverProjectSystem.ts b/src/testRunner/unittests/tsserverProjectSystem.ts index b99a2d9fe99..5491d83965d 100644 --- a/src/testRunner/unittests/tsserverProjectSystem.ts +++ b/src/testRunner/unittests/tsserverProjectSystem.ts @@ -8257,7 +8257,7 @@ new C();` verifyProjectWithResolvedModule(session); - host.removeFolder(recognizersTextDist, /*recursive*/ true); + host.deleteFolder(recognizersTextDist, /*recursive*/ true); host.runQueuedTimeoutCallbacks(); verifyProjectWithUnresolvedModule(session); @@ -9173,7 +9173,7 @@ describe("Test Suite 1", () => { checkProjectActualFiles(project, expectedFilesWithUnitTest1); const navBarResultUnitTest1 = navBarFull(session, unitTest1); - host.removeFile(unitTest1.path); + host.deleteFile(unitTest1.path); host.checkTimeoutQueueLengthAndRun(2); checkProjectActualFiles(project, expectedFilesWithoutUnitTest1); @@ -9297,7 +9297,7 @@ export function Test2() { checkDeclarationFiles(bTs, session, [bDtsMap, bDts]); // Testing what happens if we delete the original sources. - host.removeFile(bTs.path); + host.deleteFile(bTs.path); openFilesForSession([userTs], session); const service = session.getProjectService(); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5e992f3847a..e41db162ae2 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4125,7 +4125,7 @@ declare namespace ts { declare namespace ts { function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined; function resolveTripleslashReference(moduleName: string, containingFile: string): string; - function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; + function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean, system?: System): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; interface FormatDiagnosticsHost { getCurrentDirectory(): string; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 32761156558..fca9d26c306 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4125,7 +4125,7 @@ declare namespace ts { declare namespace ts { function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined; function resolveTripleslashReference(moduleName: string, containingFile: string): string; - function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; + function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean, system?: System): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; interface FormatDiagnosticsHost { getCurrentDirectory(): string; From d2240a40e19ecdb5b2547a2a6a58edb1852b0757 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 17 Aug 2018 15:24:37 -0700 Subject: [PATCH 019/163] Ger rid of unnecessary upto date host and functions pulled out --- src/compiler/tsbuild.ts | 373 +++++++++++++++++++--------------------- src/compiler/types.ts | 10 -- 2 files changed, 181 insertions(+), 202 deletions(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 966d795ed87..60f1d843e78 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -520,16 +520,6 @@ namespace ts { let context = createBuildContext(defaultOptions); const existingWatchersForWildcards = createMap(); - - const upToDateHost: UpToDateHost = { - fileExists: fileName => compilerHost.fileExists(fileName), - getModifiedTime: fileName => compilerHost.getModifiedTime!(fileName), - getUnchangedTime: fileName => context.unchangedOutputs.getValueOrUndefined(fileName), - getLastStatus: fileName => context.projectStatus.getValueOrUndefined(fileName), - setLastStatus: (fileName, status) => context.projectStatus.setValue(fileName, status), - parseConfigFile: configFilePath => configFileCache.parseConfigFile(configFilePath) - }; - return { buildAllProjects, getUpToDateStatus, @@ -611,7 +601,180 @@ namespace ts { } function getUpToDateStatus(project: ParsedCommandLine | undefined): UpToDateStatus { - return ts.getUpToDateStatus(upToDateHost, project); + if (project === undefined) { + return { type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" }; + } + + const prior = context.projectStatus.getValueOrUndefined(project.options.configFilePath!); + if (prior !== undefined) { + return prior; + } + + const actual = getUpToDateStatusWorker(project); + context.projectStatus.setValue(project.options.configFilePath!, actual); + return actual; + } + + function getUpToDateStatusWorker(project: ParsedCommandLine): UpToDateStatus { + let newestInputFileName: string = undefined!; + let newestInputFileTime = minimumDate; + // Get timestamps of input files + for (const inputFile of project.fileNames) { + if (!compilerHost.fileExists(inputFile)) { + return { + type: UpToDateStatusType.Unbuildable, + reason: `${inputFile} does not exist` + }; + } + + const inputTime = compilerHost.getModifiedTime!(inputFile) || missingFileModifiedTime; + if (inputTime > newestInputFileTime) { + newestInputFileName = inputFile; + newestInputFileTime = inputTime; + } + } + + // Collect the expected outputs of this project + const outputs = getAllProjectOutputs(project); + + if (outputs.length === 0) { + return { + type: UpToDateStatusType.ContainerOnly + }; + } + + // Now see if all outputs are newer than the newest input + let oldestOutputFileName = "(none)"; + let oldestOutputFileTime = maximumDate; + let newestOutputFileName = "(none)"; + let newestOutputFileTime = minimumDate; + let missingOutputFileName: string | undefined; + let newestDeclarationFileContentChangedTime = minimumDate; + let isOutOfDateWithInputs = false; + for (const output of outputs) { + // Output is missing; can stop checking + // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status + if (!compilerHost.fileExists(output)) { + missingOutputFileName = output; + break; + } + + const outputTime = compilerHost.getModifiedTime!(output) || missingFileModifiedTime; + if (outputTime < oldestOutputFileTime) { + oldestOutputFileTime = outputTime; + oldestOutputFileName = output; + } + + // If an output is older than the newest input, we can stop checking + // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status + if (outputTime < newestInputFileTime) { + isOutOfDateWithInputs = true; + break; + } + + if (outputTime > newestOutputFileTime) { + newestOutputFileTime = outputTime; + newestOutputFileName = output; + } + + // Keep track of when the most recent time a .d.ts file was changed. + // In addition to file timestamps, we also keep track of when a .d.ts file + // had its file touched but not had its contents changed - this allows us + // to skip a downstream typecheck + if (isDeclarationFile(output)) { + const unchangedTime = context.unchangedOutputs.getValueOrUndefined(output); + if (unchangedTime !== undefined) { + newestDeclarationFileContentChangedTime = newer(unchangedTime, newestDeclarationFileContentChangedTime); + } + else { + const outputModifiedTime = compilerHost.getModifiedTime!(output) || missingFileModifiedTime; + newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime); + } + } + } + + let pseudoUpToDate = false; + let usesPrepend = false; + let upstreamChangedProject: string | undefined; + if (project.projectReferences) { + for (const ref of project.projectReferences) { + usesPrepend = usesPrepend || !!(ref.prepend); + const resolvedRef = resolveProjectReferencePath(compilerHost, ref); + const refStatus = getUpToDateStatus(configFileCache.parseConfigFile(resolvedRef)); + + // An upstream project is blocked + if (refStatus.type === UpToDateStatusType.Unbuildable) { + return { + type: UpToDateStatusType.UpstreamBlocked, + upstreamProjectName: ref.path + }; + } + + // If the upstream project is out of date, then so are we (someone shouldn't have asked, though?) + if (refStatus.type !== UpToDateStatusType.UpToDate) { + return { + type: UpToDateStatusType.UpstreamOutOfDate, + upstreamProjectName: ref.path + }; + } + + // If the upstream project's newest file is older than our oldest output, we + // can't be out of date because of it + if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) { + continue; + } + + // If the upstream project has only change .d.ts files, and we've built + // *after* those files, then we're "psuedo up to date" and eligible for a fast rebuild + if (refStatus.newestDeclarationFileContentChangedTime && refStatus.newestDeclarationFileContentChangedTime <= oldestOutputFileTime) { + pseudoUpToDate = true; + upstreamChangedProject = ref.path; + continue; + } + + // We have an output older than an upstream output - we are out of date + Debug.assert(oldestOutputFileName !== undefined, "Should have an oldest output filename here"); + return { + type: UpToDateStatusType.OutOfDateWithUpstream, + outOfDateOutputFileName: oldestOutputFileName, + newerProjectName: ref.path + }; + } + } + + if (missingOutputFileName !== undefined) { + return { + type: UpToDateStatusType.OutputMissing, + missingOutputFileName + }; + } + + if (isOutOfDateWithInputs) { + return { + type: UpToDateStatusType.OutOfDateWithSelf, + outOfDateOutputFileName: oldestOutputFileName, + newerInputFileName: newestInputFileName + }; + } + + if (usesPrepend && pseudoUpToDate) { + return { + type: UpToDateStatusType.OutOfDateWithUpstream, + outOfDateOutputFileName: oldestOutputFileName, + newerProjectName: upstreamChangedProject! + }; + } + + // Up to date + return { + type: pseudoUpToDate ? UpToDateStatusType.UpToDateWithUpstreamTypes : UpToDateStatusType.UpToDate, + newestDeclarationFileContentChangedTime, + newestInputFileTime, + newestOutputFileTime, + newestInputFileName, + newestOutputFileName, + oldestOutputFileName + }; } function invalidateProject(configFileName: string) { @@ -1030,187 +1193,13 @@ namespace ts { } } - /** - * Gets the UpToDateStatus for a project - */ - export function getUpToDateStatus(host: UpToDateHost, project: ParsedCommandLine | undefined): UpToDateStatus { - if (project === undefined) { - return { type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" }; - } - - const prior = host.getLastStatus ? host.getLastStatus(project.options.configFilePath!) : undefined; - if (prior !== undefined) { - return prior; - } - - const actual = getUpToDateStatusWorker(host, project); - if (host.setLastStatus) { - host.setLastStatus(project.options.configFilePath!, actual); - } - - return actual; - } - - function getUpToDateStatusWorker(host: UpToDateHost, project: ParsedCommandLine): UpToDateStatus { - let newestInputFileName: string = undefined!; - let newestInputFileTime = minimumDate; - // Get timestamps of input files - for (const inputFile of project.fileNames) { - if (!host.fileExists(inputFile)) { - return { - type: UpToDateStatusType.Unbuildable, - reason: `${inputFile} does not exist` - }; - } - - const inputTime = host.getModifiedTime(inputFile) || missingFileModifiedTime; - if (inputTime > newestInputFileTime) { - newestInputFileName = inputFile; - newestInputFileTime = inputTime; - } - } - - // Collect the expected outputs of this project - const outputs = getAllProjectOutputs(project); - - if (outputs.length === 0) { - return { - type: UpToDateStatusType.ContainerOnly - }; - } - - // Now see if all outputs are newer than the newest input - let oldestOutputFileName = "(none)"; - let oldestOutputFileTime = maximumDate; - let newestOutputFileName = "(none)"; - let newestOutputFileTime = minimumDate; - let missingOutputFileName: string | undefined; - let newestDeclarationFileContentChangedTime = minimumDate; - let isOutOfDateWithInputs = false; - for (const output of outputs) { - // Output is missing; can stop checking - // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status - if (!host.fileExists(output)) { - missingOutputFileName = output; - break; - } - - const outputTime = host.getModifiedTime(output) || missingFileModifiedTime; - if (outputTime < oldestOutputFileTime) { - oldestOutputFileTime = outputTime; - oldestOutputFileName = output; - } - - // If an output is older than the newest input, we can stop checking - // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status - if (outputTime < newestInputFileTime) { - isOutOfDateWithInputs = true; - break; - } - - if (outputTime > newestOutputFileTime) { - newestOutputFileTime = outputTime; - newestOutputFileName = output; - } - - // Keep track of when the most recent time a .d.ts file was changed. - // In addition to file timestamps, we also keep track of when a .d.ts file - // had its file touched but not had its contents changed - this allows us - // to skip a downstream typecheck - if (isDeclarationFile(output)) { - const unchangedTime = host.getUnchangedTime ? host.getUnchangedTime(output) : undefined; - if (unchangedTime !== undefined) { - newestDeclarationFileContentChangedTime = newer(unchangedTime, newestDeclarationFileContentChangedTime); - } - else { - const outputModifiedTime = host.getModifiedTime(output) || missingFileModifiedTime; - newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime); - } - } - } - - let pseudoUpToDate = false; - let usesPrepend = false; - let upstreamChangedProject: string | undefined; - if (project.projectReferences && host.parseConfigFile) { - for (const ref of project.projectReferences) { - usesPrepend = usesPrepend || !!(ref.prepend); - const resolvedRef = resolveProjectReferencePath(host, ref); - const refStatus = getUpToDateStatus(host, host.parseConfigFile(resolvedRef)); - - // An upstream project is blocked - if (refStatus.type === UpToDateStatusType.Unbuildable) { - return { - type: UpToDateStatusType.UpstreamBlocked, - upstreamProjectName: ref.path - }; - } - - // If the upstream project is out of date, then so are we (someone shouldn't have asked, though?) - if (refStatus.type !== UpToDateStatusType.UpToDate) { - return { - type: UpToDateStatusType.UpstreamOutOfDate, - upstreamProjectName: ref.path - }; - } - - // If the upstream project's newest file is older than our oldest output, we - // can't be out of date because of it - if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) { - continue; - } - - // If the upstream project has only change .d.ts files, and we've built - // *after* those files, then we're "psuedo up to date" and eligible for a fast rebuild - if (refStatus.newestDeclarationFileContentChangedTime && refStatus.newestDeclarationFileContentChangedTime <= oldestOutputFileTime) { - pseudoUpToDate = true; - upstreamChangedProject = ref.path; - continue; - } - - // We have an output older than an upstream output - we are out of date - Debug.assert(oldestOutputFileName !== undefined, "Should have an oldest output filename here"); - return { - type: UpToDateStatusType.OutOfDateWithUpstream, - outOfDateOutputFileName: oldestOutputFileName, - newerProjectName: ref.path - }; - } - } - - if (missingOutputFileName !== undefined) { - return { - type: UpToDateStatusType.OutputMissing, - missingOutputFileName - }; - } - - if (isOutOfDateWithInputs) { - return { - type: UpToDateStatusType.OutOfDateWithSelf, - outOfDateOutputFileName: oldestOutputFileName, - newerInputFileName: newestInputFileName - }; - } - - if (usesPrepend && pseudoUpToDate) { - return { - type: UpToDateStatusType.OutOfDateWithUpstream, - outOfDateOutputFileName: oldestOutputFileName, - newerProjectName: upstreamChangedProject! - }; - } - - // Up to date - return { - type: pseudoUpToDate ? UpToDateStatusType.UpToDateWithUpstreamTypes : UpToDateStatusType.UpToDate, - newestDeclarationFileContentChangedTime, - newestInputFileTime, - newestOutputFileTime, - newestInputFileName, - newestOutputFileName, - oldestOutputFileName - }; + export interface UpToDateHost { + fileExists(fileName: string): boolean; + getModifiedTime(fileName: string): Date | undefined; + getUnchangedTime?(fileName: string): Date | undefined; + getLastStatus?(fileName: string): UpToDateStatus | undefined; + setLastStatus?(fileName: string, status: UpToDateStatus): void; + parseConfigFile?(configFilePath: ResolvedConfigFileName): ParsedCommandLine | undefined; } export function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4330a776d04..96129411db6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4715,16 +4715,6 @@ namespace ts { verticalTab = 0x0B, // \v } - /*@internal*/ - export interface UpToDateHost { - fileExists(fileName: string): boolean; - getModifiedTime(fileName: string): Date | undefined; - getUnchangedTime?(fileName: string): Date | undefined; - getLastStatus?(fileName: string): UpToDateStatus | undefined; - setLastStatus?(fileName: string, status: UpToDateStatus): void; - parseConfigFile?(configFilePath: ResolvedConfigFileName): ParsedCommandLine | undefined; - } - export interface ModuleResolutionHost { // TODO: GH#18217 Optional methods frequently used as non-optional From 8e49fec80fda70e64a719d99fda3388161686f11 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 17 Aug 2018 16:42:59 -0700 Subject: [PATCH 020/163] Move perform build to tsc instead of tsbuild --- src/compiler/tsbuild.ts | 122 ---------------------------------------- src/tsc/tsc.ts | 122 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 122 deletions(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 60f1d843e78..87dcb0e2b57 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -385,128 +385,6 @@ namespace ts { }; } - const buildOpts: CommandLineOption[] = [ - { - name: "verbose", - shortName: "v", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Enable_verbose_logging, - type: "boolean" - }, - { - name: "dry", - shortName: "d", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, - type: "boolean" - }, - { - name: "force", - shortName: "f", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, - type: "boolean" - }, - { - name: "clean", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Delete_the_outputs_of_all_projects, - type: "boolean" - }, - { - name: "watch", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Watch_input_files, - type: "boolean" - } - ]; - - export function performBuild(args: string[], compilerHost: CompilerHost, buildHost: BuildHost, system?: System): number | undefined { - let verbose = false; - let dry = false; - let force = false; - let clean = false; - let watch = false; - - const projects: string[] = []; - for (const arg of args) { - switch (arg.toLowerCase()) { - case "-v": - case "--verbose": - verbose = true; - continue; - case "-d": - case "--dry": - dry = true; - continue; - case "-f": - case "--force": - force = true; - continue; - case "--clean": - clean = true; - continue; - case "--watch": - case "-w": - watch = true; - continue; - - case "--?": - case "-?": - case "--help": - printHelp(buildOpts, "--build "); - return ExitStatus.Success; - } - // Not a flag, parse as filename - addProject(arg); - } - - // Nonsensical combinations - if (clean && force) { - buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"); - return ExitStatus.DiagnosticsPresent_OutputsSkipped; - } - if (clean && verbose) { - buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"); - return ExitStatus.DiagnosticsPresent_OutputsSkipped; - } - if (clean && watch) { - buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"); - return ExitStatus.DiagnosticsPresent_OutputsSkipped; - } - if (watch && dry) { - buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"); - return ExitStatus.DiagnosticsPresent_OutputsSkipped; - } - - if (projects.length === 0) { - // tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ." - addProject("."); - } - - const builder = createSolutionBuilder(compilerHost, buildHost, projects, { dry, force, verbose }, system); - if (clean) { - return builder.cleanAllProjects(); - } - - if (watch) { - builder.buildAllProjects(); - builder.startWatching(); - return undefined; - } - - return builder.buildAllProjects(); - - function addProject(projectSpecification: string) { - const fileName = resolvePath(compilerHost.getCurrentDirectory(), projectSpecification); - const refPath = resolveProjectReferencePath(compilerHost, { path: fileName }); - if (!compilerHost.fileExists(refPath)) { - return buildHost.error(Diagnostics.File_0_does_not_exist, fileName); - } - projects.push(refPath); - } - } - /** * A SolutionBuilder has an immutable set of rootNames that are the "entry point" projects, but * can dynamically add/remove other projects based on changes on the rootNames' references diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index 97e239c8bca..f6f0db6e9aa 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -172,6 +172,128 @@ namespace ts { } } + const buildOpts: CommandLineOption[] = [ + { + name: "verbose", + shortName: "v", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Enable_verbose_logging, + type: "boolean" + }, + { + name: "dry", + shortName: "d", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, + type: "boolean" + }, + { + name: "force", + shortName: "f", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, + type: "boolean" + }, + { + name: "clean", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Delete_the_outputs_of_all_projects, + type: "boolean" + }, + { + name: "watch", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Watch_input_files, + type: "boolean" + } + ]; + + function performBuild(args: string[], compilerHost: CompilerHost, buildHost: BuildHost, system?: System): number | undefined { + let verbose = false; + let dry = false; + let force = false; + let clean = false; + let watch = false; + + const projects: string[] = []; + for (const arg of args) { + switch (arg.toLowerCase()) { + case "-v": + case "--verbose": + verbose = true; + continue; + case "-d": + case "--dry": + dry = true; + continue; + case "-f": + case "--force": + force = true; + continue; + case "--clean": + clean = true; + continue; + case "--watch": + case "-w": + watch = true; + continue; + + case "--?": + case "-?": + case "--help": + printHelp(buildOpts, "--build "); + return ExitStatus.Success; + } + // Not a flag, parse as filename + addProject(arg); + } + + // Nonsensical combinations + if (clean && force) { + buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"); + return ExitStatus.DiagnosticsPresent_OutputsSkipped; + } + if (clean && verbose) { + buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"); + return ExitStatus.DiagnosticsPresent_OutputsSkipped; + } + if (clean && watch) { + buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"); + return ExitStatus.DiagnosticsPresent_OutputsSkipped; + } + if (watch && dry) { + buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"); + return ExitStatus.DiagnosticsPresent_OutputsSkipped; + } + + if (projects.length === 0) { + // tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ." + addProject("."); + } + + const builder = createSolutionBuilder(compilerHost, buildHost, projects, { dry, force, verbose }, system); + if (clean) { + return builder.cleanAllProjects(); + } + + if (watch) { + builder.buildAllProjects(); + builder.startWatching(); + return undefined; + } + + return builder.buildAllProjects(); + + function addProject(projectSpecification: string) { + const fileName = resolvePath(compilerHost.getCurrentDirectory(), projectSpecification); + const refPath = resolveProjectReferencePath(compilerHost, { path: fileName }); + if (!compilerHost.fileExists(refPath)) { + return buildHost.error(Diagnostics.File_0_does_not_exist, fileName); + } + projects.push(refPath); + } + } + function performCompilation(rootNames: string[], projectReferences: ReadonlyArray | undefined, options: CompilerOptions, configFileParsingDiagnostics?: ReadonlyArray) { const host = createCompilerHost(options); enableStatistics(options); From 071d790dec9a679d089fd7b196b900b8e678fc33 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 17 Aug 2018 17:22:08 -0700 Subject: [PATCH 021/163] Unify tsbuild option parsing with command line options parsing --- src/compiler/commandLineParser.ts | 17 +-- src/compiler/diagnosticMessages.json | 5 + src/compiler/tsbuild.ts | 11 +- src/tsc/tsc.ts | 154 +++++++++++++-------------- 4 files changed, 99 insertions(+), 88 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 00920325721..f1dd4093956 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -815,10 +815,11 @@ namespace ts { } function getOptionNameMap(): OptionNameMap { - if (optionNameMapCache) { - return optionNameMapCache; - } + return optionNameMapCache || (optionNameMapCache = createOptionNameMap(optionDeclarations)); + } + /*@internal*/ + export function createOptionNameMap(optionDeclarations: ReadonlyArray): OptionNameMap { const optionNameMap = createMap(); const shortOptionNames = createMap(); forEach(optionDeclarations, option => { @@ -828,8 +829,7 @@ namespace ts { } }); - optionNameMapCache = { optionNameMap, shortOptionNames }; - return optionNameMapCache; + return { optionNameMap, shortOptionNames }; } /* @internal */ @@ -979,7 +979,12 @@ namespace ts { } /** @internal */ - export function getOptionFromName(optionName: string, allowShort = false): CommandLineOption | undefined { + export function getOptionFromName(optionName: string, allowShort?: boolean): CommandLineOption | undefined { + return getOptionDeclarationFromName(getOptionNameMap, optionName, allowShort); + } + + /*@internal*/ + export function getOptionDeclarationFromName(getOptionNameMap: () => OptionNameMap, optionName: string, allowShort = false): CommandLineOption | undefined { optionName = optionName.toLowerCase(); const { optionNameMap, shortOptionNames } = getOptionNameMap(); // Try to translate short option names to their full equivalents. diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6000c48de4d..6c517709f4f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2900,6 +2900,11 @@ "category": "Error", "code": 5071 }, + "Unknown build option '{0}'.": { + "category": "Error", + "code": 5072 + }, + "Generates a sourcemap for each corresponding '.d.ts' file.": { "category": "Message", diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 87dcb0e2b57..54737d470e7 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -47,10 +47,13 @@ namespace ts { dependencyMap: Mapper; } - interface BuildOptions { - dry: boolean; - force: boolean; - verbose: boolean; + export interface BuildOptions { + dry?: boolean; + force?: boolean; + verbose?: boolean; + /*@internal*/ clean?: boolean; + /*@internal*/ watch?: boolean; + /*@internal*/ help?: boolean; } enum BuildResultFlags { diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index f6f0db6e9aa..a863c684931 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -62,7 +62,7 @@ namespace ts { message: report, errorDiagnostic: d => reportDiag(d) }; - const result = performBuild(args.slice(1), createCompilerHost({}), buildHost, sys); + const result = performBuild(args.slice(1), createCompilerHost({}), buildHost); // undefined = in watch mode, do not exit if (result !== undefined) { return sys.exit(result); @@ -172,96 +172,94 @@ namespace ts { } } - const buildOpts: CommandLineOption[] = [ - { - name: "verbose", - shortName: "v", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Enable_verbose_logging, - type: "boolean" - }, - { - name: "dry", - shortName: "d", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, - type: "boolean" - }, - { - name: "force", - shortName: "f", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, - type: "boolean" - }, - { - name: "clean", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Delete_the_outputs_of_all_projects, - type: "boolean" - }, - { - name: "watch", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Watch_input_files, - type: "boolean" - } - ]; - - function performBuild(args: string[], compilerHost: CompilerHost, buildHost: BuildHost, system?: System): number | undefined { - let verbose = false; - let dry = false; - let force = false; - let clean = false; - let watch = false; + function performBuild(args: string[], compilerHost: CompilerHost, buildHost: BuildHost): number | undefined { + const buildOpts: CommandLineOption[] = [ + { + name: "help", + shortName: "h", + type: "boolean", + showInSimplifiedHelpView: true, + category: Diagnostics.Command_line_Options, + description: Diagnostics.Print_this_message, + }, + { + name: "help", + shortName: "?", + type: "boolean" + }, + { + name: "verbose", + shortName: "v", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Enable_verbose_logging, + type: "boolean" + }, + { + name: "dry", + shortName: "d", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, + type: "boolean" + }, + { + name: "force", + shortName: "f", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, + type: "boolean" + }, + { + name: "clean", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Delete_the_outputs_of_all_projects, + type: "boolean" + }, + { + name: "watch", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Watch_input_files, + type: "boolean" + } + ]; + let buildOptionNameMap: OptionNameMap | undefined; + const returnBuildOptionNameMap = () => (buildOptionNameMap || (buildOptionNameMap = createOptionNameMap(buildOpts))); + const buildOptions: BuildOptions = {}; const projects: string[] = []; for (const arg of args) { - switch (arg.toLowerCase()) { - case "-v": - case "--verbose": - verbose = true; - continue; - case "-d": - case "--dry": - dry = true; - continue; - case "-f": - case "--force": - force = true; - continue; - case "--clean": - clean = true; - continue; - case "--watch": - case "-w": - watch = true; - continue; - - case "--?": - case "-?": - case "--help": - printHelp(buildOpts, "--build "); - return ExitStatus.Success; + if (arg.charCodeAt(0) === CharacterCodes.minus) { + const opt = getOptionDeclarationFromName(returnBuildOptionNameMap, arg.slice(arg.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true); + if (opt) { + buildOptions[opt.name as keyof BuildOptions] = true; + } + else { + reportDiagnostic(createCompilerDiagnostic(Diagnostics.Unknown_build_option_0, arg)); + } } - // Not a flag, parse as filename - addProject(arg); + else { + // Not a flag, parse as filename + addProject(arg); + } + } + + if (buildOptions.help) { + printHelp(buildOpts, "--build "); return ExitStatus.Success; } // Nonsensical combinations - if (clean && force) { + if (buildOptions.clean && buildOptions.force) { buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } - if (clean && verbose) { + if (buildOptions.clean && buildOptions.verbose) { buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } - if (clean && watch) { + if (buildOptions.clean && buildOptions.watch) { buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } - if (watch && dry) { + if (buildOptions.watch && buildOptions.dry) { buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } @@ -271,12 +269,12 @@ namespace ts { addProject("."); } - const builder = createSolutionBuilder(compilerHost, buildHost, projects, { dry, force, verbose }, system); - if (clean) { + const builder = createSolutionBuilder(compilerHost, buildHost, projects, buildOptions); + if (buildOptions.clean) { return builder.cleanAllProjects(); } - if (watch) { + if (buildOptions.watch) { builder.buildAllProjects(); builder.startWatching(); return undefined; From e20a7d851fe2e0843cc3648cf31daa2d28153a9f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 17 Aug 2018 17:27:19 -0700 Subject: [PATCH 022/163] Remove unnecessary usage of system and compilerHost --- src/tsc/tsc.ts | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index a863c684931..ff16a92f0fe 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -54,15 +54,7 @@ namespace ts { export function executeCommandLine(args: string[]): void { if (args.length > 0 && ((args[0].toLowerCase() === "--build") || (args[0].toLowerCase() === "-b"))) { - const reportDiag = createDiagnosticReporter(sys, defaultIsPretty()); - const report = (message: DiagnosticMessage, ...args: string[]) => reportDiag(createCompilerDiagnostic(message, ...args)); - const buildHost: BuildHost = { - error: report, - verbose: report, - message: report, - errorDiagnostic: d => reportDiag(d) - }; - const result = performBuild(args.slice(1), createCompilerHost({}), buildHost); + const result = performBuild(args.slice(1)); // undefined = in watch mode, do not exit if (result !== undefined) { return sys.exit(result); @@ -172,7 +164,7 @@ namespace ts { } } - function performBuild(args: string[], compilerHost: CompilerHost, buildHost: BuildHost): number | undefined { + function performBuild(args: string[]): number | undefined { const buildOpts: CommandLineOption[] = [ { name: "help", @@ -243,24 +235,28 @@ namespace ts { } if (buildOptions.help) { - printHelp(buildOpts, "--build "); return ExitStatus.Success; + printHelp(buildOpts, "--build "); + return ExitStatus.Success; } + // Update to pretty if host supports it + updateReportDiagnostic({}); + // Nonsensical combinations if (buildOptions.clean && buildOptions.force) { - buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"); + reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force")); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } if (buildOptions.clean && buildOptions.verbose) { - buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"); + reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose")); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } if (buildOptions.clean && buildOptions.watch) { - buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"); + reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch")); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } if (buildOptions.watch && buildOptions.dry) { - buildHost.error(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"); + reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry")); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } @@ -269,7 +265,15 @@ namespace ts { addProject("."); } - const builder = createSolutionBuilder(compilerHost, buildHost, projects, buildOptions); + const report = (message: DiagnosticMessage, ...args: string[]) => reportDiagnostic(createCompilerDiagnostic(message, ...args)); + const buildHost: BuildHost = { + error: report, + verbose: report, + message: report, + errorDiagnostic: d => reportDiagnostic(d) + }; + + const builder = createSolutionBuilder(createCompilerHost({}), buildHost, projects, buildOptions); if (buildOptions.clean) { return builder.cleanAllProjects(); } @@ -283,9 +287,9 @@ namespace ts { return builder.buildAllProjects(); function addProject(projectSpecification: string) { - const fileName = resolvePath(compilerHost.getCurrentDirectory(), projectSpecification); - const refPath = resolveProjectReferencePath(compilerHost, { path: fileName }); - if (!compilerHost.fileExists(refPath)) { + const fileName = resolvePath(sys.getCurrentDirectory(), projectSpecification); + const refPath = resolveProjectReferencePath(sys, { path: fileName }); + if (!sys.fileExists(refPath)) { return buildHost.error(Diagnostics.File_0_does_not_exist, fileName); } projects.push(refPath); From dade3365d6c2f121d18dda25d68b83a67723ae92 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 20 Aug 2018 11:13:24 -0700 Subject: [PATCH 023/163] Print version along with help when doing --build --- src/tsc/tsc.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index ff16a92f0fe..a2413d132bb 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -235,6 +235,7 @@ namespace ts { } if (buildOptions.help) { + printVersion(); printHelp(buildOpts, "--build "); return ExitStatus.Success; } From 0c4003e7351aa4d6f8e9285fc30905715485050d Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 20 Aug 2018 11:47:39 -0700 Subject: [PATCH 024/163] Use SolutionBuilderHost instead of using compilerhost for solution builder --- src/compiler/program.ts | 5 +- src/compiler/tsbuild.ts | 73 +++++++++---------- src/compiler/types.ts | 4 - src/harness/fakes.ts | 2 +- src/testRunner/unittests/tsbuildWatchMode.ts | 8 +- src/tsc/tsc.ts | 7 +- .../reference/api/tsserverlibrary.d.ts | 3 - tests/baselines/reference/api/typescript.d.ts | 3 - 8 files changed, 47 insertions(+), 58 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 1c7430e3300..6ca29707cb9 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -189,10 +189,7 @@ namespace ts { getEnvironmentVariable: name => system.getEnvironmentVariable ? system.getEnvironmentVariable(name) : "", getDirectories: (path: string) => system.getDirectories(path), realpath, - readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth), - getModifiedTime: system.getModifiedTime && (path => system.getModifiedTime!(path)), - setModifiedTime: system.setModifiedTime && ((path, date) => system.setModifiedTime!(path, date)), - deleteFile: system.deleteFile && (path => system.deleteFile!(path)) + readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth) }; } diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 54737d470e7..f0a81fe8b47 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -388,16 +388,27 @@ namespace ts { }; } + export interface SolutionBuilderHost extends CompilerHost { + getModifiedTime(fileName: string): Date | undefined; + setModifiedTime(fileName: string, date: Date): void; + deleteFile(fileName: string): void; + } + + export function createSolutionBuilderHost(system = sys) { + const host = createCompilerHost({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHost; + host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined; + host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime!(path, date) : noop; + host.deleteFile = system.deleteFile ? path => system.deleteFile!(path) : noop; + return host; + } + /** * A SolutionBuilder has an immutable set of rootNames that are the "entry point" projects, but * can dynamically add/remove other projects based on changes on the rootNames' references */ - export function createSolutionBuilder(compilerHost: CompilerHost, buildHost: BuildHost, rootNames: ReadonlyArray, defaultOptions: BuildOptions, system?: System) { - if (!compilerHost.getModifiedTime || !compilerHost.setModifiedTime) { - throw new Error("Host must support timestamp APIs"); - } + export function createSolutionBuilder(host: SolutionBuilderHost, buildHost: BuildHost, rootNames: ReadonlyArray, defaultOptions: BuildOptions, system?: System) { - const configFileCache = createConfigFileCache(compilerHost); + const configFileCache = createConfigFileCache(host); let context = createBuildContext(defaultOptions); const existingWatchersForWildcards = createMap(); @@ -501,14 +512,14 @@ namespace ts { let newestInputFileTime = minimumDate; // Get timestamps of input files for (const inputFile of project.fileNames) { - if (!compilerHost.fileExists(inputFile)) { + if (!host.fileExists(inputFile)) { return { type: UpToDateStatusType.Unbuildable, reason: `${inputFile} does not exist` }; } - const inputTime = compilerHost.getModifiedTime!(inputFile) || missingFileModifiedTime; + const inputTime = host.getModifiedTime(inputFile) || missingFileModifiedTime; if (inputTime > newestInputFileTime) { newestInputFileName = inputFile; newestInputFileTime = inputTime; @@ -535,12 +546,12 @@ namespace ts { for (const output of outputs) { // Output is missing; can stop checking // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status - if (!compilerHost.fileExists(output)) { + if (!host.fileExists(output)) { missingOutputFileName = output; break; } - const outputTime = compilerHost.getModifiedTime!(output) || missingFileModifiedTime; + const outputTime = host.getModifiedTime(output) || missingFileModifiedTime; if (outputTime < oldestOutputFileTime) { oldestOutputFileTime = outputTime; oldestOutputFileName = output; @@ -568,7 +579,7 @@ namespace ts { newestDeclarationFileContentChangedTime = newer(unchangedTime, newestDeclarationFileContentChangedTime); } else { - const outputModifiedTime = compilerHost.getModifiedTime!(output) || missingFileModifiedTime; + const outputModifiedTime = host.getModifiedTime(output) || missingFileModifiedTime; newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime); } } @@ -580,7 +591,7 @@ namespace ts { if (project.projectReferences) { for (const ref of project.projectReferences) { usesPrepend = usesPrepend || !!(ref.prepend); - const resolvedRef = resolveProjectReferencePath(compilerHost, ref); + const resolvedRef = resolveProjectReferencePath(host, ref); const refStatus = getUpToDateStatus(configFileCache.parseConfigFile(resolvedRef)); // An upstream project is blocked @@ -809,7 +820,7 @@ namespace ts { const programOptions: CreateProgramOptions = { projectReferences: configFile.projectReferences, - host: compilerHost, + host, rootNames: configFile.fileNames, options: configFile.options }; @@ -858,18 +869,18 @@ namespace ts { program.emit(/*targetSourceFile*/ undefined, (fileName, content, writeBom, onError) => { let priorChangeTime: Date | undefined; - if (!anyDtsChanged && isDeclarationFile(fileName) && compilerHost.fileExists(fileName)) { - if (compilerHost.readFile(fileName) === content) { + if (!anyDtsChanged && isDeclarationFile(fileName) && host.fileExists(fileName)) { + if (host.readFile(fileName) === content) { // Check for unchanged .d.ts files resultFlags &= ~BuildResultFlags.DeclarationOutputUnchanged; - priorChangeTime = compilerHost.getModifiedTime && compilerHost.getModifiedTime(fileName); + priorChangeTime = host.getModifiedTime(fileName); } else { anyDtsChanged = true; } } - compilerHost.writeFile(fileName, content, writeBom, onError, emptyArray); + host.writeFile(fileName, content, writeBom, onError, emptyArray); if (priorChangeTime !== undefined) { newestDeclarationFileContentChangedTime = newer(priorChangeTime, newestDeclarationFileContentChangedTime); context.unchangedOutputs.setValue(fileName, priorChangeTime); @@ -898,10 +909,10 @@ namespace ts { let priorNewestUpdateTime = minimumDate; for (const file of outputs) { if (isDeclarationFile(file)) { - priorNewestUpdateTime = newer(priorNewestUpdateTime, compilerHost.getModifiedTime!(file) || missingFileModifiedTime); + priorNewestUpdateTime = newer(priorNewestUpdateTime, host.getModifiedTime(file) || missingFileModifiedTime); } - compilerHost.setModifiedTime!(file, now); + host.setModifiedTime(file, now); } context.projectStatus.setValue(proj.options.configFilePath!, { type: UpToDateStatusType.UpToDate, newestDeclarationFileContentChangedTime: priorNewestUpdateTime } as UpToDateStatus); @@ -924,7 +935,7 @@ namespace ts { } const outputs = getAllProjectOutputs(parsed); for (const output of outputs) { - if (compilerHost.fileExists(output)) { + if (host.fileExists(output)) { filesToDelete.push(output); } } @@ -958,25 +969,20 @@ namespace ts { return ExitStatus.Success; } - // Do this check later to allow --clean --dry to function even if the host can't delete files - if (!compilerHost.deleteFile) { - throw new Error("Host does not support deleting files"); - } - for (const output of filesToDelete) { - compilerHost.deleteFile(output); + host.deleteFile(output); } return ExitStatus.Success; } function resolveProjectName(name: string): ResolvedConfigFileName | undefined { - const fullPath = resolvePath(compilerHost.getCurrentDirectory(), name); - if (compilerHost.fileExists(fullPath)) { + const fullPath = resolvePath(host.getCurrentDirectory(), name); + if (host.fileExists(fullPath)) { return fullPath as ResolvedConfigFileName; } const fullPathWithTsconfig = combinePaths(fullPath, "tsconfig.json"); - if (compilerHost.fileExists(fullPathWithTsconfig)) { + if (host.fileExists(fullPathWithTsconfig)) { return fullPathWithTsconfig as ResolvedConfigFileName; } buildHost.error(Diagnostics.File_0_not_found, relName(fullPath)); @@ -1058,7 +1064,7 @@ namespace ts { } function relName(path: string): string { - return convertToRelativePath(path, compilerHost.getCurrentDirectory(), f => compilerHost.getCanonicalFileName(f)); + return convertToRelativePath(path, host.getCurrentDirectory(), f => host.getCanonicalFileName(f)); } function reportVerbose(message: DiagnosticMessage, ...args: string[]) { @@ -1074,15 +1080,6 @@ namespace ts { } } - export interface UpToDateHost { - fileExists(fileName: string): boolean; - getModifiedTime(fileName: string): Date | undefined; - getUnchangedTime?(fileName: string): Date | undefined; - getLastStatus?(fileName: string): UpToDateStatus | undefined; - setLastStatus?(fileName: string, status: UpToDateStatus): void; - parseConfigFile?(configFilePath: ResolvedConfigFileName): ParsedCommandLine | undefined; - } - export function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray { if (project.options.outFile) { return getOutFileOutputs(project); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 96129411db6..2733348e561 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4845,10 +4845,6 @@ namespace ts { /* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution; /* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean; createHash?(data: string): string; - - getModifiedTime?(fileName: string): Date | undefined; - setModifiedTime?(fileName: string, date: Date): void; - deleteFile?(fileName: string): void; } /* @internal */ diff --git a/src/harness/fakes.ts b/src/harness/fakes.ts index 1bb358698a2..b4dd97878be 100644 --- a/src/harness/fakes.ts +++ b/src/harness/fakes.ts @@ -205,7 +205,7 @@ namespace fakes { /** * A fake `ts.CompilerHost` that leverages a virtual file system. */ - export class CompilerHost implements ts.CompilerHost { + export class CompilerHost implements ts.CompilerHost, ts.SolutionBuilderHost { public readonly sys: System; public readonly defaultLibLocation: string; public readonly outputs: documents.TextDocument[] = []; diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts index 9f608180d03..dd6a95f0f12 100644 --- a/src/testRunner/unittests/tsbuildWatchMode.ts +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -1,8 +1,8 @@ namespace ts.tscWatch { export import libFile = TestFSWithWatch.libFile; - function createSolutionBuilder(host: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { - const compilerHost = createCompilerHost({}, /*setParentNodes*/ undefined, host); - const reportDiag = createDiagnosticReporter(host); + function createSolutionBuilder(system: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { + const host = createSolutionBuilderHost(system); + const reportDiag = createDiagnosticReporter(system); const report = (message: DiagnosticMessage, ...args: string[]) => reportDiag(createCompilerDiagnostic(message, ...args)); const buildHost: BuildHost = { error: report, @@ -10,7 +10,7 @@ namespace ts.tscWatch { message: report, errorDiagnostic: d => reportDiag(d) }; - return ts.createSolutionBuilder(compilerHost, buildHost, rootNames, defaultOptions || { dry: false, force: false, verbose: false }, host); + return ts.createSolutionBuilder(host, buildHost, rootNames, defaultOptions || { dry: false, force: false, verbose: false }, system); } function createSolutionBuilderWithWatch(host: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index a2413d132bb..d53aa1f56ff 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -243,6 +243,11 @@ namespace ts { // Update to pretty if host supports it updateReportDiagnostic({}); + if (!sys.getModifiedTime || !sys.setModifiedTime || (buildOptions.clean && !sys.deleteFile)) { + reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--build")); + return ExitStatus.DiagnosticsPresent_OutputsSkipped; + } + // Nonsensical combinations if (buildOptions.clean && buildOptions.force) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force")); @@ -274,7 +279,7 @@ namespace ts { errorDiagnostic: d => reportDiagnostic(d) }; - const builder = createSolutionBuilder(createCompilerHost({}), buildHost, projects, buildOptions); + const builder = createSolutionBuilder(createSolutionBuilderHost(), buildHost, projects, buildOptions); if (buildOptions.clean) { return builder.cleanAllProjects(); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e41db162ae2..5c50a7cf457 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2690,9 +2690,6 @@ declare namespace ts { resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; getEnvironmentVariable?(name: string): string | undefined; createHash?(data: string): string; - getModifiedTime?(fileName: string): Date | undefined; - setModifiedTime?(fileName: string, date: Date): void; - deleteFile?(fileName: string): void; } interface SourceMapRange extends TextRange { source?: SourceMapSource; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index fca9d26c306..29e485415fb 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2690,9 +2690,6 @@ declare namespace ts { resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; getEnvironmentVariable?(name: string): string | undefined; createHash?(data: string): string; - getModifiedTime?(fileName: string): Date | undefined; - setModifiedTime?(fileName: string, date: Date): void; - deleteFile?(fileName: string): void; } interface SourceMapRange extends TextRange { source?: SourceMapSource; From 26b4b6c9ad87e616c38aeb7e6c1121daadc63f9c Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 20 Aug 2018 12:52:09 -0700 Subject: [PATCH 025/163] Create api with watchHost to include in solution builder host --- src/compiler/tsbuild.ts | 36 +++++++++---- src/compiler/watch.ts | 52 ++++++++++++------- src/testRunner/unittests/tsbuildWatchMode.ts | 4 +- src/tsc/tsc.ts | 6 ++- .../reference/api/tsserverlibrary.d.ts | 25 +++++---- tests/baselines/reference/api/typescript.d.ts | 25 +++++---- 6 files changed, 94 insertions(+), 54 deletions(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index f0a81fe8b47..e6bc8d252dd 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -394,6 +394,9 @@ namespace ts { deleteFile(fileName: string): void; } + export interface SolutionBuilderWithWatchHost extends SolutionBuilderHost, WatchHost { + } + export function createSolutionBuilderHost(system = sys) { const host = createCompilerHost({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHost; host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined; @@ -402,12 +405,25 @@ namespace ts { return host; } + export function createSolutionBuilderWithWatchHost(system = sys, reportWatchStatus?: WatchStatusReporter) { + const host = createSolutionBuilderHost(system) as SolutionBuilderWithWatchHost; + const watchHost = createWatchHost(system, reportWatchStatus); + host.onWatchStatusChange = watchHost.onWatchStatusChange; + host.watchFile = watchHost.watchFile; + host.watchDirectory = watchHost.watchDirectory; + host.setTimeout = watchHost.setTimeout; + host.clearTimeout = watchHost.clearTimeout; + return host; + } + /** * A SolutionBuilder has an immutable set of rootNames that are the "entry point" projects, but * can dynamically add/remove other projects based on changes on the rootNames' references + * TODO: use SolutionBuilderWithWatchHost => watchedSolution + * use SolutionBuilderHost => Solution */ - export function createSolutionBuilder(host: SolutionBuilderHost, buildHost: BuildHost, rootNames: ReadonlyArray, defaultOptions: BuildOptions, system?: System) { - + export function createSolutionBuilder(host: SolutionBuilderHost, buildHost: BuildHost, rootNames: ReadonlyArray, defaultOptions: BuildOptions) { + const hostWithWatch = host as SolutionBuilderWithWatchHost; const configFileCache = createConfigFileCache(host); let context = createBuildContext(defaultOptions); @@ -430,9 +446,6 @@ namespace ts { }; function startWatching() { - if (!system) throw new Error("System host must be provided if using --watch"); - if (!system.watchFile || !system.watchDirectory || !system.setTimeout) throw new Error("System host must support watchFile / watchDirectory / setTimeout if using --watch"); - const graph = getGlobalDependencyGraph()!; if (!graph.buildQueue) { // Everything is broken - we don't even know what to watch. Give up. @@ -443,7 +456,7 @@ namespace ts { const cfg = configFileCache.parseConfigFile(resolved); if (cfg) { // Watch this file - system.watchFile(resolved, () => { + hostWithWatch.watchFile(resolved, () => { configFileCache.removeKey(resolved); invalidateProjectAndScheduleBuilds(resolved); }); @@ -451,7 +464,7 @@ namespace ts { // Update watchers for wildcard directories if (cfg.configFileSpecs) { updateWatchingWildcardDirectories(existingWatchersForWildcards, createMapFromTemplate(cfg.configFileSpecs.wildcardDirectories), (dir, flags) => { - return system.watchDirectory!(dir, () => { + return hostWithWatch.watchDirectory(dir, () => { invalidateProjectAndScheduleBuilds(resolved); }, !!(flags & WatchDirectoryFlags.Recursive)); }); @@ -459,7 +472,7 @@ namespace ts { // Watch input files for (const input of cfg.fileNames) { - system.watchFile(input, () => { + hostWithWatch.watchFile(input, () => { invalidateProjectAndScheduleBuilds(resolved); }); } @@ -468,8 +481,11 @@ namespace ts { function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName) { invalidateProject(resolved); - system!.setTimeout!(buildInvalidatedProjects, 100); - system!.setTimeout!(buildDependentInvalidatedProjects, 3000); + if (!hostWithWatch.setTimeout) { + return; + } + hostWithWatch.setTimeout(buildInvalidatedProjects, 100); + hostWithWatch.setTimeout(buildDependentInvalidatedProjects, 3000); } } diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 9c759158f63..63904ffa43e 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -174,6 +174,17 @@ namespace ts { const noopFileWatcher: FileWatcher = { close: noop }; + export function createWatchHost(system = sys, reportWatchStatus?: WatchStatusReporter): WatchHost { + const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system); + return { + onWatchStatusChange, + watchFile: system.watchFile ? ((path, callback, pollingInterval) => system.watchFile!(path, callback, pollingInterval)) : () => noopFileWatcher, + watchDirectory: system.watchDirectory ? ((path, callback, recursive) => system.watchDirectory!(path, callback, recursive)) : () => noopFileWatcher, + setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout!.call(system, callback, ms, ...args)) : noop, + clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout!(timeoutId)) : noop + }; + } + /** * Creates the watch compiler host that can be extended with config file or root file names and options host */ @@ -186,7 +197,7 @@ namespace ts { host; // tslint:disable-line no-unused-expression (TODO: `host` is unused!) const useCaseSensitiveFileNames = () => system.useCaseSensitiveFileNames; const writeFileName = (s: string) => system.write(s + system.newLine); - const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system); + const { onWatchStatusChange, watchFile, watchDirectory, setTimeout, clearTimeout } = createWatchHost(system, reportWatchStatus); return { useCaseSensitiveFileNames, getNewLine: () => system.newLine, @@ -200,10 +211,10 @@ namespace ts { readDirectory: (path, extensions, exclude, include, depth) => system.readDirectory(path, extensions, exclude, include, depth), realpath: system.realpath && (path => system.realpath!(path)), getEnvironmentVariable: system.getEnvironmentVariable && (name => system.getEnvironmentVariable(name)), - watchFile: system.watchFile ? ((path, callback, pollingInterval) => system.watchFile!(path, callback, pollingInterval)) : () => noopFileWatcher, - watchDirectory: system.watchDirectory ? ((path, callback, recursive) => system.watchDirectory!(path, callback, recursive)) : () => noopFileWatcher, - setTimeout: system.setTimeout ? ((callback, ms, ...args: any[]) => system.setTimeout!.call(system, callback, ms, ...args)) : noop, - clearTimeout: system.clearTimeout ? (timeoutId => system.clearTimeout!(timeoutId)) : noop, + watchFile, + watchDirectory, + setTimeout, + clearTimeout, trace: s => system.write(s), onWatchStatusChange, createDirectory: path => system.createDirectory(path), @@ -224,10 +235,10 @@ namespace ts { const reportSummary = (errorCount: number) => { if (errorCount === 1) { - onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes, errorCount), newLine, compilerOptions); + onWatchStatusChange!(createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes, errorCount), newLine, compilerOptions); } else { - onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errorCount, errorCount), newLine, compilerOptions); + onWatchStatusChange!(createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errorCount, errorCount), newLine, compilerOptions); } }; @@ -270,7 +281,21 @@ namespace ts { export type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; /** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */ export type CreateProgram = (rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray) => T; - export interface WatchCompilerHost { + /** Host that has watch functionality used in --watch mode */ + export interface WatchHost { + /** If provided, called with Diagnostic message that informs about change in watch status */ + onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void; + + /** Used to watch changes in source files, missing files needed to update the program or config file */ + watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher; + /** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */ + watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; + /** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */ + setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; + /** If provided, will be used to reset existing delayed compilation */ + clearTimeout?(timeoutId: any): void; + } + export interface WatchCompilerHost extends WatchHost { // TODO: GH#18217 Optional methods are frequently asserted /** @@ -279,8 +304,6 @@ namespace ts { createProgram: CreateProgram; /** If provided, callback to invoke after every new program creation */ afterProgramCreate?(program: T): void; - /** If provided, called with Diagnostic message that informs about change in watch status */ - onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void; // Only for testing /*@internal*/ @@ -323,15 +346,6 @@ namespace ts { resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; /** If provided, used to resolve type reference directives, otherwise typescript's default resolution */ resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; - - /** Used to watch changes in source files, missing files needed to update the program or config file */ - watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher; - /** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */ - watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; - /** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */ - setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; - /** If provided, will be used to reset existing delayed compilation */ - clearTimeout?(timeoutId: any): void; } /** Internal interface used to wire emit through same host */ diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts index dd6a95f0f12..87224c09338 100644 --- a/src/testRunner/unittests/tsbuildWatchMode.ts +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -1,7 +1,7 @@ namespace ts.tscWatch { export import libFile = TestFSWithWatch.libFile; function createSolutionBuilder(system: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { - const host = createSolutionBuilderHost(system); + const host = createSolutionBuilderWithWatchHost(system); const reportDiag = createDiagnosticReporter(system); const report = (message: DiagnosticMessage, ...args: string[]) => reportDiag(createCompilerDiagnostic(message, ...args)); const buildHost: BuildHost = { @@ -10,7 +10,7 @@ namespace ts.tscWatch { message: report, errorDiagnostic: d => reportDiag(d) }; - return ts.createSolutionBuilder(host, buildHost, rootNames, defaultOptions || { dry: false, force: false, verbose: false }, system); + return ts.createSolutionBuilder(host, buildHost, rootNames, defaultOptions || { dry: false, force: false, verbose: false, watch: true }); } function createSolutionBuilderWithWatch(host: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index d53aa1f56ff..5c7af1a4b99 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -247,6 +247,9 @@ namespace ts { reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--build")); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } + if (buildOptions.watch) { + reportWatchModeWithoutSysSupport(); + } // Nonsensical combinations if (buildOptions.clean && buildOptions.force) { @@ -279,7 +282,8 @@ namespace ts { errorDiagnostic: d => reportDiagnostic(d) }; - const builder = createSolutionBuilder(createSolutionBuilderHost(), buildHost, projects, buildOptions); + // TODO: change this to host if watch => watchHost otherwiue without wathc + const builder = createSolutionBuilder(createSolutionBuilderWithWatchHost(), buildHost, projects, buildOptions); if (buildOptions.clean) { return builder.cleanAllProjects(); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5c50a7cf457..dd5f3c7c658 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4309,15 +4309,26 @@ declare namespace ts { type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; /** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */ type CreateProgram = (rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray) => T; - interface WatchCompilerHost { + /** Host that has watch functionality used in --watch mode */ + interface WatchHost { + /** If provided, called with Diagnostic message that informs about change in watch status */ + onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void; + /** Used to watch changes in source files, missing files needed to update the program or config file */ + watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher; + /** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */ + watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; + /** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */ + setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; + /** If provided, will be used to reset existing delayed compilation */ + clearTimeout?(timeoutId: any): void; + } + interface WatchCompilerHost extends WatchHost { /** * Used to create the program when need for program creation or recreation detected */ createProgram: CreateProgram; /** If provided, callback to invoke after every new program creation */ afterProgramCreate?(program: T): void; - /** If provided, called with Diagnostic message that informs about change in watch status */ - onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void; useCaseSensitiveFileNames(): boolean; getNewLine(): string; getCurrentDirectory(): string; @@ -4350,14 +4361,6 @@ declare namespace ts { resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; /** If provided, used to resolve type reference directives, otherwise typescript's default resolution */ resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; - /** Used to watch changes in source files, missing files needed to update the program or config file */ - watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher; - /** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */ - watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; - /** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */ - setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; - /** If provided, will be used to reset existing delayed compilation */ - clearTimeout?(timeoutId: any): void; } /** * Host to create watch with root files and options diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 29e485415fb..2938fc9bcc8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4309,15 +4309,26 @@ declare namespace ts { type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; /** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */ type CreateProgram = (rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray) => T; - interface WatchCompilerHost { + /** Host that has watch functionality used in --watch mode */ + interface WatchHost { + /** If provided, called with Diagnostic message that informs about change in watch status */ + onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void; + /** Used to watch changes in source files, missing files needed to update the program or config file */ + watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher; + /** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */ + watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; + /** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */ + setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; + /** If provided, will be used to reset existing delayed compilation */ + clearTimeout?(timeoutId: any): void; + } + interface WatchCompilerHost extends WatchHost { /** * Used to create the program when need for program creation or recreation detected */ createProgram: CreateProgram; /** If provided, callback to invoke after every new program creation */ afterProgramCreate?(program: T): void; - /** If provided, called with Diagnostic message that informs about change in watch status */ - onWatchStatusChange?(diagnostic: Diagnostic, newLine: string, options: CompilerOptions): void; useCaseSensitiveFileNames(): boolean; getNewLine(): string; getCurrentDirectory(): string; @@ -4350,14 +4361,6 @@ declare namespace ts { resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[]; /** If provided, used to resolve type reference directives, otherwise typescript's default resolution */ resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; - /** Used to watch changes in source files, missing files needed to update the program or config file */ - watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher; - /** Used to watch resolved module's failed lookup locations, config file specs, type roots where auto type reference directives are added */ - watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; - /** If provided, will be used to set delayed compilation, so that multiple changes in short span are compiled together */ - setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; - /** If provided, will be used to reset existing delayed compilation */ - clearTimeout?(timeoutId: any): void; } /** * Host to create watch with root files and options From dedb2aefc0b0b2b17b03b671ee89f28ab3403417 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 20 Aug 2018 13:33:54 -0700 Subject: [PATCH 026/163] Combine buildHost methods into SolutionBuilderHost's reportDiagnostic and reportStatus --- src/compiler/tsbuild.ts | 66 +++++---- src/harness/fakes.ts | 38 +++++- src/testRunner/unittests/tsbuild.ts | 134 +++++++------------ src/testRunner/unittests/tsbuildWatchMode.ts | 10 +- src/tsc/tsc.ts | 22 +-- 5 files changed, 132 insertions(+), 138 deletions(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index e6bc8d252dd..7efecab608a 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -392,21 +392,37 @@ namespace ts { getModifiedTime(fileName: string): Date | undefined; setModifiedTime(fileName: string, date: Date): void; deleteFile(fileName: string): void; + + reportDiagnostic: DiagnosticReporter; // Technically we want to move it out and allow steps of actions on Solution, but for now just merge stuff in build host here + reportSolutionBuilderStatus: DiagnosticReporter; } export interface SolutionBuilderWithWatchHost extends SolutionBuilderHost, WatchHost { } - export function createSolutionBuilderHost(system = sys) { + /** + * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic + */ + export function createBuilderStatusReporter(system: System, pretty?: boolean): DiagnosticReporter { + return diagnostic => { + let output = pretty ? `[${formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey)}] ` : `${new Date().toLocaleTimeString()} - `; + output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${system.newLine + system.newLine}`; + system.write(output); + }; + } + + export function createSolutionBuilderHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) { const host = createCompilerHost({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHost; host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined; host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime!(path, date) : noop; host.deleteFile = system.deleteFile ? path => system.deleteFile!(path) : noop; + host.reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system); + host.reportSolutionBuilderStatus = reportSolutionBuilderStatus || createBuilderStatusReporter(system); return host; } - export function createSolutionBuilderWithWatchHost(system = sys, reportWatchStatus?: WatchStatusReporter) { - const host = createSolutionBuilderHost(system) as SolutionBuilderWithWatchHost; + export function createSolutionBuilderWithWatchHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter) { + const host = createSolutionBuilderHost(system, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderWithWatchHost; const watchHost = createWatchHost(system, reportWatchStatus); host.onWatchStatusChange = watchHost.onWatchStatusChange; host.watchFile = watchHost.watchFile; @@ -422,7 +438,7 @@ namespace ts { * TODO: use SolutionBuilderWithWatchHost => watchedSolution * use SolutionBuilderHost => Solution */ - export function createSolutionBuilder(host: SolutionBuilderHost, buildHost: BuildHost, rootNames: ReadonlyArray, defaultOptions: BuildOptions) { + export function createSolutionBuilder(host: SolutionBuilderHost, rootNames: ReadonlyArray, defaultOptions: BuildOptions) { const hostWithWatch = host as SolutionBuilderWithWatchHost; const configFileCache = createConfigFileCache(host); let context = createBuildContext(defaultOptions); @@ -445,6 +461,10 @@ namespace ts { startWatching }; + function reportStatus(message: DiagnosticMessage, ...args: string[]) { + host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args)); + } + function startWatching() { const graph = getGlobalDependencyGraph()!; if (!graph.buildQueue) { @@ -743,7 +763,7 @@ namespace ts { verboseReportProjectStatus(next, status); if (status.type === UpToDateStatusType.UpstreamBlocked) { - if (context.options.verbose) buildHost.verbose(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, resolved, status.upstreamProjectName); + if (context.options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, resolved, status.upstreamProjectName); continue; } @@ -780,7 +800,7 @@ namespace ts { if (temporaryMarks[projPath]) { if (!inCircularContext) { hadError = true; - buildHost.error(Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0, circularityReportStack.join("\r\n")); + reportStatus(Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0, circularityReportStack.join("\r\n")); return; } } @@ -812,11 +832,11 @@ namespace ts { function buildSingleProject(proj: ResolvedConfigFileName): BuildResultFlags { if (context.options.dry) { - buildHost.message(Diagnostics.A_non_dry_build_would_build_project_0, proj); + reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj); return BuildResultFlags.Success; } - if (context.options.verbose) buildHost.verbose(Diagnostics.Building_project_0, proj); + if (context.options.verbose) reportStatus(Diagnostics.Building_project_0, proj); let resultFlags = BuildResultFlags.None; resultFlags |= BuildResultFlags.DeclarationOutputUnchanged; @@ -850,7 +870,7 @@ namespace ts { if (syntaxDiagnostics.length) { resultFlags |= BuildResultFlags.SyntaxErrors; for (const diag of syntaxDiagnostics) { - buildHost.errorDiagnostic(diag); + host.reportDiagnostic(diag); } context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Syntactic errors" }); return resultFlags; @@ -862,7 +882,7 @@ namespace ts { if (declDiagnostics.length) { resultFlags |= BuildResultFlags.DeclarationEmitErrors; for (const diag of declDiagnostics) { - buildHost.errorDiagnostic(diag); + host.reportDiagnostic(diag); } context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Declaration file errors" }); return resultFlags; @@ -874,7 +894,7 @@ namespace ts { if (semanticDiagnostics.length) { resultFlags |= BuildResultFlags.TypeErrors; for (const diag of semanticDiagnostics) { - buildHost.errorDiagnostic(diag); + host.reportDiagnostic(diag); } context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Semantic errors" }); return resultFlags; @@ -913,11 +933,11 @@ namespace ts { function updateOutputTimestamps(proj: ParsedCommandLine) { if (context.options.dry) { - return buildHost.message(Diagnostics.A_non_dry_build_would_build_project_0, proj.options.configFilePath!); + return reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj.options.configFilePath!); } if (context.options.verbose) { - buildHost.verbose(Diagnostics.Updating_output_timestamps_of_project_0, proj.options.configFilePath!); + reportStatus(Diagnostics.Updating_output_timestamps_of_project_0, proj.options.configFilePath!); } const now = new Date(); @@ -970,18 +990,18 @@ namespace ts { function cleanAllProjects() { const resolvedNames: ReadonlyArray | undefined = getAllProjectsInScope(); if (resolvedNames === undefined) { - buildHost.message(Diagnostics.Skipping_clean_because_not_all_projects_could_be_located); + reportStatus(Diagnostics.Skipping_clean_because_not_all_projects_could_be_located); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } const filesToDelete = getFilesToClean(resolvedNames); if (filesToDelete === undefined) { - buildHost.message(Diagnostics.Skipping_clean_because_not_all_projects_could_be_located); + reportStatus(Diagnostics.Skipping_clean_because_not_all_projects_could_be_located); return ExitStatus.DiagnosticsPresent_OutputsSkipped; } if (context.options.dry) { - buildHost.message(Diagnostics.A_non_dry_build_would_delete_the_following_files_Colon_0, filesToDelete.map(f => `\r\n * ${f}`).join("")); + reportStatus(Diagnostics.A_non_dry_build_would_delete_the_following_files_Colon_0, filesToDelete.map(f => `\r\n * ${f}`).join("")); return ExitStatus.Success; } @@ -1001,7 +1021,7 @@ namespace ts { if (host.fileExists(fullPathWithTsconfig)) { return fullPathWithTsconfig as ResolvedConfigFileName; } - buildHost.error(Diagnostics.File_0_not_found, relName(fullPath)); + host.reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_not_found, relName(fullPath))); return undefined; } @@ -1039,7 +1059,7 @@ namespace ts { // Up to date, skip if (defaultOptions.dry) { // In a dry build, inform the user of this fact - buildHost.message(Diagnostics.Project_0_is_up_to_date, projName); + reportStatus(Diagnostics.Project_0_is_up_to_date, projName); } continue; } @@ -1051,7 +1071,7 @@ namespace ts { } if (status.type === UpToDateStatusType.UpstreamBlocked) { - if (context.options.verbose) buildHost.verbose(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName); + if (context.options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName); continue; } @@ -1076,23 +1096,19 @@ namespace ts { for (const name of graph.buildQueue) { names.push(name); } - if (context.options.verbose) buildHost.verbose(Diagnostics.Projects_in_this_build_Colon_0, names.map(s => "\r\n * " + relName(s)).join("")); + if (context.options.verbose) reportStatus(Diagnostics.Projects_in_this_build_Colon_0, names.map(s => "\r\n * " + relName(s)).join("")); } function relName(path: string): string { return convertToRelativePath(path, host.getCurrentDirectory(), f => host.getCanonicalFileName(f)); } - function reportVerbose(message: DiagnosticMessage, ...args: string[]) { - buildHost.verbose(message, ...args); - } - /** * Report the up-to-date status of a project if we're in verbose mode */ function verboseReportProjectStatus(configFileName: string, status: UpToDateStatus) { if (!context.options.verbose) return; - return formatUpToDateStatus(configFileName, status, relName, reportVerbose); + return formatUpToDateStatus(configFileName, status, relName, reportStatus); } } diff --git a/src/harness/fakes.ts b/src/harness/fakes.ts index b4dd97878be..bd9d62f90e5 100644 --- a/src/harness/fakes.ts +++ b/src/harness/fakes.ts @@ -205,7 +205,7 @@ namespace fakes { /** * A fake `ts.CompilerHost` that leverages a virtual file system. */ - export class CompilerHost implements ts.CompilerHost, ts.SolutionBuilderHost { + export class CompilerHost implements ts.CompilerHost { public readonly sys: System; public readonly defaultLibLocation: string; public readonly outputs: documents.TextDocument[] = []; @@ -374,5 +374,41 @@ namespace fakes { return parsed; } } + + export class SolutionBuilderHost extends CompilerHost implements ts.SolutionBuilderHost { + diagnostics: ts.Diagnostic[] = []; + + reportDiagnostic(diagnostic: ts.Diagnostic) { + this.diagnostics.push(diagnostic); + } + + reportSolutionBuilderStatus(diagnostic: ts.Diagnostic) { + this.diagnostics.push(diagnostic); + } + + clearDiagnostics() { + this.diagnostics.length = 0; + } + + assertDiagnosticMessages(...expected: ts.DiagnosticMessage[]) { + const actual = this.diagnostics.slice(); + if (actual.length !== expected.length) { + assert.fail(actual, expected, `Diagnostic arrays did not match - got\r\n${actual.map(a => " " + a.messageText).join("\r\n")}\r\nexpected\r\n${expected.map(e => " " + e.message).join("\r\n")}`); + } + for (let i = 0; i < actual.length; i++) { + if (actual[i].code !== expected[i].code) { + assert.fail(actual[i].messageText, expected[i].message, `Mismatched error code - expected diagnostic ${i} "${actual[i].messageText}" to match ${expected[i].message}`); + } + } + } + + printDiagnostics(header = "== Diagnostics ==") { + const out = ts.createDiagnosticReporter(ts.sys); + ts.sys.write(header + "\r\n"); + for (const d of this.diagnostics) { + out(d); + } + } + } } diff --git a/src/testRunner/unittests/tsbuild.ts b/src/testRunner/unittests/tsbuild.ts index b65220588c5..f8813ecd1ae 100644 --- a/src/testRunner/unittests/tsbuild.ts +++ b/src/testRunner/unittests/tsbuild.ts @@ -1,15 +1,5 @@ namespace ts { let currentTime = 100; - let lastDiagnostics: Diagnostic[] = []; - const reportDiagnostic: DiagnosticReporter = diagnostic => lastDiagnostics.push(diagnostic); - const report = (message: DiagnosticMessage, ...args: string[]) => reportDiagnostic(createCompilerDiagnostic(message, ...args)); - const buildHost: BuildHost = { - error: report, - verbose: report, - message: report, - errorDiagnostic: d => reportDiagnostic(d) - }; - export namespace Sample1 { tick(); const projFs = loadProjectFromDisk("tests/projects/sample1"); @@ -21,12 +11,12 @@ namespace ts { describe("tsbuild - sanity check of clean build of 'sample1' project", () => { it("can build the sample project 'sample1' without error", () => { const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: false, force: false, verbose: false }); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false }); - clearDiagnostics(); + host.clearDiagnostics(); builder.buildAllProjects(); - assertDiagnosticMessages(/*empty*/); + host.assertDiagnosticMessages(/*empty*/); // Check for outputs. Not an exhaustive list for (const output of allExpectedOutputs) { @@ -37,12 +27,11 @@ namespace ts { describe("tsbuild - dry builds", () => { it("doesn't write any files in a dry build", () => { - clearDiagnostics(); const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: true, force: false, verbose: false }); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false }); builder.buildAllProjects(); - assertDiagnosticMessages(Diagnostics.A_non_dry_build_would_build_project_0, Diagnostics.A_non_dry_build_would_build_project_0, Diagnostics.A_non_dry_build_would_build_project_0); + host.assertDiagnosticMessages(Diagnostics.A_non_dry_build_would_build_project_0, Diagnostics.A_non_dry_build_would_build_project_0, Diagnostics.A_non_dry_build_would_build_project_0); // Check for outputs to not be written. Not an exhaustive list for (const output of allExpectedOutputs) { @@ -51,28 +40,26 @@ namespace ts { }); it("indicates that it would skip builds during a dry build", () => { - clearDiagnostics(); const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); + const host = new fakes.SolutionBuilderHost(fs); - let builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: false, force: false, verbose: false }); + let builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false }); builder.buildAllProjects(); tick(); - clearDiagnostics(); - builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: true, force: false, verbose: false }); + host.clearDiagnostics(); + builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false }); builder.buildAllProjects(); - assertDiagnosticMessages(Diagnostics.Project_0_is_up_to_date, Diagnostics.Project_0_is_up_to_date, Diagnostics.Project_0_is_up_to_date); + host.assertDiagnosticMessages(Diagnostics.Project_0_is_up_to_date, Diagnostics.Project_0_is_up_to_date, Diagnostics.Project_0_is_up_to_date); }); }); describe("tsbuild - clean builds", () => { it("removes all files it built", () => { - clearDiagnostics(); const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); + const host = new fakes.SolutionBuilderHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: false, force: false, verbose: false }); + const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false }); builder.buildAllProjects(); // Verify they exist for (const output of allExpectedOutputs) { @@ -91,9 +78,9 @@ namespace ts { describe("tsbuild - force builds", () => { it("always builds under --force", () => { const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); + const host = new fakes.SolutionBuilderHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: false, force: true, verbose: false }); + const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: true, verbose: false }); builder.buildAllProjects(); let currentTime = time(); checkOutputTimestamps(currentTime); @@ -116,14 +103,14 @@ namespace ts { describe("tsbuild - can detect when and what to rebuild", () => { const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: false, force: false, verbose: true }); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: true }); it("Builds the project", () => { - clearDiagnostics(); + host.clearDiagnostics(); builder.resetBuildContext(); builder.buildAllProjects(); - assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0, + host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0, Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, Diagnostics.Building_project_0, Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, @@ -135,10 +122,10 @@ namespace ts { // All three projects are up to date it("Detects that all projects are up to date", () => { - clearDiagnostics(); + host.clearDiagnostics(); builder.resetBuildContext(); builder.buildAllProjects(); - assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0, + host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0, Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2); @@ -147,12 +134,12 @@ namespace ts { // Update a file in the leaf node (tests), only it should rebuild the last one it("Only builds the leaf node project", () => { - clearDiagnostics(); + host.clearDiagnostics(); fs.writeFileSync("/src/tests/index.ts", "const m = 10;"); builder.resetBuildContext(); builder.buildAllProjects(); - assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0, + host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0, Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, @@ -162,12 +149,12 @@ namespace ts { // Update a file in the parent (without affecting types), should get fast downstream builds it("Detects type-only changes in upstream projects", () => { - clearDiagnostics(); + host.clearDiagnostics(); replaceText(fs, "/src/core/index.ts", "HELLO WORLD", "WELCOME PLANET"); builder.resetBuildContext(); builder.buildAllProjects(); - assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0, + host.assertDiagnosticMessages(Diagnostics.Projects_in_this_build_Colon_0, Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, Diagnostics.Building_project_0, Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, @@ -180,15 +167,13 @@ namespace ts { describe("tsbuild - downstream-blocked compilations", () => { it("won't build downstream projects if upstream projects have errors", () => { const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: false, force: false, verbose: true }); - - clearDiagnostics(); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: true }); // Induce an error in the middle project replaceText(fs, "/src/logic/index.ts", "c.multiply(10, 15)", `c.muitply()`); builder.buildAllProjects(); - assertDiagnosticMessages( + host.assertDiagnosticMessages( Diagnostics.Projects_in_this_build_Colon_0, Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, Diagnostics.Building_project_0, @@ -204,12 +189,11 @@ namespace ts { describe("tsbuild - project invalidation", () => { it("invalidates projects correctly", () => { const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/tests"], { dry: false, force: false, verbose: false }); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false }); - clearDiagnostics(); builder.buildAllProjects(); - assertDiagnosticMessages(/*empty*/); + host.assertDiagnosticMessages(/*empty*/); // Update a timestamp in the middle project tick(); @@ -240,11 +224,10 @@ namespace ts { function verifyProjectWithResolveJsonModule(configFile: string, ...expectedDiagnosticMessages: DiagnosticMessage[]) { const fs = projFs.shadow(); - const host = new fakes.CompilerHost(fs); - const builder = createSolutionBuilder(host, buildHost, [configFile], { dry: false, force: false, verbose: false }); - clearDiagnostics(); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, [configFile], { dry: false, force: false, verbose: false }); builder.buildAllProjects(); - assertDiagnosticMessages(...expectedDiagnosticMessages); + host.assertDiagnosticMessages(...expectedDiagnosticMessages); if (!expectedDiagnosticMessages.length) { // Check for outputs. Not an exhaustive list for (const output of allExpectedOutputs) { @@ -274,11 +257,11 @@ namespace ts { let fs: vfs.FileSystem | undefined; before(() => { fs = outFileFs.shadow(); - const host = new fakes.CompilerHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/third"], { dry: false, force: false, verbose: false }); - clearDiagnostics(); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: false }); + host.clearDiagnostics(); builder.buildAllProjects(); - assertDiagnosticMessages(/*none*/); + host.assertDiagnosticMessages(/*none*/); }); after(() => { fs = undefined; @@ -293,25 +276,24 @@ namespace ts { describe("tsbuild - downstream prepend projects always get rebuilt", () => { it("", () => { const fs = outFileFs.shadow(); - const host = new fakes.CompilerHost(fs); - const builder = createSolutionBuilder(host, buildHost, ["/src/third"], { dry: false, force: false, verbose: false }); - clearDiagnostics(); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: false }); builder.buildAllProjects(); - assertDiagnosticMessages(/*none*/); + host.assertDiagnosticMessages(/*none*/); assert.equal(fs.statSync("src/third/thirdjs/output/third-output.js").mtimeMs, time(), "First build timestamp is correct"); tick(); replaceText(fs, "src/first/first_PART1.ts", "Hello", "Hola"); tick(); builder.resetBuildContext(); builder.buildAllProjects(); - assertDiagnosticMessages(/*none*/); + host.assertDiagnosticMessages(/*none*/); assert.equal(fs.statSync("src/third/thirdjs/output/third-output.js").mtimeMs, time(), "Second build timestamp is correct"); }); }); } describe("tsbuild - graph-ordering", () => { - let host: fakes.CompilerHost | undefined; + let host: fakes.SolutionBuilderHost | undefined; const deps: [string, string][] = [ ["A", "B"], ["B", "C"], @@ -324,7 +306,7 @@ namespace ts { before(() => { const fs = new vfs.FileSystem(false); - host = new fakes.CompilerHost(fs); + host = new fakes.SolutionBuilderHost(fs); writeProjects(fs, ["A", "B", "C", "D", "E", "F", "G"], deps); }); @@ -349,7 +331,7 @@ namespace ts { }); function checkGraphOrdering(rootNames: string[], expectedBuildSet: string[]) { - const builder = createSolutionBuilder(host!, buildHost, rootNames, { dry: true, force: false, verbose: false }); + const builder = createSolutionBuilder(host!, rootNames, { dry: true, force: false, verbose: false }); const projFileNames = rootNames.map(getProjectFileName); const graph = builder.getBuildGraph(projFileNames); @@ -404,30 +386,6 @@ namespace ts { fs.writeFileSync(path, newContent, "utf-8"); } - function assertDiagnosticMessages(...expected: DiagnosticMessage[]) { - const actual = lastDiagnostics.slice(); - if (actual.length !== expected.length) { - assert.fail(actual, expected, `Diagnostic arrays did not match - got\r\n${actual.map(a => " " + a.messageText).join("\r\n")}\r\nexpected\r\n${expected.map(e => " " + e.message).join("\r\n")}`); - } - for (let i = 0; i < actual.length; i++) { - if (actual[i].code !== expected[i].code) { - assert.fail(actual[i].messageText, expected[i].message, `Mismatched error code - expected diagnostic ${i} "${actual[i].messageText}" to match ${expected[i].message}`); - } - } - } - - function clearDiagnostics() { - lastDiagnostics = []; - } - - export function printDiagnostics(header = "== Diagnostics ==") { - const out = createDiagnosticReporter(sys); - sys.write(header + "\r\n"); - for (const d of lastDiagnostics) { - out(d); - } - } - function tick() { currentTime += 60_000; } diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts index 87224c09338..d43a24a0b9c 100644 --- a/src/testRunner/unittests/tsbuildWatchMode.ts +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -2,15 +2,7 @@ namespace ts.tscWatch { export import libFile = TestFSWithWatch.libFile; function createSolutionBuilder(system: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { const host = createSolutionBuilderWithWatchHost(system); - const reportDiag = createDiagnosticReporter(system); - const report = (message: DiagnosticMessage, ...args: string[]) => reportDiag(createCompilerDiagnostic(message, ...args)); - const buildHost: BuildHost = { - error: report, - verbose: report, - message: report, - errorDiagnostic: d => reportDiag(d) - }; - return ts.createSolutionBuilder(host, buildHost, rootNames, defaultOptions || { dry: false, force: false, verbose: false, watch: true }); + return ts.createSolutionBuilder(host, rootNames, defaultOptions || { dry: false, force: false, verbose: false, watch: true }); } function createSolutionBuilderWithWatch(host: WatchedSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index 5c7af1a4b99..5be8660187b 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -13,7 +13,7 @@ namespace ts { } let reportDiagnostic = createDiagnosticReporter(sys); - function updateReportDiagnostic(options: CompilerOptions) { + function updateReportDiagnostic(options?: CompilerOptions) { if (shouldBePretty(options)) { reportDiagnostic = createDiagnosticReporter(sys, /*pretty*/ true); } @@ -23,8 +23,8 @@ namespace ts { return !!sys.writeOutputIsTTY && sys.writeOutputIsTTY(); } - function shouldBePretty(options: CompilerOptions) { - if (typeof options.pretty === "undefined") { + function shouldBePretty(options?: CompilerOptions) { + if (!options || typeof options.pretty === "undefined") { return defaultIsPretty(); } return options.pretty; @@ -241,7 +241,7 @@ namespace ts { } // Update to pretty if host supports it - updateReportDiagnostic({}); + updateReportDiagnostic(); if (!sys.getModifiedTime || !sys.setModifiedTime || (buildOptions.clean && !sys.deleteFile)) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--build")); @@ -274,16 +274,8 @@ namespace ts { addProject("."); } - const report = (message: DiagnosticMessage, ...args: string[]) => reportDiagnostic(createCompilerDiagnostic(message, ...args)); - const buildHost: BuildHost = { - error: report, - verbose: report, - message: report, - errorDiagnostic: d => reportDiagnostic(d) - }; - // TODO: change this to host if watch => watchHost otherwiue without wathc - const builder = createSolutionBuilder(createSolutionBuilderWithWatchHost(), buildHost, projects, buildOptions); + const builder = createSolutionBuilder(createSolutionBuilderWithWatchHost(sys, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty()), createWatchStatusReporter()), projects, buildOptions); if (buildOptions.clean) { return builder.cleanAllProjects(); } @@ -300,7 +292,7 @@ namespace ts { const fileName = resolvePath(sys.getCurrentDirectory(), projectSpecification); const refPath = resolveProjectReferencePath(sys, { path: fileName }); if (!sys.fileExists(refPath)) { - return buildHost.error(Diagnostics.File_0_does_not_exist, fileName); + return reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, fileName)); } projects.push(refPath); } @@ -339,7 +331,7 @@ namespace ts { }; } - function createWatchStatusReporter(options: CompilerOptions) { + function createWatchStatusReporter(options?: CompilerOptions) { return ts.createWatchStatusReporter(sys, shouldBePretty(options)); } From 7960090bb68bda21857c8759cec637dd3fbedd36 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 20 Aug 2018 14:22:58 -0700 Subject: [PATCH 027/163] Add preserveWatchOutput option to build option and report starting compilation and file changes detected status --- src/compiler/tsbuild.ts | 9 +++++++++ src/tsc/tsc.ts | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 7efecab608a..2d66ddfe75d 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -54,6 +54,7 @@ namespace ts { /*@internal*/ clean?: boolean; /*@internal*/ watch?: boolean; /*@internal*/ help?: boolean; + preserveWatchOutput?: boolean; } enum BuildResultFlags { @@ -465,6 +466,12 @@ namespace ts { host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args)); } + function reportWatchStatus(message: DiagnosticMessage, ...args: string[]) { + if (hostWithWatch.onWatchStatusChange) { + hostWithWatch.onWatchStatusChange(createCompilerDiagnostic(message, ...args), host.getNewLine(), { preserveWatchOutput: context.options.preserveWatchOutput }); + } + } + function startWatching() { const graph = getGlobalDependencyGraph()!; if (!graph.buildQueue) { @@ -500,6 +507,7 @@ namespace ts { } function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName) { + reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation); invalidateProject(resolved); if (!hostWithWatch.setTimeout) { return; @@ -1038,6 +1046,7 @@ namespace ts { } function buildAllProjects(): ExitStatus { + if (context.options.watch) { reportWatchStatus(Diagnostics.Starting_compilation_in_watch_mode); } const graph = getGlobalDependencyGraph(); if (graph === undefined) return ExitStatus.DiagnosticsPresent_OutputsSkipped; diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index 5be8660187b..1685dfc3449 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -211,7 +211,13 @@ namespace ts { category: Diagnostics.Command_line_Options, description: Diagnostics.Watch_input_files, type: "boolean" - } + }, + { + name: "preserveWatchOutput", + type: "boolean", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen, + }, ]; let buildOptionNameMap: OptionNameMap | undefined; const returnBuildOptionNameMap = () => (buildOptionNameMap || (buildOptionNameMap = createOptionNameMap(buildOpts))); From 0831edab3648dc0f8e2ecb9a7dd30d868d8de27b Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 20 Aug 2018 16:06:13 -0700 Subject: [PATCH 028/163] Keep only errors starting on new screen --- src/compiler/watch.ts | 8 +------- src/testRunner/unittests/tscWatchMode.ts | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 63904ffa43e..c091ad5c30c 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -27,12 +27,6 @@ namespace ts { }; } - /** @internal */ - export const nonClearingMessageCodes: number[] = [ - Diagnostics.Found_1_error_Watching_for_file_changes.code, - Diagnostics.Found_0_errors_Watching_for_file_changes.code - ]; - /** * @returns Whether the screen was cleared. */ @@ -41,7 +35,7 @@ namespace ts { !options.preserveWatchOutput && !options.extendedDiagnostics && !options.diagnostics && - !contains(nonClearingMessageCodes, diagnostic.code)) { + contains(screenStartingMessageCodes, diagnostic.code)) { system.clearScreen(); return true; } diff --git a/src/testRunner/unittests/tscWatchMode.ts b/src/testRunner/unittests/tscWatchMode.ts index 51c0d888f0b..c881e9c14da 100644 --- a/src/testRunner/unittests/tscWatchMode.ts +++ b/src/testRunner/unittests/tscWatchMode.ts @@ -110,7 +110,7 @@ namespace ts.tscWatch { function assertWatchDiagnostic(diagnostic: Diagnostic) { const expected = getWatchDiagnosticWithoutDate(diagnostic); - if (!disableConsoleClears && !contains(nonClearingMessageCodes, diagnostic.code)) { + if (!disableConsoleClears && contains(screenStartingMessageCodes, diagnostic.code)) { assert.equal(host.screenClears[screenClears], index, `Expected screen clear at this diagnostic: ${expected}`); screenClears++; } From 4193846108b7bb7e7caadf7a9e62b487714c60e9 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 21 Aug 2018 13:52:04 -0700 Subject: [PATCH 029/163] Do not expose change in createCompilerHost --- src/compiler/program.ts | 7 ++++++- src/compiler/tsbuild.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 6ca29707cb9..08bb4727781 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -66,7 +66,12 @@ namespace ts { mtime: Date; } - export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost { + export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost { + return createCompilerHostWorker(options, setParentNodes); + } + /*@internal*/ + // TODO(shkamat): update this after reworking ts build API + export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost { const existingDirectories = createMap(); function getCanonicalFileName(fileName: string): string { diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 2d66ddfe75d..22b2237d1ae 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -413,7 +413,7 @@ namespace ts { } export function createSolutionBuilderHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) { - const host = createCompilerHost({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHost; + const host = createCompilerHostWorker({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHost; host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined; host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime!(path, date) : noop; host.deleteFile = system.deleteFile ? path => system.deleteFile!(path) : noop; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index dd5f3c7c658..3b7764cfd74 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4122,7 +4122,7 @@ declare namespace ts { declare namespace ts { function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined; function resolveTripleslashReference(moduleName: string, containingFile: string): string; - function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean, system?: System): CompilerHost; + function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; interface FormatDiagnosticsHost { getCurrentDirectory(): string; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2938fc9bcc8..e92e3d6e1d5 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4122,7 +4122,7 @@ declare namespace ts { declare namespace ts { function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName?: string): string | undefined; function resolveTripleslashReference(moduleName: string, containingFile: string): string; - function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean, system?: System): CompilerHost; + function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; interface FormatDiagnosticsHost { getCurrentDirectory(): string; From ac7c2ba9e2f71edc03fdf3fd2f753d145584cc83 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 21 Aug 2018 16:18:51 -0700 Subject: [PATCH 030/163] Remove unused overloads of 'deduplicate' and 'deduplicateSorted' --- src/compiler/core.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 1eaab5b1b59..3cd8e1fd115 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -775,7 +775,7 @@ namespace ts { return deduplicated.map(i => array[i]); } - function deduplicateEquality(array: ReadonlyArray, equalityComparer: EqualityComparer) { + function deduplicateEquality(array: ReadonlyArray, equalityComparer?: EqualityComparer) { const result: T[] = []; for (const item of array) { pushIfUnique(result, item, equalityComparer); @@ -789,23 +789,17 @@ namespace ts { * @param comparer An optional `Comparer` used to sort entries before comparison, though the * result will remain in the original order in `array`. */ - export function deduplicate(array: ReadonlyArray, equalityComparer?: EqualityComparer, comparer?: Comparer): T[]; - export function deduplicate(array: ReadonlyArray | undefined, equalityComparer?: EqualityComparer, comparer?: Comparer): T[] | undefined; - export function deduplicate(array: ReadonlyArray | undefined, equalityComparer: EqualityComparer, comparer?: Comparer): T[] | undefined { - return !array ? undefined : - array.length === 0 ? [] : + export function deduplicate(array: ReadonlyArray, equalityComparer?: EqualityComparer, comparer?: Comparer): T[] { + return array.length === 0 ? [] : array.length === 1 ? array.slice() : - comparer ? deduplicateRelational(array, equalityComparer, comparer) : + comparer ? deduplicateRelational(array, equalityComparer!, comparer) : deduplicateEquality(array, equalityComparer); } /** * Deduplicates an array that has already been sorted. */ - function deduplicateSorted(array: ReadonlyArray, comparer: EqualityComparer | Comparer): T[]; - function deduplicateSorted(array: ReadonlyArray | undefined, comparer: EqualityComparer | Comparer): T[] | undefined; - function deduplicateSorted(array: ReadonlyArray | undefined, comparer: EqualityComparer | Comparer): T[] | undefined { - if (!array) return undefined; + function deduplicateSorted(array: ReadonlyArray, comparer: EqualityComparer | Comparer): T[] { if (array.length === 0) return []; let last = array[0]; From cec1b0a7179983eb880e806120ae25ac207029a9 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 21 Aug 2018 16:25:57 -0700 Subject: [PATCH 031/163] Report error summary from the queue. --- src/compiler/program.ts | 2 +- src/compiler/tsbuild.ts | 166 ++++++++++++++----- src/testRunner/unittests/tsbuild.ts | 4 +- src/testRunner/unittests/tsbuildWatchMode.ts | 80 ++++++++- src/testRunner/unittests/tscWatchMode.ts | 4 +- 5 files changed, 206 insertions(+), 50 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 08bb4727781..d1168046b8b 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -175,7 +175,7 @@ namespace ts { return getDirectoryPath(normalizePath(system.getExecutingFilePath())); } - const newLine = getNewLineCharacter(options); + const newLine = getNewLineCharacter(options, () => system.newLine); const realpath = system.realpath && ((path: string) => system.realpath!(path)); return { diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 22b2237d1ae..5fdab168951 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -35,9 +35,11 @@ namespace ts { * Map from config file name to up-to-date status */ projectStatus: FileMap; + diagnostics?: FileMap; // TODO(shkamat): this should be really be diagnostics but thats for later time - invalidatedProjects: FileMap; - queuedProjects: FileMap; + invalidateProject(project: ResolvedConfigFileName, dependencyGraph: DependencyGraph | undefined): void; + getNextInvalidatedProject(): ResolvedConfigFileName | undefined; + pendingInvalidatedProjects(): boolean; missingRoots: Map; } @@ -194,6 +196,7 @@ namespace ts { hasKey(fileName: string): boolean; removeKey(fileName: string): void; getKeys(): string[]; + getSize(): number; } /** @@ -209,7 +212,8 @@ namespace ts { getValueOrUndefined, removeKey, getKeys, - hasKey + hasKey, + getSize }; function getKeys(): string[] { @@ -242,6 +246,10 @@ namespace ts { const f = normalizePath(fileName); return lookup.get(f); } + + function getSize() { + return lookup.size; + } } function createDependencyMapper() { @@ -375,18 +383,64 @@ namespace ts { } export function createBuildContext(options: BuildOptions): BuildContext { - const invalidatedProjects = createFileMap(); - const queuedProjects = createFileMap(); + const invalidatedProjectQueue = [] as ResolvedConfigFileName[]; + let nextIndex = 0; + const projectPendingBuild = createFileMap(); const missingRoots = createMap(); + const diagnostics = options.watch ? createFileMap() : undefined; return { options, projectStatus: createFileMap(), + diagnostics, unchangedOutputs: createFileMap(), - invalidatedProjects, - missingRoots, - queuedProjects + invalidateProject, + getNextInvalidatedProject, + pendingInvalidatedProjects, + missingRoots }; + + function invalidateProject(proj: ResolvedConfigFileName, dependancyGraph: DependencyGraph | undefined) { + if (!projectPendingBuild.hasKey(proj)) { + addProjToQueue(proj); + if (dependancyGraph) { + queueBuildForDownstreamReferences(proj, dependancyGraph); + } + } + } + + function addProjToQueue(proj: ResolvedConfigFileName) { + projectPendingBuild.setValue(proj, true); + invalidatedProjectQueue.push(proj); + } + + function getNextInvalidatedProject() { + if (nextIndex < invalidatedProjectQueue.length) { + const proj = invalidatedProjectQueue[nextIndex]; + nextIndex++; + projectPendingBuild.removeKey(proj); + if (!projectPendingBuild.getSize()) { + invalidatedProjectQueue.length = 0; + } + return proj; + } + } + + function pendingInvalidatedProjects() { + return !!projectPendingBuild.getSize(); + } + + // Mark all downstream projects of this one needing to be built "later" + function queueBuildForDownstreamReferences(root: ResolvedConfigFileName, dependancyGraph: DependencyGraph) { + const deps = dependancyGraph.dependencyMap.getReferencesTo(root); + for (const ref of deps) { + // Can skip circular references + if (!projectPendingBuild.hasKey(ref)) { + addProjToQueue(ref); + queueBuildForDownstreamReferences(ref, dependancyGraph); + } + } + } } export interface SolutionBuilderHost extends CompilerHost { @@ -443,6 +497,7 @@ namespace ts { const hostWithWatch = host as SolutionBuilderWithWatchHost; const configFileCache = createConfigFileCache(host); let context = createBuildContext(defaultOptions); + let timerToBuildInvalidatedProject: any; const existingWatchersForWildcards = createMap(); return { @@ -454,8 +509,7 @@ namespace ts { getBuildGraph, invalidateProject, - buildInvalidatedProjects, - buildDependentInvalidatedProjects, + buildInvalidatedProject, resolveProjectName, @@ -466,7 +520,19 @@ namespace ts { host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args)); } - function reportWatchStatus(message: DiagnosticMessage, ...args: string[]) { + function storeErrors(proj: ResolvedConfigFileName, diagnostics: ReadonlyArray) { + if (context.options.watch) { + storeErrorSummary(proj, diagnostics.filter(diagnostic => diagnostic.category === DiagnosticCategory.Error).length); + } + } + + function storeErrorSummary(proj: ResolvedConfigFileName, errorCount: number) { + if (context.options.watch) { + context.diagnostics!.setValue(proj, errorCount); + } + } + + function reportWatchStatus(message: DiagnosticMessage, ...args: (string | number | undefined)[]) { if (hostWithWatch.onWatchStatusChange) { hostWithWatch.onWatchStatusChange(createCompilerDiagnostic(message, ...args), host.getNewLine(), { preserveWatchOutput: context.options.preserveWatchOutput }); } @@ -506,15 +572,12 @@ namespace ts { } } - function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName) { - reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation); - invalidateProject(resolved); - if (!hostWithWatch.setTimeout) { - return; - } - hostWithWatch.setTimeout(buildInvalidatedProjects, 100); - hostWithWatch.setTimeout(buildDependentInvalidatedProjects, 3000); - } + } + + function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName) { + reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation); + invalidateProject(resolved); + scheduleBuildInvalidatedProject(); } function resetBuildContext(opts = defaultOptions) { @@ -725,33 +788,44 @@ namespace ts { } configFileCache.removeKey(resolved); - context.invalidatedProjects.setValue(resolved, true); context.projectStatus.removeKey(resolved); - - const graph = getGlobalDependencyGraph()!; - if (graph) { - queueBuildForDownstreamReferences(resolved); + if (context.options.watch) { + context.diagnostics!.removeKey(resolved); } - // Mark all downstream projects of this one needing to be built "later" - function queueBuildForDownstreamReferences(root: ResolvedConfigFileName) { - const deps = graph.dependencyMap.getReferencesTo(root); - for (const ref of deps) { - // Can skip circular references - if (!context.queuedProjects.hasKey(ref)) { - context.queuedProjects.setValue(ref, true); - queueBuildForDownstreamReferences(ref); - } + context.invalidateProject(resolved, getGlobalDependencyGraph()); + } + + function scheduleBuildInvalidatedProject() { + if (!hostWithWatch.setTimeout || !hostWithWatch.clearTimeout) { + return; + } + if (timerToBuildInvalidatedProject) { + hostWithWatch.clearTimeout(timerToBuildInvalidatedProject); + } + timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildInvalidatedProject, 250); + } + + function buildInvalidatedProject() { + timerToBuildInvalidatedProject = undefined; + const buildProject = context.getNextInvalidatedProject(); + buildSomeProjects(p => p === buildProject); + if (context.pendingInvalidatedProjects()) { + if (!timerToBuildInvalidatedProject) { + scheduleBuildInvalidatedProject(); } } + else { + reportErrorSummary(); + } } - function buildInvalidatedProjects() { - buildSomeProjects(p => context.invalidatedProjects.hasKey(p)); - } - - function buildDependentInvalidatedProjects() { - buildSomeProjects(p => context.queuedProjects.hasKey(p)); + function reportErrorSummary() { + if (context.options.watch) { + let errorCount = 0; + context.diagnostics!.getKeys().forEach(resolved => errorCount += context.diagnostics!.getValue(resolved)); + reportWatchStatus(errorCount === 1 ? Diagnostics.Found_1_error_Watching_for_file_changes : Diagnostics.Found_0_errors_Watching_for_file_changes, errorCount); + } } function buildSomeProjects(predicate: (projName: ResolvedConfigFileName) => boolean) { @@ -808,6 +882,7 @@ namespace ts { if (temporaryMarks[projPath]) { if (!inCircularContext) { hadError = true; + // TODO(shkamat): Account for this error reportStatus(Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0, circularityReportStack.join("\r\n")); return; } @@ -853,6 +928,7 @@ namespace ts { if (!configFile) { // Failed to read the config file resultFlags |= BuildResultFlags.ConfigFileErrors; + storeErrorSummary(proj, 1); context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Config file errors" }); return resultFlags; } @@ -880,6 +956,7 @@ namespace ts { for (const diag of syntaxDiagnostics) { host.reportDiagnostic(diag); } + storeErrors(proj, syntaxDiagnostics); context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Syntactic errors" }); return resultFlags; } @@ -892,6 +969,7 @@ namespace ts { for (const diag of declDiagnostics) { host.reportDiagnostic(diag); } + storeErrors(proj, declDiagnostics); context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Declaration file errors" }); return resultFlags; } @@ -904,6 +982,7 @@ namespace ts { for (const diag of semanticDiagnostics) { host.reportDiagnostic(diag); } + storeErrors(proj, semanticDiagnostics); context.projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Semantic errors" }); return resultFlags; } @@ -1029,6 +1108,7 @@ namespace ts { if (host.fileExists(fullPathWithTsconfig)) { return fullPathWithTsconfig as ResolvedConfigFileName; } + // TODO(shkamat): right now this is accounted as 1 error in config file, but we need to do better host.reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_not_found, relName(fullPath))); return undefined; } @@ -1048,7 +1128,10 @@ namespace ts { function buildAllProjects(): ExitStatus { if (context.options.watch) { reportWatchStatus(Diagnostics.Starting_compilation_in_watch_mode); } const graph = getGlobalDependencyGraph(); - if (graph === undefined) return ExitStatus.DiagnosticsPresent_OutputsSkipped; + if (graph === undefined) { + reportErrorSummary(); + return ExitStatus.DiagnosticsPresent_OutputsSkipped; + } const queue = graph.buildQueue; reportBuildQueue(graph); @@ -1092,6 +1175,7 @@ namespace ts { const buildResult = buildSingleProject(next); anyFailed = anyFailed || !!(buildResult & BuildResultFlags.AnyErrors); } + reportErrorSummary(); return anyFailed ? ExitStatus.DiagnosticsPresent_OutputsSkipped : ExitStatus.Success; } diff --git a/src/testRunner/unittests/tsbuild.ts b/src/testRunner/unittests/tsbuild.ts index f8813ecd1ae..b7d708446c1 100644 --- a/src/testRunner/unittests/tsbuild.ts +++ b/src/testRunner/unittests/tsbuild.ts @@ -205,14 +205,14 @@ namespace ts { // Rebuild this project tick(); builder.invalidateProject("/src/logic"); - builder.buildInvalidatedProjects(); + builder.buildInvalidatedProject(); // The file should be updated assert.equal(fs.statSync("/src/logic/index.js").mtimeMs, time(), "JS file should have been rebuilt"); assert.isBelow(fs.statSync("/src/tests/index.js").mtimeMs, time(), "Downstream JS file should *not* have been rebuilt"); // Build downstream projects should update 'tests', but not 'core' tick(); - builder.buildDependentInvalidatedProjects(); + builder.buildInvalidatedProject(); assert.equal(fs.statSync("/src/tests/index.js").mtimeMs, time(), "Downstream JS file should have been rebuilt"); assert.isBelow(fs.statSync("/src/core/index.js").mtimeMs, time(), "Upstream JS file should not have been rebuilt"); }); diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts index d43a24a0b9c..d1405fa9e2c 100644 --- a/src/testRunner/unittests/tsbuildWatchMode.ts +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -25,12 +25,18 @@ namespace ts.tscWatch { /** [tsconfig, index] | [tsconfig, index, anotherModule, someDecl] */ type SubProjectFiles = [ReadonlyFile, ReadonlyFile] | [ReadonlyFile, ReadonlyFile, ReadonlyFile, ReadonlyFile]; const root = Harness.IO.getWorkspaceRoot(); + + function projectFilePath(subProject: SubProject, baseFileName: string) { + return `${projectsLocation}/${project}/${subProject}/${baseFileName.toLowerCase()}`; + } + function projectFile(subProject: SubProject, baseFileName: string): File { return { - path: `${projectsLocation}/${project}/${subProject}/${baseFileName.toLowerCase()}`, + path: projectFilePath(subProject, baseFileName), content: Harness.IO.readFile(`${root}/tests/projects/${project}/${subProject}/${baseFileName}`)! }; } + function subProjectFiles(subProject: SubProject, anotherModuleAndSomeDecl?: true): SubProjectFiles { const tsconfig = projectFile(subProject, "tsconfig.json"); const index = projectFile(subProject, "index.ts"); @@ -42,20 +48,86 @@ namespace ts.tscWatch { return [tsconfig, index, anotherModule, someDecl]; } + function getOutputFileNames(subProject: SubProject, baseFileNameWithoutExtension: string) { + const file = projectFilePath(subProject, baseFileNameWithoutExtension); + return [`${file}.js`, `${file}.d.ts`]; + } + + type OutputFileStamp = [string, Date | undefined]; + function getOutputStamps(host: WatchedSystem, subProject: SubProject, baseFileNameWithoutExtension: string): OutputFileStamp[] { + return getOutputFileNames(subProject, baseFileNameWithoutExtension).map(f => [f, host.getModifiedTime(f)] as OutputFileStamp); + } + + function getOutputFileStamps(host: WatchedSystem): OutputFileStamp[] { + return [ + ...getOutputStamps(host, SubProject.core, "anotherModule"), + ...getOutputStamps(host, SubProject.core, "index"), + ...getOutputStamps(host, SubProject.logic, "index"), + ...getOutputStamps(host, SubProject.tests, "index"), + ]; + } + + function verifyChangedFiles(actualStamps: OutputFileStamp[], oldTimeStamps: OutputFileStamp[], changedFiles: string[]) { + for (let i = 0; i < oldTimeStamps.length; i++) { + const actual = actualStamps[i]; + const old = oldTimeStamps[i]; + if (contains(changedFiles, actual[0])) { + assert.isTrue((actual[1] || 0) > (old[1] || 0), `${actual[0]} expected to written`); + } + else { + assert.equal(actual[1], old[1], `${actual[0]} expected to not change`); + } + } + } + const core = subProjectFiles(SubProject.core, /*anotherModuleAndSomeDecl*/ true); const logic = subProjectFiles(SubProject.logic); const tests = subProjectFiles(SubProject.tests); const ui = subProjectFiles(SubProject.ui); const allFiles: ReadonlyArray = [libFile, ...core, ...logic, ...tests, ...ui]; const testProjectExpectedWatchedFiles = [core[0], core[1], core[2], ...logic, ...tests].map(f => f.path); - it("creates solution in watch mode", () => { + + function createSolutionInWatchMode() { const host = createWatchedSystem(allFiles, { currentDirectory: projectsLocation }); - const originalWrite = host.write; - host.write = s => { console.log(s); originalWrite.call(host, s); }; createSolutionBuilderWithWatch(host, [`${project}/${SubProject.tests}`]); checkWatchedFiles(host, testProjectExpectedWatchedFiles); checkWatchedDirectories(host, emptyArray, /*recursive*/ false); checkWatchedDirectories(host, emptyArray, /*recursive*/ true); // TODO: #26524 + checkOutputErrorsInitial(host, emptyArray); + const outputFileStamps = getOutputFileStamps(host); + for (const stamp of outputFileStamps) { + assert.isDefined(stamp[1], `${stamp[0]} expected to be present`); + } + return { host, outputFileStamps }; + } + it("creates solution in watch mode", () => { + createSolutionInWatchMode(); }); + + it("change builds changes and reports found errors message", () => { + const { host, outputFileStamps } = createSolutionInWatchMode(); + host.writeFile(core[1].path, `${core[1].content} +export class someClass { }`); + host.checkTimeoutQueueLengthAndRun(1); // Builds core + const changedCore = getOutputFileStamps(host); + verifyChangedFiles(changedCore, outputFileStamps, [ + ...getOutputFileNames(SubProject.core, "anotherModule"), // This should not be written really + ...getOutputFileNames(SubProject.core, "index") + ]); + host.checkTimeoutQueueLengthAndRun(1); // Builds tests + const changedTests = getOutputFileStamps(host); + verifyChangedFiles(changedTests, changedCore, [ + ...getOutputFileNames(SubProject.tests, "index") // Again these need not be written + ]); + host.checkTimeoutQueueLengthAndRun(1); // Builds logic + const changedLogic = getOutputFileStamps(host); + verifyChangedFiles(changedLogic, changedTests, [ + ...getOutputFileNames(SubProject.logic, "index") // Again these need not be written + ]); + host.checkTimeoutQueueLength(0); + checkOutputErrorsIncremental(host, emptyArray); + }); + + // TODO: write tests reporting errors but that will have more involved work since file }); } diff --git a/src/testRunner/unittests/tscWatchMode.ts b/src/testRunner/unittests/tscWatchMode.ts index c881e9c14da..da1c4fd0d70 100644 --- a/src/testRunner/unittests/tscWatchMode.ts +++ b/src/testRunner/unittests/tscWatchMode.ts @@ -136,7 +136,7 @@ namespace ts.tscWatch { : createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errors.length); } - function checkOutputErrorsInitial(host: WatchedSystem, errors: ReadonlyArray, disableConsoleClears?: boolean, logsBeforeErrors?: string[]) { + export function checkOutputErrorsInitial(host: WatchedSystem, errors: ReadonlyArray, disableConsoleClears?: boolean, logsBeforeErrors?: string[]) { checkOutputErrors( host, /*logsBeforeWatchDiagnostic*/ undefined, @@ -147,7 +147,7 @@ namespace ts.tscWatch { createErrorsFoundCompilerDiagnostic(errors)); } - function checkOutputErrorsIncremental(host: WatchedSystem, errors: ReadonlyArray, disableConsoleClears?: boolean, logsBeforeWatchDiagnostic?: string[], logsBeforeErrors?: string[]) { + export function checkOutputErrorsIncremental(host: WatchedSystem, errors: ReadonlyArray, disableConsoleClears?: boolean, logsBeforeWatchDiagnostic?: string[], logsBeforeErrors?: string[]) { checkOutputErrors( host, logsBeforeWatchDiagnostic, From 213d374e13b1b6916598d28c1373e050547def20 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 22 Aug 2018 15:27:03 -0700 Subject: [PATCH 032/163] Make equalityComparer non-optional --- src/compiler/core.ts | 6 +++--- src/server/session.ts | 7 +------ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 3cd8e1fd115..722b42975ee 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -775,7 +775,7 @@ namespace ts { return deduplicated.map(i => array[i]); } - function deduplicateEquality(array: ReadonlyArray, equalityComparer?: EqualityComparer) { + function deduplicateEquality(array: ReadonlyArray, equalityComparer: EqualityComparer) { const result: T[] = []; for (const item of array) { pushIfUnique(result, item, equalityComparer); @@ -789,10 +789,10 @@ namespace ts { * @param comparer An optional `Comparer` used to sort entries before comparison, though the * result will remain in the original order in `array`. */ - export function deduplicate(array: ReadonlyArray, equalityComparer?: EqualityComparer, comparer?: Comparer): T[] { + export function deduplicate(array: ReadonlyArray, equalityComparer: EqualityComparer, comparer?: Comparer): T[] { return array.length === 0 ? [] : array.length === 1 ? array.slice() : - comparer ? deduplicateRelational(array, equalityComparer!, comparer) : + comparer ? deduplicateRelational(array, equalityComparer, comparer) : deduplicateEquality(array, equalityComparer); } diff --git a/src/server/session.ts b/src/server/session.ts index 8d2fbe9e190..43f2e4f76b3 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -266,8 +266,6 @@ namespace ts.server { getValue: (path: Path) => T, projects: Projects, action: (project: Project, value: T) => ReadonlyArray | U | undefined, - comparer?: (a: U, b: U) => number, - areEqual?: (a: U, b: U) => boolean, ): U[] { const outputs = flatMap(isArray(projects) ? projects : projects.projects, project => action(project, defaultValue)); if (!isArray(projects) && projects.symLinkedProjects) { @@ -276,10 +274,7 @@ namespace ts.server { outputs.push(...flatMap(projects, project => action(project, value))); }); } - - return comparer - ? sortAndDeduplicate(outputs, comparer, areEqual) - : deduplicate(outputs, areEqual); + return deduplicate(outputs, equateValues); } function combineProjectOutputFromEveryProject(projectService: ProjectService, action: (project: Project) => ReadonlyArray, areEqual: (a: T, b: T) => boolean) { From bedf776b42e1d4708428a7b26fb0a1521a3f462e Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Thu, 23 Aug 2018 09:08:29 +0200 Subject: [PATCH 033/163] Revert #26360: Don't error on destructure of private property with computed property syntax --- src/compiler/checker.ts | 2 +- .../reference/destructureComputedProperty.errors.txt | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7e0e7122404..983f9f070d0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24250,7 +24250,7 @@ namespace ts { if (nameText) { const property = getPropertyOfType(parentType!, nameText)!; // TODO: GH#18217 markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference. - if (parent.initializer && property && !isComputedPropertyName(name)) { + if (parent.initializer && property) { checkPropertyAccessibility(parent, parent.initializer.kind === SyntaxKind.SuperKeyword, parentType!, property); } } diff --git a/tests/baselines/reference/destructureComputedProperty.errors.txt b/tests/baselines/reference/destructureComputedProperty.errors.txt index 5d461867a54..5b39820988a 100644 --- a/tests/baselines/reference/destructureComputedProperty.errors.txt +++ b/tests/baselines/reference/destructureComputedProperty.errors.txt @@ -1,8 +1,9 @@ tests/cases/compiler/destructureComputedProperty.ts(7,7): error TS2341: Property 'p' is private and only accessible within class 'C'. +tests/cases/compiler/destructureComputedProperty.ts(8,7): error TS2341: Property 'p' is private and only accessible within class 'C'. tests/cases/compiler/destructureComputedProperty.ts(10,7): error TS2341: Property 'p' is private and only accessible within class 'C'. -==== tests/cases/compiler/destructureComputedProperty.ts (2 errors) ==== +==== tests/cases/compiler/destructureComputedProperty.ts (3 errors) ==== declare const ab: { n: number } | { n: string }; const nameN = "n"; const { [nameN]: n } = ab; @@ -13,6 +14,8 @@ tests/cases/compiler/destructureComputedProperty.ts(10,7): error TS2341: Propert ~~~~~~~~~~~ !!! error TS2341: Property 'p' is private and only accessible within class 'C'. const { ["p"]: p1 } = new C(); + ~~~~~~~~~~~~~ +!!! error TS2341: Property 'p' is private and only accessible within class 'C'. const { [nameP]: p2 } = new C(); const { p: p3 } = new C(); ~~~~~~~~~ From e2eda0a43f4fdd938e73de219960c136bb2f30a0 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Thu, 23 Aug 2018 17:56:29 -0700 Subject: [PATCH 034/163] Substitute process ID for "PID" in log file names This will help us solve the problem of logs getting clobbered when the server restarts. --- src/tsserver/server.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index 3e5986e9408..53d052eefb3 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -644,14 +644,18 @@ namespace ts.server { const cmdLineVerbosity = getLogLevel(findArgument("--logVerbosity")); const envLogOptions = parseLoggingEnvironmentString(process.env.TSS_LOG); - const logFileName = cmdLineLogFileName + const unsubstitutedLogFileName = cmdLineLogFileName ? stripQuotes(cmdLineLogFileName) : envLogOptions.logToFile ? envLogOptions.file || (__dirname + "/.log" + process.pid.toString()) : undefined; + const substitutedLogFileName = unsubstitutedLogFileName + ? unsubstitutedLogFileName.replace("PID", process.pid.toString()) + : undefined; + const logVerbosity = cmdLineVerbosity || envLogOptions.detailLevel; - return new Logger(logFileName!, envLogOptions.traceToConsole!, logVerbosity!); // TODO: GH#18217 + return new Logger(substitutedLogFileName!, envLogOptions.traceToConsole!, logVerbosity!); // TODO: GH#18217 } // This places log file in the directory containing editorServices.js // TODO: check that this location is writable From 0f04e43cc0b225f1c02d593b21e20977ad0264fb Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 24 Aug 2018 04:10:34 +0000 Subject: [PATCH 035/163] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 20262 ++++++++-------- 1 file changed, 10131 insertions(+), 10131 deletions(-) diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 62489815a38..7fade1f0ae3 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,10132 +1,10132 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - veya - biçiminde olmalıdır. Örneğin, '{0}' veya '{1}'.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - türü olmalıdır.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()' kullanın.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + veya - biçiminde olmalıdır. Örneğin, '{0}' veya '{1}'.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + türü olmalıdır.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()' kullanın.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 8ba501926a48c244b13ef3c96c2bf0942628e003 Mon Sep 17 00:00:00 2001 From: Wenlu Wang Date: Fri, 24 Aug 2018 12:31:53 +0800 Subject: [PATCH 036/163] try get add missing member return type from context (#26250) * try get add missing member return type from context * support contextual type --- src/services/codefixes/helpers.ts | 22 ++++++++----------- .../fourslash/codeFixAddMissingMember10.ts | 16 ++++++++++++++ .../fourslash/codeFixAddMissingMember11.ts | 18 +++++++++++++++ 3 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 tests/cases/fourslash/codeFixAddMissingMember10.ts create mode 100644 tests/cases/fourslash/codeFixAddMissingMember11.ts diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 5b955d24926..eec693bbb69 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -112,27 +112,23 @@ namespace ts.codefix { export function createMethodFromCallExpression( context: CodeFixContextBase, - { typeArguments, arguments: args, parent: parent }: CallExpression, + call: CallExpression, methodName: string, inJs: boolean, makeStatic: boolean, preferences: UserPreferences, body: boolean, ): MethodDeclaration { + const { typeArguments, arguments: args, parent } = call; const checker = context.program.getTypeChecker(); - const types = map(args, - arg => { - let type = checker.getTypeAtLocation(arg); - if (type === undefined) { - return undefined; - } - // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" - type = checker.getBaseTypeOfLiteralType(type); - return checker.typeToTypeNode(type); - }); + const types = map(args, arg => + // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" + checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg)))); const names = map(args, arg => isIdentifier(arg) ? arg.text : - isPropertyAccessExpression(arg) ? arg.name.text : undefined); + isPropertyAccessExpression(arg) ? arg.name.text : undefined); + const contextualType = checker.getContextualType(call); + const returnType = inJs ? undefined : contextualType && checker.typeToTypeNode(contextualType, call) || createKeywordTypeNode(SyntaxKind.AnyKeyword); return createMethod( /*decorators*/ undefined, /*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined, @@ -142,7 +138,7 @@ namespace ts.codefix { /*typeParameters*/ inJs ? undefined : map(typeArguments, (_, i) => createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)), /*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs), - /*type*/ inJs ? undefined : createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*type*/ returnType, body ? createStubbedMethodBody(preferences) : undefined); } diff --git a/tests/cases/fourslash/codeFixAddMissingMember10.ts b/tests/cases/fourslash/codeFixAddMissingMember10.ts new file mode 100644 index 00000000000..990d86ec49a --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember10.ts @@ -0,0 +1,16 @@ +/// + +//// class C {} +//// const n: number = new C().add(1, 2); + +verify.codeFixAll({ + fixId: "addMissingMember", + fixAllDescription: "Add all missing members", + newFileContent: +`class C { + add(arg0: number, arg1: number): number { + throw new Error("Method not implemented."); + } +} +const n: number = new C().add(1, 2);`, +}); diff --git a/tests/cases/fourslash/codeFixAddMissingMember11.ts b/tests/cases/fourslash/codeFixAddMissingMember11.ts new file mode 100644 index 00000000000..6f68502d4c9 --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember11.ts @@ -0,0 +1,18 @@ +/// + +//// class C {} +//// function f(v: number): void { } +//// f(new C().add(1, 2)) + +verify.codeFixAll({ + fixId: "addMissingMember", + fixAllDescription: "Add all missing members", + newFileContent: +`class C { + add(arg0: number, arg1: number): number { + throw new Error("Method not implemented."); + } +} +function f(v: number): void { } +f(new C().add(1, 2))`, +}); From bdb7c351a27e3e42b9c64deb15c617e3332eacc4 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Fri, 24 Aug 2018 08:30:21 -0700 Subject: [PATCH 037/163] Update user baselines (#26664) --- .../user/chrome-devtools-frontend.log | 2 - tests/baselines/reference/user/uglify-js.log | 90 +++++++++---------- 2 files changed, 45 insertions(+), 47 deletions(-) diff --git a/tests/baselines/reference/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index 31bd0e9d8b2..09fdbcc0b4b 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -14,8 +14,6 @@ Standard output: ../../../../built/local/lib.es5.d.ts(1346,11): error TS2300: Duplicate identifier 'ArrayLike'. ../../../../built/local/lib.es5.d.ts(1382,6): error TS2300: Duplicate identifier 'Record'. ../../../../node_modules/@types/node/index.d.ts(150,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type '{}', but here has type 'NodeModule'. -definitions.js(3,5): error TS2322: Type '{}' is not assignable to type 'typeof Animation'. - Property 'AnimationGroupPreviewUI' is missing in type '{}'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(43,8): error TS2339: Property '_importScriptPathPrefix' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(95,28): error TS2339: Property 'response' does not exist on type 'EventTarget'. node_modules/chrome-devtools-frontend/front_end/Runtime.js(147,37): error TS2339: Property '_importScriptPathPrefix' does not exist on type 'Window'. diff --git a/tests/baselines/reference/user/uglify-js.log b/tests/baselines/reference/user/uglify-js.log index 26ee4837234..0bc48d677a2 100644 --- a/tests/baselines/reference/user/uglify-js.log +++ b/tests/baselines/reference/user/uglify-js.log @@ -5,51 +5,51 @@ node_modules/uglify-js/lib/ast.js(328,33): error TS2339: Property 'transform' do node_modules/uglify-js/lib/ast.js(869,5): error TS2322: Type '{ _visit: (node: any, descend: any) => any; parent: (n: any) => any; push: typeof push; pop: typeof pop; self: () => any; find_parent: (type: any) => any; has_directive: (type: any) => any; loopcontrol_target: (node: any) => any; in_boolean_context: () => boolean | undefined; }' is not assignable to type 'TreeWalker'. Object literal may only specify known properties, but '_visit' does not exist in type 'TreeWalker'. Did you mean to write 'visit'? node_modules/uglify-js/lib/compress.js(167,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(501,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(818,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1073,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1087,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'true | ((node: any) => any)' has no compatible call signatures. -node_modules/uglify-js/lib/compress.js(1151,53): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1193,112): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(1194,29): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(1203,87): error TS2322: Type 'false' is not assignable to type 'number'. -node_modules/uglify-js/lib/compress.js(1211,29): error TS2322: Type 'false' is not assignable to type 'never'. -node_modules/uglify-js/lib/compress.js(1317,38): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1412,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1508,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1540,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1951,44): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(2137,19): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3193,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3206,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. -node_modules/uglify-js/lib/compress.js(3345,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3400,14): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3417,29): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3442,62): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3669,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3690,24): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3700,28): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3859,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary & { set: (key: any, val: any) => any; add: (key: any, val: any) => any; get: (key: any) => any; del: (key: any) => any; has: (key: any) => boolean; each: (f: any) => void; size: () => any; map: (f: any) => any[]; clone: () => Dictionary & any; toObject: () => any; }', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(3911,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. -node_modules/uglify-js/lib/compress.js(3967,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4076,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4375,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(4459,22): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4809,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4816,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ get: () => string; toString: () => string; indent: () => void; indentation: () => number; current_width: () => number; should_break: () => boolean; has_parens: () => boolean; newline: () => void; print: (str: any) => void; ... 24 more ...; parent: (n: any) => any; }'. -node_modules/uglify-js/lib/compress.js(4820,36): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(4825,41): error TS2339: Property 'get' does not exist on type 'string'. -node_modules/uglify-js/lib/compress.js(5312,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. -node_modules/uglify-js/lib/compress.js(5747,25): error TS2367: This condition will always return 'false' since the types 'boolean' and '"f"' have no overlap. -node_modules/uglify-js/lib/compress.js(5775,32): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5835,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5907,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5913,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(6306,43): error TS2454: Variable 'property' is used before being assigned. -node_modules/uglify-js/lib/compress.js(6321,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6324,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. -node_modules/uglify-js/lib/compress.js(6330,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6358,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(500,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(817,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1072,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1086,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'true | ((node: any) => any)' has no compatible call signatures. +node_modules/uglify-js/lib/compress.js(1150,53): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1192,112): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(1193,29): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(1202,87): error TS2322: Type 'false' is not assignable to type 'number'. +node_modules/uglify-js/lib/compress.js(1210,29): error TS2322: Type 'false' is not assignable to type 'never'. +node_modules/uglify-js/lib/compress.js(1316,38): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1411,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1507,27): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1539,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1963,44): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(2149,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3205,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3218,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. +node_modules/uglify-js/lib/compress.js(3358,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3413,14): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3430,29): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3455,62): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3681,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3702,24): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3712,28): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3871,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary & { set: (key: any, val: any) => any; add: (key: any, val: any) => any; get: (key: any) => any; del: (key: any) => any; has: (key: any) => boolean; each: (f: any) => void; size: () => any; map: (f: any) => any[]; clone: () => Dictionary & any; toObject: () => any; }', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(3923,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. +node_modules/uglify-js/lib/compress.js(3979,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4088,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4387,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(4471,22): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4821,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4828,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ get: () => string; toString: () => string; indent: () => void; indentation: () => number; current_width: () => number; should_break: () => boolean; has_parens: () => boolean; newline: () => void; print: (str: any) => void; ... 24 more ...; parent: (n: any) => any; }'. +node_modules/uglify-js/lib/compress.js(4832,36): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(4837,41): error TS2339: Property 'get' does not exist on type 'string'. +node_modules/uglify-js/lib/compress.js(5324,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. +node_modules/uglify-js/lib/compress.js(5759,25): error TS2367: This condition will always return 'false' since the types 'boolean' and '"f"' have no overlap. +node_modules/uglify-js/lib/compress.js(5787,32): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5847,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5919,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5925,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(6318,43): error TS2454: Variable 'property' is used before being assigned. +node_modules/uglify-js/lib/compress.js(6333,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6336,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. +node_modules/uglify-js/lib/compress.js(6342,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6370,19): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/minify.js(170,75): error TS2339: Property 'compress' does not exist on type 'Compressor'. node_modules/uglify-js/lib/mozilla-ast.js(566,18): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/output.js(246,9): error TS2554: Expected 0 arguments, but got 2. From 0043ba16b17f82c8e7acf87adabd6e6ad540b147 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 24 Aug 2018 10:30:39 -0700 Subject: [PATCH 038/163] Allow weak type detection for intersection sources (#26668) Previously, intersections were only allowed as targets, but this was just an artifact of the original implementation, which operated inside the structural part of isRelatedTo. Removing this restriction catches subtle bugs in React user code, where a function named `create` returns a mapped type whose types are all branded numbers. The display of these properties, for some original type `T`, is not `number & { __ }` but the much-less-obvious `RegisteredStyle`. --- src/compiler/checker.ts | 2 +- .../intersectionAsWeakTypeSource.errors.txt | 30 ++++++++ .../reference/intersectionAsWeakTypeSource.js | 26 +++++++ .../intersectionAsWeakTypeSource.symbols | 72 +++++++++++++++++++ .../intersectionAsWeakTypeSource.types | 60 ++++++++++++++++ .../intersectionAsWeakTypeSource.ts | 18 +++++ 6 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/intersectionAsWeakTypeSource.errors.txt create mode 100644 tests/baselines/reference/intersectionAsWeakTypeSource.js create mode 100644 tests/baselines/reference/intersectionAsWeakTypeSource.symbols create mode 100644 tests/baselines/reference/intersectionAsWeakTypeSource.types create mode 100644 tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0509d53c9b3..50cbb6cb064 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11178,7 +11178,7 @@ namespace ts { } if (relation !== comparableRelation && - !(source.flags & TypeFlags.UnionOrIntersection) && + !(source.flags & TypeFlags.Union) && !(target.flags & TypeFlags.Union) && !isIntersectionConstituent && source !== globalObjectType && diff --git a/tests/baselines/reference/intersectionAsWeakTypeSource.errors.txt b/tests/baselines/reference/intersectionAsWeakTypeSource.errors.txt new file mode 100644 index 00000000000..69da07115ad --- /dev/null +++ b/tests/baselines/reference/intersectionAsWeakTypeSource.errors.txt @@ -0,0 +1,30 @@ +tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts(8,7): error TS2559: Type 'XY' has no properties in common with type 'Z'. +tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts(18,7): error TS2322: Type 'Brand<{ view: number; styleMedia: string; }>' is not assignable to type 'ViewStyle'. + Property 'view' is missing in type 'Number & { __brand: { view: number; styleMedia: string; }; }'. + + +==== tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts (2 errors) ==== + interface X { x: string } + interface Y { y: number } + interface Z { z?: boolean } + + type XY = X & Y; + const xy: XY = {x: 'x', y: 10}; + + const z1: Z = xy; // error, {xy} doesn't overlap with {z} + ~~ +!!! error TS2559: Type 'XY' has no properties in common with type 'Z'. + + + interface ViewStyle { + view: number + styleMedia: string + } + type Brand = number & { __brand: T } + declare function create(styles: T): { [P in keyof T]: Brand }; + const wrapped = create({ first: { view: 0, styleMedia: "???" } }); + const vs: ViewStyle = wrapped.first // error, first is a branded number + ~~ +!!! error TS2322: Type 'Brand<{ view: number; styleMedia: string; }>' is not assignable to type 'ViewStyle'. +!!! error TS2322: Property 'view' is missing in type 'Number & { __brand: { view: number; styleMedia: string; }; }'. + \ No newline at end of file diff --git a/tests/baselines/reference/intersectionAsWeakTypeSource.js b/tests/baselines/reference/intersectionAsWeakTypeSource.js new file mode 100644 index 00000000000..fefb6f79c2b --- /dev/null +++ b/tests/baselines/reference/intersectionAsWeakTypeSource.js @@ -0,0 +1,26 @@ +//// [intersectionAsWeakTypeSource.ts] +interface X { x: string } +interface Y { y: number } +interface Z { z?: boolean } + +type XY = X & Y; +const xy: XY = {x: 'x', y: 10}; + +const z1: Z = xy; // error, {xy} doesn't overlap with {z} + + +interface ViewStyle { + view: number + styleMedia: string +} +type Brand = number & { __brand: T } +declare function create(styles: T): { [P in keyof T]: Brand }; +const wrapped = create({ first: { view: 0, styleMedia: "???" } }); +const vs: ViewStyle = wrapped.first // error, first is a branded number + + +//// [intersectionAsWeakTypeSource.js] +var xy = { x: 'x', y: 10 }; +var z1 = xy; // error, {xy} doesn't overlap with {z} +var wrapped = create({ first: { view: 0, styleMedia: "???" } }); +var vs = wrapped.first; // error, first is a branded number diff --git a/tests/baselines/reference/intersectionAsWeakTypeSource.symbols b/tests/baselines/reference/intersectionAsWeakTypeSource.symbols new file mode 100644 index 00000000000..78c35abc286 --- /dev/null +++ b/tests/baselines/reference/intersectionAsWeakTypeSource.symbols @@ -0,0 +1,72 @@ +=== tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts === +interface X { x: string } +>X : Symbol(X, Decl(intersectionAsWeakTypeSource.ts, 0, 0)) +>x : Symbol(X.x, Decl(intersectionAsWeakTypeSource.ts, 0, 13)) + +interface Y { y: number } +>Y : Symbol(Y, Decl(intersectionAsWeakTypeSource.ts, 0, 25)) +>y : Symbol(Y.y, Decl(intersectionAsWeakTypeSource.ts, 1, 13)) + +interface Z { z?: boolean } +>Z : Symbol(Z, Decl(intersectionAsWeakTypeSource.ts, 1, 25)) +>z : Symbol(Z.z, Decl(intersectionAsWeakTypeSource.ts, 2, 13)) + +type XY = X & Y; +>XY : Symbol(XY, Decl(intersectionAsWeakTypeSource.ts, 2, 27)) +>X : Symbol(X, Decl(intersectionAsWeakTypeSource.ts, 0, 0)) +>Y : Symbol(Y, Decl(intersectionAsWeakTypeSource.ts, 0, 25)) + +const xy: XY = {x: 'x', y: 10}; +>xy : Symbol(xy, Decl(intersectionAsWeakTypeSource.ts, 5, 5)) +>XY : Symbol(XY, Decl(intersectionAsWeakTypeSource.ts, 2, 27)) +>x : Symbol(x, Decl(intersectionAsWeakTypeSource.ts, 5, 16)) +>y : Symbol(y, Decl(intersectionAsWeakTypeSource.ts, 5, 23)) + +const z1: Z = xy; // error, {xy} doesn't overlap with {z} +>z1 : Symbol(z1, Decl(intersectionAsWeakTypeSource.ts, 7, 5)) +>Z : Symbol(Z, Decl(intersectionAsWeakTypeSource.ts, 1, 25)) +>xy : Symbol(xy, Decl(intersectionAsWeakTypeSource.ts, 5, 5)) + + +interface ViewStyle { +>ViewStyle : Symbol(ViewStyle, Decl(intersectionAsWeakTypeSource.ts, 7, 17)) + + view: number +>view : Symbol(ViewStyle.view, Decl(intersectionAsWeakTypeSource.ts, 10, 21)) + + styleMedia: string +>styleMedia : Symbol(ViewStyle.styleMedia, Decl(intersectionAsWeakTypeSource.ts, 11, 16)) +} +type Brand = number & { __brand: T } +>Brand : Symbol(Brand, Decl(intersectionAsWeakTypeSource.ts, 13, 1)) +>T : Symbol(T, Decl(intersectionAsWeakTypeSource.ts, 14, 11)) +>__brand : Symbol(__brand, Decl(intersectionAsWeakTypeSource.ts, 14, 26)) +>T : Symbol(T, Decl(intersectionAsWeakTypeSource.ts, 14, 11)) + +declare function create(styles: T): { [P in keyof T]: Brand }; +>create : Symbol(create, Decl(intersectionAsWeakTypeSource.ts, 14, 39)) +>T : Symbol(T, Decl(intersectionAsWeakTypeSource.ts, 15, 24)) +>s : Symbol(s, Decl(intersectionAsWeakTypeSource.ts, 15, 37)) +>ViewStyle : Symbol(ViewStyle, Decl(intersectionAsWeakTypeSource.ts, 7, 17)) +>styles : Symbol(styles, Decl(intersectionAsWeakTypeSource.ts, 15, 62)) +>T : Symbol(T, Decl(intersectionAsWeakTypeSource.ts, 15, 24)) +>P : Symbol(P, Decl(intersectionAsWeakTypeSource.ts, 15, 77)) +>T : Symbol(T, Decl(intersectionAsWeakTypeSource.ts, 15, 24)) +>Brand : Symbol(Brand, Decl(intersectionAsWeakTypeSource.ts, 13, 1)) +>T : Symbol(T, Decl(intersectionAsWeakTypeSource.ts, 15, 24)) +>P : Symbol(P, Decl(intersectionAsWeakTypeSource.ts, 15, 77)) + +const wrapped = create({ first: { view: 0, styleMedia: "???" } }); +>wrapped : Symbol(wrapped, Decl(intersectionAsWeakTypeSource.ts, 16, 5)) +>create : Symbol(create, Decl(intersectionAsWeakTypeSource.ts, 14, 39)) +>first : Symbol(first, Decl(intersectionAsWeakTypeSource.ts, 16, 24)) +>view : Symbol(view, Decl(intersectionAsWeakTypeSource.ts, 16, 33)) +>styleMedia : Symbol(styleMedia, Decl(intersectionAsWeakTypeSource.ts, 16, 42)) + +const vs: ViewStyle = wrapped.first // error, first is a branded number +>vs : Symbol(vs, Decl(intersectionAsWeakTypeSource.ts, 17, 5)) +>ViewStyle : Symbol(ViewStyle, Decl(intersectionAsWeakTypeSource.ts, 7, 17)) +>wrapped.first : Symbol(first, Decl(intersectionAsWeakTypeSource.ts, 16, 24)) +>wrapped : Symbol(wrapped, Decl(intersectionAsWeakTypeSource.ts, 16, 5)) +>first : Symbol(first, Decl(intersectionAsWeakTypeSource.ts, 16, 24)) + diff --git a/tests/baselines/reference/intersectionAsWeakTypeSource.types b/tests/baselines/reference/intersectionAsWeakTypeSource.types new file mode 100644 index 00000000000..2362f7c92c1 --- /dev/null +++ b/tests/baselines/reference/intersectionAsWeakTypeSource.types @@ -0,0 +1,60 @@ +=== tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts === +interface X { x: string } +>x : string + +interface Y { y: number } +>y : number + +interface Z { z?: boolean } +>z : boolean + +type XY = X & Y; +>XY : XY + +const xy: XY = {x: 'x', y: 10}; +>xy : XY +>{x: 'x', y: 10} : { x: string; y: number; } +>x : string +>'x' : "x" +>y : number +>10 : 10 + +const z1: Z = xy; // error, {xy} doesn't overlap with {z} +>z1 : Z +>xy : XY + + +interface ViewStyle { + view: number +>view : number + + styleMedia: string +>styleMedia : string +} +type Brand = number & { __brand: T } +>Brand : Brand +>__brand : T + +declare function create(styles: T): { [P in keyof T]: Brand }; +>create : (styles: T) => { [P in keyof T]: Brand; } +>s : string +>styles : T + +const wrapped = create({ first: { view: 0, styleMedia: "???" } }); +>wrapped : { first: Brand<{ view: number; styleMedia: string; }>; } +>create({ first: { view: 0, styleMedia: "???" } }) : { first: Brand<{ view: number; styleMedia: string; }>; } +>create : (styles: T) => { [P in keyof T]: Brand; } +>{ first: { view: 0, styleMedia: "???" } } : { first: { view: number; styleMedia: string; }; } +>first : { view: number; styleMedia: string; } +>{ view: 0, styleMedia: "???" } : { view: number; styleMedia: string; } +>view : number +>0 : 0 +>styleMedia : string +>"???" : "???" + +const vs: ViewStyle = wrapped.first // error, first is a branded number +>vs : ViewStyle +>wrapped.first : Brand<{ view: number; styleMedia: string; }> +>wrapped : { first: Brand<{ view: number; styleMedia: string; }>; } +>first : Brand<{ view: number; styleMedia: string; }> + diff --git a/tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts b/tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts new file mode 100644 index 00000000000..1ebe78b05f5 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionAsWeakTypeSource.ts @@ -0,0 +1,18 @@ +interface X { x: string } +interface Y { y: number } +interface Z { z?: boolean } + +type XY = X & Y; +const xy: XY = {x: 'x', y: 10}; + +const z1: Z = xy; // error, {xy} doesn't overlap with {z} + + +interface ViewStyle { + view: number + styleMedia: string +} +type Brand = number & { __brand: T } +declare function create(styles: T): { [P in keyof T]: Brand }; +const wrapped = create({ first: { view: 0, styleMedia: "???" } }); +const vs: ViewStyle = wrapped.first // error, first is a branded number From 9ef65ef3a4cf550d7231fb55a508f09fb7bfff1d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 24 Aug 2018 13:29:28 -0700 Subject: [PATCH 039/163] Use getSpreadArgumentType when relating to complex rest parameter types --- src/compiler/checker.ts | 198 ++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 97 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 36cf9aa9474..0a32874e525 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7789,8 +7789,12 @@ namespace ts { } function tryGetRestTypeOfSignature(signature: Signature): Type | undefined { - const type = getTypeOfRestParameter(signature); - return type && getIndexTypeOfType(type, IndexKind.Number); + if (signature.hasRestParameter) { + const sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); + const restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType; + return restType && getIndexTypeOfType(restType, IndexKind.Number); + } + return undefined; } function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean): Signature { @@ -10718,9 +10722,9 @@ namespace ts { } const sourceCount = getParameterCount(source); - const sourceGenericRestType = getGenericRestType(source); - const targetGenericRestType = sourceGenericRestType ? getGenericRestType(target) : undefined; - if (sourceGenericRestType && !(targetGenericRestType && sourceCount === targetCount)) { + const sourceRestType = getNonArrayRestType(source); + const targetRestType = sourceRestType ? getNonArrayRestType(target) : undefined; + if (sourceRestType && !(targetRestType && sourceCount === targetCount)) { return Ternary.False; } @@ -10749,8 +10753,8 @@ namespace ts { const paramCount = Math.max(sourceCount, targetCount); const lastIndex = paramCount - 1; for (let i = 0; i < paramCount; i++) { - const sourceType = i === lastIndex && sourceGenericRestType || getTypeAtPosition(source, i); - const targetType = i === lastIndex && targetGenericRestType || getTypeAtPosition(target, i); + const sourceType = i === lastIndex && sourceRestType || getTypeAtPosition(source, i); + const targetType = i === lastIndex && targetRestType || getTypeAtPosition(target, i); // In order to ensure that any generic type Foo is at least co-variant with respect to T no matter // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions, // they naturally relate only contra-variantly). However, if the source and target parameters both have @@ -12693,6 +12697,11 @@ namespace ts { return type.target.hasRestElement ? type.typeArguments![type.target.typeParameters!.length - 1] : undefined; } + function getRestArrayTypeOfTupleType(type: TupleTypeReference) { + const restType = getRestTypeOfTupleType(type); + return restType && createArrayType(restType); + } + function getLengthOfTupleType(type: TupleTypeReference) { return getTypeReferenceArity(type) - (type.target.hasRestElement ? 1 : 0); } @@ -13038,19 +13047,18 @@ namespace ts { function forEachMatchingParameterType(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) { const sourceCount = getParameterCount(source); const targetCount = getParameterCount(target); - const sourceHasRest = hasEffectiveRestParameter(source); - const targetHasRest = hasEffectiveRestParameter(target); - const maxCount = sourceHasRest && targetHasRest ? Math.max(sourceCount, targetCount) : - sourceHasRest ? targetCount : - targetHasRest ? sourceCount : + const sourceRestType = getEffectiveRestType(source); + const targetRestType = getEffectiveRestType(target); + const maxCount = sourceRestType && targetRestType ? Math.max(sourceCount, targetCount) : + sourceRestType ? targetCount : + targetRestType ? sourceCount : Math.min(sourceCount, targetCount); - const targetGenericRestType = getGenericRestType(target); - const paramCount = targetGenericRestType ? Math.min(targetCount - 1, maxCount) : maxCount; + const paramCount = targetRestType ? Math.min(targetCount - 1, maxCount) : maxCount; for (let i = 0; i < paramCount; i++) { callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } - if (targetGenericRestType) { - callback(getRestTypeAtPosition(source, paramCount), targetGenericRestType); + if (targetRestType) { + callback(getRestTypeAtPosition(source, paramCount), targetRestType); } } @@ -13510,32 +13518,37 @@ namespace ts { } function inferFromProperties(source: Type, target: Type) { - if (isTupleType(source) && isTupleType(target)) { - const sourceLength = getLengthOfTupleType(source); - const targetLength = getLengthOfTupleType(target); - const sourceRestType = getRestTypeOfTupleType(source); - const targetRestType = getRestTypeOfTupleType(target); - const fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength; - for (let i = 0; i < fixedLength; i++) { - inferFromTypes(i < sourceLength ? source.typeArguments![i] : sourceRestType!, target.typeArguments![i]); + if (isTupleType(source)) { + if (isTupleType(target)) { + const sourceLength = getLengthOfTupleType(source); + const targetLength = getLengthOfTupleType(target); + const sourceRestType = getRestTypeOfTupleType(source); + const targetRestType = getRestTypeOfTupleType(target); + const fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength; + for (let i = 0; i < fixedLength; i++) { + inferFromTypes(i < sourceLength ? source.typeArguments![i] : sourceRestType!, target.typeArguments![i]); + } + if (targetRestType) { + const types = fixedLength < sourceLength ? source.typeArguments!.slice(fixedLength, sourceLength) : []; + if (sourceRestType) { + types.push(sourceRestType); + } + if (types.length) { + inferFromTypes(getUnionType(types), targetRestType); + } + } + return; } - if (targetRestType) { - const types = fixedLength < sourceLength ? source.typeArguments!.slice(fixedLength, sourceLength) : []; - if (sourceRestType) { - types.push(sourceRestType); - } - if (types.length) { - inferFromTypes(getUnionType(types), targetRestType); - } + if (isArrayType(target)) { + inferFromIndexTypes(source, target); + return; } } - else { - const properties = getPropertiesOfObjectType(target); - for (const targetProp of properties) { - const sourceProp = getPropertyOfType(source, targetProp.escapedName); - if (sourceProp) { - inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); - } + const properties = getPropertiesOfObjectType(target); + for (const targetProp of properties) { + const sourceProp = getPropertyOfType(source, targetProp.escapedName); + if (sourceProp) { + inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); } } } @@ -18679,8 +18692,8 @@ namespace ts { inferTypes(context.inferences, thisArgumentType, thisType); } - const genericRestType = getGenericRestType(signature); - const argCount = genericRestType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length; + const restType = getNonArrayRestType(signature); + const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length; for (let i = 0; i < argCount; i++) { const arg = args[i]; if (arg.kind !== SyntaxKind.OmittedExpression) { @@ -18693,14 +18706,21 @@ namespace ts { } } - if (genericRestType) { - const spreadType = getSpreadArgumentType(args, argCount, args.length, genericRestType, context); - inferTypes(context.inferences, spreadType, genericRestType); + if (restType) { + const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, context); + inferTypes(context.inferences, spreadType, restType); } return getInferredTypes(context); } + function getArrayifiedType(type: Type) { + if (forEachType(type, t => !(t.flags & (TypeFlags.Any | TypeFlags.Instantiable) || isArrayType(t) || isTupleType(t)))) { + return createArrayType(getIndexTypeOfType(type, IndexKind.Number) || errorType); + } + return type; + } + function getSpreadArgumentType(args: ReadonlyArray, index: number, argCount: number, restType: TypeParameter, context: InferenceContext | undefined) { if (index >= argCount - 1) { const arg = args[argCount - 1]; @@ -18709,7 +18729,7 @@ namespace ts { // and the argument are ...x forms. return arg.kind === SyntaxKind.SyntheticExpression ? createArrayType((arg).type) : - checkExpressionWithContextualType((arg).expression, restType, context); + getArrayifiedType(checkExpressionWithContextualType((arg).expression, restType, context)); } } const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType; @@ -18814,28 +18834,27 @@ namespace ts { } } const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; - const restIndex = signature.hasRestParameter ? signature.parameters.length - 1 : -1; - const restType = restIndex >= 0 ? getTypeOfSymbol(signature.parameters[restIndex]) : anyType; - for (let i = 0; i < args.length; i++) { + const restType = getNonArrayRestType(signature); + const argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length; + for (let i = 0; i < argCount; i++) { const arg = args[i]; if (arg.kind !== SyntaxKind.OmittedExpression) { - if (i === restIndex && (restType.flags & TypeFlags.TypeParameter || isSpreadArgument(arg) && !isArrayType(restType))) { - const spreadType = getSpreadArgumentType(args, i, args.length, restType, /*context*/ undefined); - return checkTypeRelatedTo(spreadType, restType, relation, arg, headMessage); - } - else { - const paramType = getTypeAtPosition(signature, i); - const argType = checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined); - // If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter), - // we obtain the regular type of any object literal arguments because we may not have inferred complete - // parameter types yet and therefore excess property checks may yield false positives (see #17041). - const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType; - if (!checkTypeRelatedTo(checkArgType, paramType, relation, reportErrors ? arg : undefined, headMessage)) { - return false; - } + const paramType = getTypeAtPosition(signature, i); + const argType = checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined); + // If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter), + // we obtain the regular type of any object literal arguments because we may not have inferred complete + // parameter types yet and therefore excess property checks may yield false positives (see #17041). + const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType; + if (!checkTypeRelatedTo(checkArgType, paramType, relation, reportErrors ? arg : undefined, headMessage)) { + return false; } } } + if (restType) { + const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined); + const errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined; + return checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage); + } return true; } @@ -19187,7 +19206,7 @@ namespace ts { checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJavaScriptFile(candidate.declaration)); // If the original signature has a generic rest type, instantiation may produce a // signature with different arity and we need to perform another arity check. - if (getGenericRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { + if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { candidateForArgumentArityError = checkCandidate; continue; } @@ -20138,14 +20157,11 @@ namespace ts { function getRestTypeAtPosition(source: Signature, pos: number): Type { const paramCount = getParameterCount(source); - const hasRest = hasEffectiveRestParameter(source); - if (hasRest && pos === paramCount - 1) { - const genericRestType = getGenericRestType(source); - if (genericRestType) { - return genericRestType; - } + const restType = getEffectiveRestType(source); + if (restType && pos === paramCount - 1) { + return restType; } - const start = hasRest ? Math.min(pos, paramCount - 1) : pos; + const start = restType ? Math.min(pos, paramCount - 1) : pos; const types = []; const names = []; for (let i = start; i < paramCount; i++) { @@ -20154,18 +20170,7 @@ namespace ts { } const minArgumentCount = getMinArgumentCount(source); const minLength = minArgumentCount < start ? 0 : minArgumentCount - start; - return createTupleType(types, minLength, hasRest, names); - } - - function getTypeOfRestParameter(signature: Signature) { - if (signature.hasRestParameter) { - const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); - if (isTupleType(restType)) { - return getRestTypeOfTupleType(restType); - } - return restType; - } - return undefined; + return createTupleType(types, minLength, !!restType, names); } function getParameterCount(signature: Signature) { @@ -20192,16 +20197,6 @@ namespace ts { return signature.minArgumentCount; } - function getGenericRestType(signature: Signature) { - if (signature.hasRestParameter) { - const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); - if (restType.flags & TypeFlags.Instantiable) { - return restType; - } - } - return undefined; - } - function hasEffectiveRestParameter(signature: Signature) { if (signature.hasRestParameter) { const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); @@ -20210,6 +20205,19 @@ namespace ts { return false; } + function getEffectiveRestType(signature: Signature) { + if (signature.hasRestParameter) { + const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); + return isTupleType(restType) ? getRestArrayTypeOfTupleType(restType) : restType; + } + return undefined; + } + + function getNonArrayRestType(signature: Signature) { + const restType = getEffectiveRestType(signature); + return restType && !isArrayType(restType) && !isTypeAny(restType) ? restType : undefined; + } + function getTypeOfFirstParameterOfSignature(signature: Signature) { return getTypeOfFirstParameterOfSignatureWithFallback(signature, neverType); } @@ -21889,10 +21897,6 @@ namespace ts { } } - function isRestParameterType(type: Type) { - return isArrayType(type) || isTupleType(type) || type.flags & TypeFlags.Instantiable && isTypeAssignableTo(type, anyArrayType); - } - function checkParameter(node: ParameterDeclaration) { // Grammar checking // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the @@ -21924,7 +21928,7 @@ namespace ts { // Only check rest parameter type if it's not a binding pattern. Since binding patterns are // not allowed in a rest parameter, we already have an error from checkGrammarParameterList. - if (node.dotDotDotToken && !isBindingPattern(node.name) && !isRestParameterType(getTypeOfSymbol(node.symbol))) { + if (node.dotDotDotToken && !isBindingPattern(node.name) && !isTypeAssignableTo(getTypeOfSymbol(node.symbol), anyArrayType)) { error(node, Diagnostics.A_rest_parameter_must_be_of_an_array_type); } } From 4e44b080200ec47ea5accaf51331a0ae73629740 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 24 Aug 2018 13:30:05 -0700 Subject: [PATCH 040/163] Accept new baselines --- ...tructuringParameterDeclaration4.errors.txt | 5 +- .../restParametersOfNonArrayTypes2.errors.txt | 86 +------------------ 2 files changed, 2 insertions(+), 89 deletions(-) diff --git a/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt index d5a0d34e1a1..2af931d352d 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt @@ -1,4 +1,3 @@ -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(13,13): error TS2370: A rest parameter must be of an array type. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(14,17): error TS1047: A rest parameter cannot be optional. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(15,16): error TS1048: A rest parameter cannot have an initializer. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(20,19): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. @@ -16,7 +15,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts( tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(34,28): error TS2304: Cannot find name 'E'. -==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts (11 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts (10 errors) ==== // If the parameter is a rest parameter, the parameter type is any[] // A type annotation for a rest parameter must denote an array type. @@ -30,8 +29,6 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts( function a0(...x: [number, number, string]) { } // Error, rest parameter must be array type function a1(...x: (number|string)[]) { } function a2(...a: someArray) { } // Error, rest parameter must be array type - ~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. function a3(...b?) { } // Error, can't be optional ~ !!! error TS1047: A rest parameter cannot be optional. diff --git a/tests/baselines/reference/restParametersOfNonArrayTypes2.errors.txt b/tests/baselines/reference/restParametersOfNonArrayTypes2.errors.txt index 654f053e8bb..5c31031cba4 100644 --- a/tests/baselines/reference/restParametersOfNonArrayTypes2.errors.txt +++ b/tests/baselines/reference/restParametersOfNonArrayTypes2.errors.txt @@ -1,40 +1,12 @@ -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(7,14): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(8,22): error TS2370: A rest parameter must be of an array type. tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(9,11): error TS1014: A rest parameter must be last in a parameter list. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(9,11): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(9,26): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(12,9): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(16,6): error TS2370: A rest parameter must be of an array type. tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(17,9): error TS1014: A rest parameter must be last in a parameter list. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(17,9): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(17,24): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(21,6): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(22,9): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(26,9): error TS2370: A rest parameter must be of an array type. tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(27,21): error TS1014: A rest parameter must be last in a parameter list. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(27,21): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(27,36): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(28,9): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(34,15): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(35,23): error TS2370: A rest parameter must be of an array type. tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(36,11): error TS1014: A rest parameter must be last in a parameter list. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(36,11): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(36,35): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(39,9): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(43,6): error TS2370: A rest parameter must be of an array type. tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(44,9): error TS1014: A rest parameter must be last in a parameter list. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(44,9): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(44,33): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(48,6): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(49,9): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(53,9): error TS2370: A rest parameter must be of an array type. tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(54,21): error TS1014: A rest parameter must be last in a parameter list. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(54,21): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(54,45): error TS2370: A rest parameter must be of an array type. -tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts(55,9): error TS2370: A rest parameter must be of an array type. -==== tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts (34 errors) ==== +==== tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfNonArrayTypes2.ts (6 errors) ==== // Rest parameters must be an array type if they have a type annotation, // user defined subtypes of array do not count, all of these are errors @@ -42,120 +14,64 @@ tests/cases/conformance/types/objectTypeLiteral/callSignatures/restParametersOfN interface MyThing2 extends Array { } function foo(...x: MyThing) { } - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. var f = function foo(...x: MyThing) { } - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. var f2 = (...x: MyThing, ...y: MyThing) => { } ~~~ !!! error TS1014: A rest parameter must be last in a parameter list. - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. class C { foo(...x: MyThing) { } - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. } interface I { (...x: MyThing); - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. foo(...x: MyThing, ...y: MyThing); ~~~ !!! error TS1014: A rest parameter must be last in a parameter list. - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. } var a: { (...x: MyThing); - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. foo(...x: MyThing); - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. } var b = { foo(...x: MyThing) { }, - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. a: function foo(...x: MyThing, ...y: MyThing) { }, ~~~ !!! error TS1014: A rest parameter must be last in a parameter list. - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. b: (...x: MyThing) => { } - ~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. } function foo2(...x: MyThing2) { } - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. var f3 = function foo(...x: MyThing2) { } - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. var f4 = (...x: MyThing2, ...y: MyThing2) => { } ~~~ !!! error TS1014: A rest parameter must be last in a parameter list. - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. class C2 { foo(...x: MyThing2) { } - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. } interface I2 { (...x: MyThing2); - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. foo(...x: MyThing2, ...y: MyThing2); ~~~ !!! error TS1014: A rest parameter must be last in a parameter list. - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. } var a2: { (...x: MyThing2); - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. foo(...x: MyThing2); - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. } var b2 = { foo(...x: MyThing2) { }, - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. a: function foo(...x: MyThing2, ...y: MyThing2) { }, ~~~ !!! error TS1014: A rest parameter must be last in a parameter list. - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. b: (...x: MyThing2) => { } - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2370: A rest parameter must be of an array type. } \ No newline at end of file From f5f61335ee655675f33e6b7238f9c160036d0eb6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 07:29:15 -0700 Subject: [PATCH 041/163] Revise complex rest parameter handling in relations and inference --- src/compiler/checker.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0a32874e525..39e1ab5e526 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10723,8 +10723,9 @@ namespace ts { const sourceCount = getParameterCount(source); const sourceRestType = getNonArrayRestType(source); - const targetRestType = sourceRestType ? getNonArrayRestType(target) : undefined; - if (sourceRestType && !(targetRestType && sourceCount === targetCount)) { + const targetRestType = getNonArrayRestType(target); + if (sourceRestType && targetRestType && sourceCount !== targetCount) { + // We're not able to relate misaliged complex rest parameters return Ternary.False; } @@ -10750,11 +10751,12 @@ namespace ts { } } - const paramCount = Math.max(sourceCount, targetCount); - const lastIndex = paramCount - 1; + const paramCount = sourceRestType || targetRestType ? Math.min(sourceCount, targetCount) : Math.max(sourceCount, targetCount); + const restIndex = sourceRestType || targetRestType ? paramCount - 1 : -1; + for (let i = 0; i < paramCount; i++) { - const sourceType = i === lastIndex && sourceRestType || getTypeAtPosition(source, i); - const targetType = i === lastIndex && targetRestType || getTypeAtPosition(target, i); + const sourceType = i === restIndex ? getRestTypeAtPosition(source, i) : getTypeAtPosition(source, i); + const targetType = i === restIndex ? getRestTypeAtPosition(target, i) : getTypeAtPosition(target, i); // In order to ensure that any generic type Foo is at least co-variant with respect to T no matter // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions, // they naturally relate only contra-variantly). However, if the source and target parameters both have @@ -13049,11 +13051,9 @@ namespace ts { const targetCount = getParameterCount(target); const sourceRestType = getEffectiveRestType(source); const targetRestType = getEffectiveRestType(target); - const maxCount = sourceRestType && targetRestType ? Math.max(sourceCount, targetCount) : + const paramCount = targetRestType ? Math.min(targetCount - 1, sourceCount) : sourceRestType ? targetCount : - targetRestType ? sourceCount : Math.min(sourceCount, targetCount); - const paramCount = targetRestType ? Math.min(targetCount - 1, maxCount) : maxCount; for (let i = 0; i < paramCount; i++) { callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } From 0e1b99842c3a35e6e113253e2e3cfe9ce6ee60bc Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 07:29:34 -0700 Subject: [PATCH 042/163] Accept new baselines --- .../restTuplesFromContextualTypes.errors.txt | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/baselines/reference/restTuplesFromContextualTypes.errors.txt diff --git a/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt b/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt new file mode 100644 index 00000000000..7495095d074 --- /dev/null +++ b/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt @@ -0,0 +1,84 @@ +tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error TS2345: Argument of type '(a: number, b: any, ...x: any[]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'. + Types of parameters 'b' and 'args' are incompatible. + Type 'T' is not assignable to type '[any, ...any[]]'. + Type 'any[]' is not assignable to type '[any, ...any[]]'. + Property '0' is missing in type 'any[]'. + + +==== tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts (1 errors) ==== + declare const t1: [number, boolean, string]; + + (function (a, b, c){})(...t1); + (function (...x){})(...t1); + (function (a, ...x){})(...t1); + (function (a, b, ...x){})(...t1); + (function (a, b, c, ...x){})(...t1); + + declare function f1(cb: (...args: typeof t1) => void): void; + + f1((a, b, c) => {}) + f1((...x) => {}) + f1((a, ...x) => {}) + f1((a, b, ...x) => {}) + f1((a, b, c, ...x) => {}) + + declare const t2: [number, boolean, ...string[]]; + + (function (a, b, c){})(...t2); + (function (...x){})(...t2); + (function (a, ...x){})(...t2); + (function (a, b, ...x){})(...t2); + (function (a, b, c, ...x){})(...t2); + + declare function f2(cb: (...args: typeof t2) => void): void; + + f2((a, b, c) => {}) + f2((...x) => {}) + f2((a, ...x) => {}) + f2((a, b, ...x) => {}) + f2((a, b, c, ...x) => {}) + + declare const t3: [boolean, ...string[]]; + + (function (a, b, c){})(1, ...t3); + (function (...x){})(1, ...t3); + (function (a, ...x){})(1, ...t3); + (function (a, b, ...x){})(1, ...t3); + (function (a, b, c, ...x){})(1, ...t3); + + declare function f3(cb: (x: number, ...args: typeof t3) => void): void; + + f3((a, b, c) => {}) + f3((...x) => {}) + f3((a, ...x) => {}) + f3((a, b, ...x) => {}) + f3((a, b, c, ...x) => {}) + + function f4(t: T) { + (function(...x){})(...t); + (function(a, ...x){})(1, ...t); + (function(a, ...x){})(1, 2, ...t); + function f(cb: (x: number, ...args: T) => void) {} + f((...x) => {}); + f((a, ...x) => {}); + f((a, b, ...x) => {}); + ~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(a: number, b: any, ...x: any[]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'. +!!! error TS2345: Types of parameters 'b' and 'args' are incompatible. +!!! error TS2345: Type 'T' is not assignable to type '[any, ...any[]]'. +!!! error TS2345: Type 'any[]' is not assignable to type '[any, ...any[]]'. +!!! error TS2345: Property '0' is missing in type 'any[]'. + } + + // Repro from #25288 + + declare var tuple: [number, string]; + (function foo(a, b){}(...tuple)); + + // Repro from #25289 + + declare function take(cb: (a: number, b: string) => void): void; + + (function foo(...rest){}(1, '')); + take(function(...rest){}); + \ No newline at end of file From 676892ee56ef5804ea018ab217f1d4d1399bf4ef Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 07:55:13 -0700 Subject: [PATCH 043/163] Add tests --- .../types/rest/genericRestParameters3.ts | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 tests/cases/conformance/types/rest/genericRestParameters3.ts diff --git a/tests/cases/conformance/types/rest/genericRestParameters3.ts b/tests/cases/conformance/types/rest/genericRestParameters3.ts new file mode 100644 index 00000000000..e2e2a3a3fba --- /dev/null +++ b/tests/cases/conformance/types/rest/genericRestParameters3.ts @@ -0,0 +1,56 @@ +// @strict: true +// @declaration: true + +declare let f1: (x: string, ...args: [string] | [number, boolean]) => void; +declare let f2: (x: string, y: string) => void; +declare let f3: (x: string, y: number, z: boolean) => void; +declare let f4: (...args: [string, string] | [string, number, boolean]) => void; + +declare const tt: [string] | [number, boolean]; + +f1("foo", "abc"); +f1("foo", 10, true); +f1("foo", ...tt); +f1("foo", 10); // Error +f1("foo"); // Error + +f2 = f1; +f3 = f1; +f4 = f1; // Error, misaligned complex rest types +f1 = f2; // Error +f1 = f3; // Error +f1 = f4; // Error, misaligned complex rest types + +// Repro from #26110 + +interface CoolArray extends Array { + hello: number; +} + +declare function foo(cb: (...args: T) => void): void; + +foo>(); // Error +foo>(100); // Error +foo>(foo); // Error + +function bar(...args: T): T { + return args; +} + +let a = bar(10, 20); +let b = bar>(10, 20); // Error + +declare function baz(...args: CoolArray): void; +declare const ca: CoolArray; + +baz(); // Error +baz(1); // Error +baz(1, 2); // Error +baz(...ca); // Error + +// Repro from #26491 + +declare function hmm(...args: A): void; +hmm(); // okay, A = [] +hmm(1, "s"); // okay, A = [1, "s"] +hmm("what"); // no error? A = [] | [number, string] ? From 349bee92a34cf3550ae594213ad1eefabfb2f3df Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 07:55:21 -0700 Subject: [PATCH 044/163] Accept new baselines --- .../genericRestParameters3.errors.txt | 148 ++++++++++++++ .../reference/genericRestParameters3.js | 106 ++++++++++ .../reference/genericRestParameters3.symbols | 157 +++++++++++++++ .../reference/genericRestParameters3.types | 182 ++++++++++++++++++ 4 files changed, 593 insertions(+) create mode 100644 tests/baselines/reference/genericRestParameters3.errors.txt create mode 100644 tests/baselines/reference/genericRestParameters3.js create mode 100644 tests/baselines/reference/genericRestParameters3.symbols create mode 100644 tests/baselines/reference/genericRestParameters3.types diff --git a/tests/baselines/reference/genericRestParameters3.errors.txt b/tests/baselines/reference/genericRestParameters3.errors.txt new file mode 100644 index 00000000000..1f028153397 --- /dev/null +++ b/tests/baselines/reference/genericRestParameters3.errors.txt @@ -0,0 +1,148 @@ +tests/cases/conformance/types/rest/genericRestParameters3.ts(11,11): error TS2345: Argument of type '[10]' is not assignable to parameter of type '[string] | [number, boolean]'. + Type '[10]' is not assignable to type '[string]'. + Type '10' is not assignable to type 'string'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(12,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'. + Type '[]' is not assignable to type '[number, boolean]'. + Property '0' is missing in type '[]'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(16,1): error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(17,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. + Types of parameters 'y' and 'args' are incompatible. + Type '[string] | [number, boolean]' is not assignable to type '[string]'. + Type '[number, boolean]' is not assignable to type '[string]'. + Types of property '0' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. + Types of parameters 'y' and 'args' are incompatible. + Type '[string] | [number, boolean]' is not assignable to type '[number, boolean]'. + Type '[string]' is not assignable to type '[number, boolean]'. + Property '1' is missing in type '[string]'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(19,1): error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(29,1): error TS2554: Expected 1 arguments, but got 0. +tests/cases/conformance/types/rest/genericRestParameters3.ts(30,21): error TS2345: Argument of type '100' is not assignable to parameter of type '(...args: CoolArray) => void'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(31,21): error TS2345: Argument of type '(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray) => void'. + Types of parameters 'cb' and 'args' are incompatible. + Type 'CoolArray' is not assignable to type '[(...args: any[]) => void]'. + Property '0' is missing in type 'CoolArray'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(38,32): error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray'. + Property 'hello' is missing in type '[10, 20]'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(43,1): error TS2345: Argument of type '[]' is not assignable to parameter of type 'CoolArray'. + Property 'hello' is missing in type '[]'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(44,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type 'CoolArray<{}>'. + Property 'hello' is missing in type '[number]'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(45,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type 'CoolArray<{}>'. + Property 'hello' is missing in type '[number, number]'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(46,5): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'CoolArray'. + Property 'hello' is missing in type 'number[]'. +tests/cases/conformance/types/rest/genericRestParameters3.ts(53,5): error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'. + Type '["what"]' is not assignable to type '[number, string]'. + Property '1' is missing in type '["what"]'. + + +==== tests/cases/conformance/types/rest/genericRestParameters3.ts (15 errors) ==== + declare let f1: (x: string, ...args: [string] | [number, boolean]) => void; + declare let f2: (x: string, y: string) => void; + declare let f3: (x: string, y: number, z: boolean) => void; + declare let f4: (...args: [string, string] | [string, number, boolean]) => void; + + declare const tt: [string] | [number, boolean]; + + f1("foo", "abc"); + f1("foo", 10, true); + f1("foo", ...tt); + f1("foo", 10); // Error + ~~ +!!! error TS2345: Argument of type '[10]' is not assignable to parameter of type '[string] | [number, boolean]'. +!!! error TS2345: Type '[10]' is not assignable to type '[string]'. +!!! error TS2345: Type '10' is not assignable to type 'string'. + f1("foo"); // Error + ~~~~~~~~~ +!!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'. +!!! error TS2345: Type '[]' is not assignable to type '[number, boolean]'. +!!! error TS2345: Property '0' is missing in type '[]'. + + f2 = f1; + f3 = f1; + f4 = f1; // Error, misaligned complex rest types + ~~ +!!! error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'. + f1 = f2; // Error + ~~ +!!! error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. +!!! error TS2322: Types of parameters 'y' and 'args' are incompatible. +!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[string]'. +!!! error TS2322: Type '[number, boolean]' is not assignable to type '[string]'. +!!! error TS2322: Types of property '0' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + f1 = f3; // Error + ~~ +!!! error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. +!!! error TS2322: Types of parameters 'y' and 'args' are incompatible. +!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[number, boolean]'. +!!! error TS2322: Type '[string]' is not assignable to type '[number, boolean]'. +!!! error TS2322: Property '1' is missing in type '[string]'. + f1 = f4; // Error, misaligned complex rest types + ~~ +!!! error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. + + // Repro from #26110 + + interface CoolArray extends Array { + hello: number; + } + + declare function foo(cb: (...args: T) => void): void; + + foo>(); // Error + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2554: Expected 1 arguments, but got 0. + foo>(100); // Error + ~~~ +!!! error TS2345: Argument of type '100' is not assignable to parameter of type '(...args: CoolArray) => void'. + foo>(foo); // Error + ~~~ +!!! error TS2345: Argument of type '(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray) => void'. +!!! error TS2345: Types of parameters 'cb' and 'args' are incompatible. +!!! error TS2345: Type 'CoolArray' is not assignable to type '[(...args: any[]) => void]'. +!!! error TS2345: Property '0' is missing in type 'CoolArray'. + + function bar(...args: T): T { + return args; + } + + let a = bar(10, 20); + let b = bar>(10, 20); // Error + ~~ +!!! error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray'. +!!! error TS2345: Property 'hello' is missing in type '[10, 20]'. + + declare function baz(...args: CoolArray): void; + declare const ca: CoolArray; + + baz(); // Error + ~~~~~ +!!! error TS2345: Argument of type '[]' is not assignable to parameter of type 'CoolArray'. +!!! error TS2345: Property 'hello' is missing in type '[]'. + baz(1); // Error + ~ +!!! error TS2345: Argument of type '[number]' is not assignable to parameter of type 'CoolArray<{}>'. +!!! error TS2345: Property 'hello' is missing in type '[number]'. + baz(1, 2); // Error + ~ +!!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type 'CoolArray<{}>'. +!!! error TS2345: Property 'hello' is missing in type '[number, number]'. + baz(...ca); // Error + ~~~~~ +!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'CoolArray'. +!!! error TS2345: Property 'hello' is missing in type 'number[]'. + + // Repro from #26491 + + declare function hmm(...args: A): void; + hmm(); // okay, A = [] + hmm(1, "s"); // okay, A = [1, "s"] + hmm("what"); // no error? A = [] | [number, string] ? + ~~~~~~ +!!! error TS2345: Argument of type '["what"]' is not assignable to parameter of type '[] | [number, string]'. +!!! error TS2345: Type '["what"]' is not assignable to type '[number, string]'. +!!! error TS2345: Property '1' is missing in type '["what"]'. + \ No newline at end of file diff --git a/tests/baselines/reference/genericRestParameters3.js b/tests/baselines/reference/genericRestParameters3.js new file mode 100644 index 00000000000..132edcbefb6 --- /dev/null +++ b/tests/baselines/reference/genericRestParameters3.js @@ -0,0 +1,106 @@ +//// [genericRestParameters3.ts] +declare let f1: (x: string, ...args: [string] | [number, boolean]) => void; +declare let f2: (x: string, y: string) => void; +declare let f3: (x: string, y: number, z: boolean) => void; +declare let f4: (...args: [string, string] | [string, number, boolean]) => void; + +declare const tt: [string] | [number, boolean]; + +f1("foo", "abc"); +f1("foo", 10, true); +f1("foo", ...tt); +f1("foo", 10); // Error +f1("foo"); // Error + +f2 = f1; +f3 = f1; +f4 = f1; // Error, misaligned complex rest types +f1 = f2; // Error +f1 = f3; // Error +f1 = f4; // Error, misaligned complex rest types + +// Repro from #26110 + +interface CoolArray extends Array { + hello: number; +} + +declare function foo(cb: (...args: T) => void): void; + +foo>(); // Error +foo>(100); // Error +foo>(foo); // Error + +function bar(...args: T): T { + return args; +} + +let a = bar(10, 20); +let b = bar>(10, 20); // Error + +declare function baz(...args: CoolArray): void; +declare const ca: CoolArray; + +baz(); // Error +baz(1); // Error +baz(1, 2); // Error +baz(...ca); // Error + +// Repro from #26491 + +declare function hmm(...args: A): void; +hmm(); // okay, A = [] +hmm(1, "s"); // okay, A = [1, "s"] +hmm("what"); // no error? A = [] | [number, string] ? + + +//// [genericRestParameters3.js] +"use strict"; +f1("foo", "abc"); +f1("foo", 10, true); +f1.apply(void 0, ["foo"].concat(tt)); +f1("foo", 10); // Error +f1("foo"); // Error +f2 = f1; +f3 = f1; +f4 = f1; // Error, misaligned complex rest types +f1 = f2; // Error +f1 = f3; // Error +f1 = f4; // Error, misaligned complex rest types +foo(); // Error +foo(100); // Error +foo(foo); // Error +function bar() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return args; +} +var a = bar(10, 20); +var b = bar(10, 20); // Error +baz(); // Error +baz(1); // Error +baz(1, 2); // Error +baz.apply(void 0, ca); // Error +hmm(); // okay, A = [] +hmm(1, "s"); // okay, A = [1, "s"] +hmm("what"); // no error? A = [] | [number, string] ? + + +//// [genericRestParameters3.d.ts] +declare let f1: (x: string, ...args: [string] | [number, boolean]) => void; +declare let f2: (x: string, y: string) => void; +declare let f3: (x: string, y: number, z: boolean) => void; +declare let f4: (...args: [string, string] | [string, number, boolean]) => void; +declare const tt: [string] | [number, boolean]; +interface CoolArray extends Array { + hello: number; +} +declare function foo(cb: (...args: T) => void): void; +declare function bar(...args: T): T; +declare let a: [number, number]; +declare let b: any; +declare function baz(...args: CoolArray): void; +declare const ca: CoolArray; +declare function hmm(...args: A): void; diff --git a/tests/baselines/reference/genericRestParameters3.symbols b/tests/baselines/reference/genericRestParameters3.symbols new file mode 100644 index 00000000000..a768f205b57 --- /dev/null +++ b/tests/baselines/reference/genericRestParameters3.symbols @@ -0,0 +1,157 @@ +=== tests/cases/conformance/types/rest/genericRestParameters3.ts === +declare let f1: (x: string, ...args: [string] | [number, boolean]) => void; +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) +>x : Symbol(x, Decl(genericRestParameters3.ts, 0, 17)) +>args : Symbol(args, Decl(genericRestParameters3.ts, 0, 27)) + +declare let f2: (x: string, y: string) => void; +>f2 : Symbol(f2, Decl(genericRestParameters3.ts, 1, 11)) +>x : Symbol(x, Decl(genericRestParameters3.ts, 1, 17)) +>y : Symbol(y, Decl(genericRestParameters3.ts, 1, 27)) + +declare let f3: (x: string, y: number, z: boolean) => void; +>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11)) +>x : Symbol(x, Decl(genericRestParameters3.ts, 2, 17)) +>y : Symbol(y, Decl(genericRestParameters3.ts, 2, 27)) +>z : Symbol(z, Decl(genericRestParameters3.ts, 2, 38)) + +declare let f4: (...args: [string, string] | [string, number, boolean]) => void; +>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11)) +>args : Symbol(args, Decl(genericRestParameters3.ts, 3, 17)) + +declare const tt: [string] | [number, boolean]; +>tt : Symbol(tt, Decl(genericRestParameters3.ts, 5, 13)) + +f1("foo", "abc"); +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) + +f1("foo", 10, true); +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) + +f1("foo", ...tt); +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) +>tt : Symbol(tt, Decl(genericRestParameters3.ts, 5, 13)) + +f1("foo", 10); // Error +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) + +f1("foo"); // Error +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) + +f2 = f1; +>f2 : Symbol(f2, Decl(genericRestParameters3.ts, 1, 11)) +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) + +f3 = f1; +>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11)) +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) + +f4 = f1; // Error, misaligned complex rest types +>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11)) +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) + +f1 = f2; // Error +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) +>f2 : Symbol(f2, Decl(genericRestParameters3.ts, 1, 11)) + +f1 = f3; // Error +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) +>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11)) + +f1 = f4; // Error, misaligned complex rest types +>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) +>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11)) + +// Repro from #26110 + +interface CoolArray extends Array { +>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8)) +>E : Symbol(E, Decl(genericRestParameters3.ts, 22, 20)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>E : Symbol(E, Decl(genericRestParameters3.ts, 22, 20)) + + hello: number; +>hello : Symbol(CoolArray.hello, Decl(genericRestParameters3.ts, 22, 41)) +} + +declare function foo(cb: (...args: T) => void): void; +>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1)) +>T : Symbol(T, Decl(genericRestParameters3.ts, 26, 21)) +>cb : Symbol(cb, Decl(genericRestParameters3.ts, 26, 38)) +>args : Symbol(args, Decl(genericRestParameters3.ts, 26, 43)) +>T : Symbol(T, Decl(genericRestParameters3.ts, 26, 21)) + +foo>(); // Error +>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1)) +>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8)) + +foo>(100); // Error +>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1)) +>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8)) + +foo>(foo); // Error +>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1)) +>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8)) +>foo : Symbol(foo, Decl(genericRestParameters3.ts, 24, 1)) + +function bar(...args: T): T { +>bar : Symbol(bar, Decl(genericRestParameters3.ts, 30, 25)) +>T : Symbol(T, Decl(genericRestParameters3.ts, 32, 13)) +>args : Symbol(args, Decl(genericRestParameters3.ts, 32, 30)) +>T : Symbol(T, Decl(genericRestParameters3.ts, 32, 13)) +>T : Symbol(T, Decl(genericRestParameters3.ts, 32, 13)) + + return args; +>args : Symbol(args, Decl(genericRestParameters3.ts, 32, 30)) +} + +let a = bar(10, 20); +>a : Symbol(a, Decl(genericRestParameters3.ts, 36, 3)) +>bar : Symbol(bar, Decl(genericRestParameters3.ts, 30, 25)) + +let b = bar>(10, 20); // Error +>b : Symbol(b, Decl(genericRestParameters3.ts, 37, 3)) +>bar : Symbol(bar, Decl(genericRestParameters3.ts, 30, 25)) +>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8)) + +declare function baz(...args: CoolArray): void; +>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39)) +>T : Symbol(T, Decl(genericRestParameters3.ts, 39, 21)) +>args : Symbol(args, Decl(genericRestParameters3.ts, 39, 24)) +>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8)) +>T : Symbol(T, Decl(genericRestParameters3.ts, 39, 21)) + +declare const ca: CoolArray; +>ca : Symbol(ca, Decl(genericRestParameters3.ts, 40, 13)) +>CoolArray : Symbol(CoolArray, Decl(genericRestParameters3.ts, 18, 8)) + +baz(); // Error +>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39)) + +baz(1); // Error +>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39)) + +baz(1, 2); // Error +>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39)) + +baz(...ca); // Error +>baz : Symbol(baz, Decl(genericRestParameters3.ts, 37, 39)) +>ca : Symbol(ca, Decl(genericRestParameters3.ts, 40, 13)) + +// Repro from #26491 + +declare function hmm(...args: A): void; +>hmm : Symbol(hmm, Decl(genericRestParameters3.ts, 45, 11)) +>A : Symbol(A, Decl(genericRestParameters3.ts, 49, 21)) +>args : Symbol(args, Decl(genericRestParameters3.ts, 49, 54)) +>A : Symbol(A, Decl(genericRestParameters3.ts, 49, 21)) + +hmm(); // okay, A = [] +>hmm : Symbol(hmm, Decl(genericRestParameters3.ts, 45, 11)) + +hmm(1, "s"); // okay, A = [1, "s"] +>hmm : Symbol(hmm, Decl(genericRestParameters3.ts, 45, 11)) + +hmm("what"); // no error? A = [] | [number, string] ? +>hmm : Symbol(hmm, Decl(genericRestParameters3.ts, 45, 11)) + diff --git a/tests/baselines/reference/genericRestParameters3.types b/tests/baselines/reference/genericRestParameters3.types new file mode 100644 index 00000000000..8d8d145a44f --- /dev/null +++ b/tests/baselines/reference/genericRestParameters3.types @@ -0,0 +1,182 @@ +=== tests/cases/conformance/types/rest/genericRestParameters3.ts === +declare let f1: (x: string, ...args: [string] | [number, boolean]) => void; +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>x : string +>args : [string] | [number, boolean] + +declare let f2: (x: string, y: string) => void; +>f2 : (x: string, y: string) => void +>x : string +>y : string + +declare let f3: (x: string, y: number, z: boolean) => void; +>f3 : (x: string, y: number, z: boolean) => void +>x : string +>y : number +>z : boolean + +declare let f4: (...args: [string, string] | [string, number, boolean]) => void; +>f4 : (...args: [string, string] | [string, number, boolean]) => void +>args : [string, string] | [string, number, boolean] + +declare const tt: [string] | [number, boolean]; +>tt : [string] | [number, boolean] + +f1("foo", "abc"); +>f1("foo", "abc") : void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>"foo" : "foo" +>"abc" : "abc" + +f1("foo", 10, true); +>f1("foo", 10, true) : void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>"foo" : "foo" +>10 : 10 +>true : true + +f1("foo", ...tt); +>f1("foo", ...tt) : void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>"foo" : "foo" +>...tt : string | number | boolean +>tt : [string] | [number, boolean] + +f1("foo", 10); // Error +>f1("foo", 10) : void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>"foo" : "foo" +>10 : 10 + +f1("foo"); // Error +>f1("foo") : void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>"foo" : "foo" + +f2 = f1; +>f2 = f1 : (x: string, ...args: [string] | [number, boolean]) => void +>f2 : (x: string, y: string) => void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void + +f3 = f1; +>f3 = f1 : (x: string, ...args: [string] | [number, boolean]) => void +>f3 : (x: string, y: number, z: boolean) => void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void + +f4 = f1; // Error, misaligned complex rest types +>f4 = f1 : (x: string, ...args: [string] | [number, boolean]) => void +>f4 : (...args: [string, string] | [string, number, boolean]) => void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void + +f1 = f2; // Error +>f1 = f2 : (x: string, y: string) => void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>f2 : (x: string, y: string) => void + +f1 = f3; // Error +>f1 = f3 : (x: string, y: number, z: boolean) => void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>f3 : (x: string, y: number, z: boolean) => void + +f1 = f4; // Error, misaligned complex rest types +>f1 = f4 : (...args: [string, string] | [string, number, boolean]) => void +>f1 : (x: string, ...args: [string] | [number, boolean]) => void +>f4 : (...args: [string, string] | [string, number, boolean]) => void + +// Repro from #26110 + +interface CoolArray extends Array { + hello: number; +>hello : number +} + +declare function foo(cb: (...args: T) => void): void; +>foo : (cb: (...args: T) => void) => void +>cb : (...args: T) => void +>args : T + +foo>(); // Error +>foo>() : any +>foo : (cb: (...args: T) => void) => void + +foo>(100); // Error +>foo>(100) : any +>foo : (cb: (...args: T) => void) => void +>100 : 100 + +foo>(foo); // Error +>foo>(foo) : any +>foo : (cb: (...args: T) => void) => void +>foo : (cb: (...args: T) => void) => void + +function bar(...args: T): T { +>bar : (...args: T) => T +>args : T + + return args; +>args : T +} + +let a = bar(10, 20); +>a : [number, number] +>bar(10, 20) : [number, number] +>bar : (...args: T) => T +>10 : 10 +>20 : 20 + +let b = bar>(10, 20); // Error +>b : any +>bar>(10, 20) : any +>bar : (...args: T) => T +>10 : 10 +>20 : 20 + +declare function baz(...args: CoolArray): void; +>baz : (...args: CoolArray) => void +>args : CoolArray + +declare const ca: CoolArray; +>ca : CoolArray + +baz(); // Error +>baz() : any +>baz : (...args: CoolArray) => void + +baz(1); // Error +>baz(1) : any +>baz : (...args: CoolArray) => void +>1 : 1 + +baz(1, 2); // Error +>baz(1, 2) : any +>baz : (...args: CoolArray) => void +>1 : 1 +>2 : 2 + +baz(...ca); // Error +>baz(...ca) : any +>baz : (...args: CoolArray) => void +>...ca : number +>ca : CoolArray + +// Repro from #26491 + +declare function hmm(...args: A): void; +>hmm : (...args: A) => void +>args : A + +hmm(); // okay, A = [] +>hmm() : void +>hmm : (...args: A) => void + +hmm(1, "s"); // okay, A = [1, "s"] +>hmm(1, "s") : void +>hmm : (...args: A) => void +>1 : 1 +>"s" : "s" + +hmm("what"); // no error? A = [] | [number, string] ? +>hmm("what") : any +>hmm : (...args: A) => void +>"what" : "what" + From 3ec2c45f5fa68ed53b723bb9d20bd3e2bd607d95 Mon Sep 17 00:00:00 2001 From: Nathan Day Date: Wed, 15 Aug 2018 01:08:13 -0400 Subject: [PATCH 045/163] include leading non-ASCII horizontal whitespace in SyntaxKind.WhitespaceTrivia token --- src/compiler/scanner.ts | 18 ++++++++++++++++++ .../scannerNonAsciiHorizontalWhitespace.js | 14 ++++++++++++++ ...scannerNonAsciiHorizontalWhitespace.symbols | 9 +++++++++ .../scannerNonAsciiHorizontalWhitespace.types | 10 ++++++++++ .../scannerNonAsciiHorizontalWhitespace.ts | 6 ++++++ 5 files changed, 57 insertions(+) create mode 100644 tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.js create mode 100644 tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.symbols create mode 100644 tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.types create mode 100644 tests/cases/conformance/scanner/ecmascript5/scannerNonAsciiHorizontalWhitespace.ts diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index af74d69ceef..376c18b7205 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -1390,6 +1390,24 @@ namespace ts { case CharacterCodes.verticalTab: case CharacterCodes.formFeed: case CharacterCodes.space: + case CharacterCodes.nonBreakingSpace: + case CharacterCodes.ogham: + case CharacterCodes.enQuad: + case CharacterCodes.emQuad: + case CharacterCodes.enSpace: + case CharacterCodes.emSpace: + case CharacterCodes.threePerEmSpace: + case CharacterCodes.fourPerEmSpace: + case CharacterCodes.sixPerEmSpace: + case CharacterCodes.figureSpace: + case CharacterCodes.punctuationSpace: + case CharacterCodes.thinSpace: + case CharacterCodes.hairSpace: + case CharacterCodes.zeroWidthSpace: + case CharacterCodes.narrowNoBreakSpace: + case CharacterCodes.mathematicalSpace: + case CharacterCodes.ideographicSpace: + case CharacterCodes.byteOrderMark: if (skipTrivia) { pos++; continue; diff --git a/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.js b/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.js new file mode 100644 index 00000000000..b9ae124f1ef --- /dev/null +++ b/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.js @@ -0,0 +1,14 @@ +//// [scannerNonAsciiHorizontalWhitespace.ts] +//// [scannerNonAsciiHorizontalWhitespace.ts] +"  function f() {}" + +//// [scannerNonAsciiHorizontalWhitespace.js] +"  function f() {}" + + + +//// [scannerNonAsciiHorizontalWhitespace.js] +//// [scannerNonAsciiHorizontalWhitespace.ts] +"  function f() {}"; +//// [scannerNonAsciiHorizontalWhitespace.js] +"  function f() {}"; diff --git a/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.symbols b/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.symbols new file mode 100644 index 00000000000..8a7fdec1d33 --- /dev/null +++ b/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/scanner/ecmascript5/scannerNonAsciiHorizontalWhitespace.ts === +//// [scannerNonAsciiHorizontalWhitespace.ts] +No type information for this code."  function f() {}" +No type information for this code. +No type information for this code.//// [scannerNonAsciiHorizontalWhitespace.js] +No type information for this code."  function f() {}" +No type information for this code. +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.types b/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.types new file mode 100644 index 00000000000..5d68e59d73b --- /dev/null +++ b/tests/baselines/reference/scannerNonAsciiHorizontalWhitespace.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/scanner/ecmascript5/scannerNonAsciiHorizontalWhitespace.ts === +//// [scannerNonAsciiHorizontalWhitespace.ts] +"  function f() {}" +>"  function f() {}" : "  function f() {}" + +//// [scannerNonAsciiHorizontalWhitespace.js] +"  function f() {}" +>"  function f() {}" : "  function f() {}" + + diff --git a/tests/cases/conformance/scanner/ecmascript5/scannerNonAsciiHorizontalWhitespace.ts b/tests/cases/conformance/scanner/ecmascript5/scannerNonAsciiHorizontalWhitespace.ts new file mode 100644 index 00000000000..447cad65684 --- /dev/null +++ b/tests/cases/conformance/scanner/ecmascript5/scannerNonAsciiHorizontalWhitespace.ts @@ -0,0 +1,6 @@ +//// [scannerNonAsciiHorizontalWhitespace.ts] +"  function f() {}" + +//// [scannerNonAsciiHorizontalWhitespace.js] +"  function f() {}" + From 9c551a107a5463de6030b7295b17d624f368e267 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 16:09:08 -0700 Subject: [PATCH 046/163] Ignore parameters when inferring from return type only signature --- src/compiler/checker.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ce116ffac23..f070d71bb16 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13549,14 +13549,16 @@ namespace ts { const sourceLen = sourceSignatures.length; const targetLen = targetSignatures.length; const len = sourceLen < targetLen ? sourceLen : targetLen; + const skipParameters = !!(source.flags & TypeFlags.ContainsAnyFunctionType); for (let i = 0; i < len; i++) { - inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i])); + inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]), skipParameters); } } - function inferFromSignature(source: Signature, target: Signature) { - forEachMatchingParameterType(source, target, inferFromContravariantTypes); - + function inferFromSignature(source: Signature, target: Signature, skipParameters: boolean) { + if (!skipParameters) { + forEachMatchingParameterType(source, target, inferFromContravariantTypes); + } const sourceTypePredicate = getTypePredicateOfSignature(source); const targetTypePredicate = getTypePredicateOfSignature(target); if (sourceTypePredicate && targetTypePredicate && sourceTypePredicate.kind === targetTypePredicate.kind) { @@ -20576,8 +20578,10 @@ namespace ts { return links.contextFreeType; } const returnType = getReturnTypeFromBody(node, checkMode); - const singleReturnSignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); - return links.contextFreeType = createAnonymousType(node.symbol, emptySymbols, [singleReturnSignature], emptyArray, undefined, undefined); + const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined); + returnOnlyType.flags |= TypeFlags.ContainsAnyFunctionType; + return links.contextFreeType = returnOnlyType; } return anyFunctionType; } From 09bc7505a742b3ffd8bbf01ec50af2bdd8bef551 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 16:09:18 -0700 Subject: [PATCH 047/163] Add regression test --- .../badInferenceLowerPriorityThanGoodInference.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/cases/compiler/badInferenceLowerPriorityThanGoodInference.ts b/tests/cases/compiler/badInferenceLowerPriorityThanGoodInference.ts index 59dfb3ff447..8092e909df6 100644 --- a/tests/cases/compiler/badInferenceLowerPriorityThanGoodInference.ts +++ b/tests/cases/compiler/badInferenceLowerPriorityThanGoodInference.ts @@ -1,3 +1,5 @@ +// Repro from #13118 + interface Foo { a: A; b: (x: A) => void; @@ -10,4 +12,11 @@ const result = canYouInferThis(() => ({ b: x => { } })) -result.BLAH; \ No newline at end of file +result.BLAH; + +// Repro from #26629 + +function goofus (f: (...args: ARGS) => any ) {} + +goofus((a: string) => ({ dog() { return a; } })); +goofus((a: string) => ({ dog: function() { return a; } })); From ed97443ab6581582bb1dcab5b15cc5f20c312051 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 16:09:25 -0700 Subject: [PATCH 048/163] Accept new baselines --- ...InferenceLowerPriorityThanGoodInference.js | 17 ++++- ...enceLowerPriorityThanGoodInference.symbols | 63 +++++++++++++------ ...erenceLowerPriorityThanGoodInference.types | 30 +++++++++ 3 files changed, 89 insertions(+), 21 deletions(-) diff --git a/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.js b/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.js index de98d754bb0..a089d4eb935 100644 --- a/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.js +++ b/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.js @@ -1,4 +1,6 @@ //// [badInferenceLowerPriorityThanGoodInference.ts] +// Repro from #13118 + interface Foo { a: A; b: (x: A) => void; @@ -11,11 +13,24 @@ const result = canYouInferThis(() => ({ b: x => { } })) -result.BLAH; +result.BLAH; + +// Repro from #26629 + +function goofus (f: (...args: ARGS) => any ) {} + +goofus((a: string) => ({ dog() { return a; } })); +goofus((a: string) => ({ dog: function() { return a; } })); + //// [badInferenceLowerPriorityThanGoodInference.js] +// Repro from #13118 var result = canYouInferThis(function () { return ({ a: { BLAH: 33 }, b: function (x) { } }); }); result.BLAH; +// Repro from #26629 +function goofus(f) { } +goofus(function (a) { return ({ dog: function () { return a; } }); }); +goofus(function (a) { return ({ dog: function () { return a; } }); }); diff --git a/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.symbols b/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.symbols index d03ac3b800a..6eb97aef3ba 100644 --- a/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.symbols +++ b/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.symbols @@ -1,42 +1,65 @@ === tests/cases/compiler/badInferenceLowerPriorityThanGoodInference.ts === +// Repro from #13118 + interface Foo { >Foo : Symbol(Foo, Decl(badInferenceLowerPriorityThanGoodInference.ts, 0, 0)) ->A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 0, 14)) +>A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 2, 14)) a: A; ->a : Symbol(Foo.a, Decl(badInferenceLowerPriorityThanGoodInference.ts, 0, 18)) ->A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 0, 14)) +>a : Symbol(Foo.a, Decl(badInferenceLowerPriorityThanGoodInference.ts, 2, 18)) +>A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 2, 14)) b: (x: A) => void; ->b : Symbol(Foo.b, Decl(badInferenceLowerPriorityThanGoodInference.ts, 1, 9)) ->x : Symbol(x, Decl(badInferenceLowerPriorityThanGoodInference.ts, 2, 8)) ->A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 0, 14)) +>b : Symbol(Foo.b, Decl(badInferenceLowerPriorityThanGoodInference.ts, 3, 9)) +>x : Symbol(x, Decl(badInferenceLowerPriorityThanGoodInference.ts, 4, 8)) +>A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 2, 14)) } declare function canYouInferThis(fn: () => Foo): A; ->canYouInferThis : Symbol(canYouInferThis, Decl(badInferenceLowerPriorityThanGoodInference.ts, 3, 1)) ->A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 5, 33)) ->fn : Symbol(fn, Decl(badInferenceLowerPriorityThanGoodInference.ts, 5, 36)) +>canYouInferThis : Symbol(canYouInferThis, Decl(badInferenceLowerPriorityThanGoodInference.ts, 5, 1)) +>A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 7, 33)) +>fn : Symbol(fn, Decl(badInferenceLowerPriorityThanGoodInference.ts, 7, 36)) >Foo : Symbol(Foo, Decl(badInferenceLowerPriorityThanGoodInference.ts, 0, 0)) ->A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 5, 33)) ->A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 5, 33)) +>A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 7, 33)) +>A : Symbol(A, Decl(badInferenceLowerPriorityThanGoodInference.ts, 7, 33)) const result = canYouInferThis(() => ({ ->result : Symbol(result, Decl(badInferenceLowerPriorityThanGoodInference.ts, 7, 5)) ->canYouInferThis : Symbol(canYouInferThis, Decl(badInferenceLowerPriorityThanGoodInference.ts, 3, 1)) +>result : Symbol(result, Decl(badInferenceLowerPriorityThanGoodInference.ts, 9, 5)) +>canYouInferThis : Symbol(canYouInferThis, Decl(badInferenceLowerPriorityThanGoodInference.ts, 5, 1)) a: { BLAH: 33 }, ->a : Symbol(a, Decl(badInferenceLowerPriorityThanGoodInference.ts, 7, 39)) ->BLAH : Symbol(BLAH, Decl(badInferenceLowerPriorityThanGoodInference.ts, 8, 8)) +>a : Symbol(a, Decl(badInferenceLowerPriorityThanGoodInference.ts, 9, 39)) +>BLAH : Symbol(BLAH, Decl(badInferenceLowerPriorityThanGoodInference.ts, 10, 8)) b: x => { } ->b : Symbol(b, Decl(badInferenceLowerPriorityThanGoodInference.ts, 8, 20)) ->x : Symbol(x, Decl(badInferenceLowerPriorityThanGoodInference.ts, 9, 6)) +>b : Symbol(b, Decl(badInferenceLowerPriorityThanGoodInference.ts, 10, 20)) +>x : Symbol(x, Decl(badInferenceLowerPriorityThanGoodInference.ts, 11, 6)) })) result.BLAH; ->result.BLAH : Symbol(BLAH, Decl(badInferenceLowerPriorityThanGoodInference.ts, 8, 8)) ->result : Symbol(result, Decl(badInferenceLowerPriorityThanGoodInference.ts, 7, 5)) ->BLAH : Symbol(BLAH, Decl(badInferenceLowerPriorityThanGoodInference.ts, 8, 8)) +>result.BLAH : Symbol(BLAH, Decl(badInferenceLowerPriorityThanGoodInference.ts, 10, 8)) +>result : Symbol(result, Decl(badInferenceLowerPriorityThanGoodInference.ts, 9, 5)) +>BLAH : Symbol(BLAH, Decl(badInferenceLowerPriorityThanGoodInference.ts, 10, 8)) + +// Repro from #26629 + +function goofus (f: (...args: ARGS) => any ) {} +>goofus : Symbol(goofus, Decl(badInferenceLowerPriorityThanGoodInference.ts, 14, 12)) +>ARGS : Symbol(ARGS, Decl(badInferenceLowerPriorityThanGoodInference.ts, 18, 17)) +>f : Symbol(f, Decl(badInferenceLowerPriorityThanGoodInference.ts, 18, 38)) +>args : Symbol(args, Decl(badInferenceLowerPriorityThanGoodInference.ts, 18, 42)) +>ARGS : Symbol(ARGS, Decl(badInferenceLowerPriorityThanGoodInference.ts, 18, 17)) + +goofus((a: string) => ({ dog() { return a; } })); +>goofus : Symbol(goofus, Decl(badInferenceLowerPriorityThanGoodInference.ts, 14, 12)) +>a : Symbol(a, Decl(badInferenceLowerPriorityThanGoodInference.ts, 20, 8)) +>dog : Symbol(dog, Decl(badInferenceLowerPriorityThanGoodInference.ts, 20, 24)) +>a : Symbol(a, Decl(badInferenceLowerPriorityThanGoodInference.ts, 20, 8)) + +goofus((a: string) => ({ dog: function() { return a; } })); +>goofus : Symbol(goofus, Decl(badInferenceLowerPriorityThanGoodInference.ts, 14, 12)) +>a : Symbol(a, Decl(badInferenceLowerPriorityThanGoodInference.ts, 21, 8)) +>dog : Symbol(dog, Decl(badInferenceLowerPriorityThanGoodInference.ts, 21, 24)) +>a : Symbol(a, Decl(badInferenceLowerPriorityThanGoodInference.ts, 21, 8)) diff --git a/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.types b/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.types index 8b0ab548fdd..0847f9c29d8 100644 --- a/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.types +++ b/tests/baselines/reference/badInferenceLowerPriorityThanGoodInference.types @@ -1,4 +1,6 @@ === tests/cases/compiler/badInferenceLowerPriorityThanGoodInference.ts === +// Repro from #13118 + interface Foo { a: A; >a : A @@ -38,3 +40,31 @@ result.BLAH; >result : { BLAH: number; } >BLAH : number +// Repro from #26629 + +function goofus (f: (...args: ARGS) => any ) {} +>goofus : (f: (...args: ARGS) => any) => void +>f : (...args: ARGS) => any +>args : ARGS + +goofus((a: string) => ({ dog() { return a; } })); +>goofus((a: string) => ({ dog() { return a; } })) : void +>goofus : (f: (...args: ARGS) => any) => void +>(a: string) => ({ dog() { return a; } }) : (a: string) => { dog(): string; } +>a : string +>({ dog() { return a; } }) : { dog(): string; } +>{ dog() { return a; } } : { dog(): string; } +>dog : () => string +>a : string + +goofus((a: string) => ({ dog: function() { return a; } })); +>goofus((a: string) => ({ dog: function() { return a; } })) : void +>goofus : (f: (...args: ARGS) => any) => void +>(a: string) => ({ dog: function() { return a; } }) : (a: string) => { dog: () => string; } +>a : string +>({ dog: function() { return a; } }) : { dog: () => string; } +>{ dog: function() { return a; } } : { dog: () => string; } +>dog : () => string +>function() { return a; } : () => string +>a : string + From e852627df02f9403f6a77ad30334678c4efacd1a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 18:25:02 -0700 Subject: [PATCH 049/163] Add early out for type assertions in getTypeOfExpression --- src/compiler/checker.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ce116ffac23..4b15c471c6a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21698,15 +21698,19 @@ namespace ts { * to cache the result. */ function getTypeOfExpression(node: Expression, cache?: boolean) { + const expr = skipParentheses(node); // Optimize for the common case of a call to a function with a single non-generic call // signature where we can just fetch the return type without checking the arguments. - if (node.kind === SyntaxKind.CallExpression && (node).expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(node)) { - const funcType = checkNonNullExpression((node).expression); + if (expr.kind === SyntaxKind.CallExpression && (expr).expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) { + const funcType = checkNonNullExpression((expr).expression); const signature = getSingleCallSignature(funcType); if (signature && !signature.typeParameters) { return getReturnTypeOfSignature(signature); } } + else if (expr.kind === SyntaxKind.TypeAssertionExpression || expr.kind === SyntaxKind.AsExpression) { + return getTypeFromTypeNode((expr).type); + } // Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions // should have a parameter that indicates whether full error checking is required such that // we can perform the optimizations locally. From 0c759b819488a44a53fbc33c24415d6e7f921c8f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 18:25:14 -0700 Subject: [PATCH 050/163] Add regression test --- .../controlFlowSelfReferentialLoop.ts | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/cases/compiler/controlFlowSelfReferentialLoop.ts b/tests/cases/compiler/controlFlowSelfReferentialLoop.ts index 361d3a557b4..0be51effc80 100644 --- a/tests/cases/compiler/controlFlowSelfReferentialLoop.ts +++ b/tests/cases/compiler/controlFlowSelfReferentialLoop.ts @@ -99,4 +99,23 @@ function md5(string:string): void { b=II(b,c,d,a,x[k+9], S44,0xEB86D391); } } -export default md5; \ No newline at end of file +export default md5; + +// Repro from #26655 + +interface DataShape { + message: { id: string } +} + +function getObject(id: string | number) { + return {} as any +} + +;(() => { + let id: string | number = 'a' + while (1) { + const data = getObject(id) as DataShape + const message = data.message + id = message.id + } +})() From a1c373c3c72a3010917ad41832f13463d92a60cf Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 25 Aug 2018 18:25:20 -0700 Subject: [PATCH 051/163] Accept new baselines --- .../controlFlowSelfReferentialLoop.errors.txt | 22 +++++++- .../controlFlowSelfReferentialLoop.js | 34 ++++++++++++- .../controlFlowSelfReferentialLoop.symbols | 42 +++++++++++++++ .../controlFlowSelfReferentialLoop.types | 51 +++++++++++++++++++ 4 files changed, 147 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/controlFlowSelfReferentialLoop.errors.txt b/tests/baselines/reference/controlFlowSelfReferentialLoop.errors.txt index 69f670359af..b36d991f114 100644 --- a/tests/baselines/reference/controlFlowSelfReferentialLoop.errors.txt +++ b/tests/baselines/reference/controlFlowSelfReferentialLoop.errors.txt @@ -184,4 +184,24 @@ tests/cases/compiler/controlFlowSelfReferentialLoop.ts(17,29): error TS7006: Par b=II(b,c,d,a,x[k+9], S44,0xEB86D391); } } - export default md5; \ No newline at end of file + export default md5; + + // Repro from #26655 + + interface DataShape { + message: { id: string } + } + + function getObject(id: string | number) { + return {} as any + } + + ;(() => { + let id: string | number = 'a' + while (1) { + const data = getObject(id) as DataShape + const message = data.message + id = message.id + } + })() + \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowSelfReferentialLoop.js b/tests/baselines/reference/controlFlowSelfReferentialLoop.js index 4781f2776fb..a6efecb7e2a 100644 --- a/tests/baselines/reference/controlFlowSelfReferentialLoop.js +++ b/tests/baselines/reference/controlFlowSelfReferentialLoop.js @@ -98,7 +98,27 @@ function md5(string:string): void { b=II(b,c,d,a,x[k+9], S44,0xEB86D391); } } -export default md5; +export default md5; + +// Repro from #26655 + +interface DataShape { + message: { id: string } +} + +function getObject(id: string | number) { + return {} as any +} + +;(() => { + let id: string | number = 'a' + while (1) { + const data = getObject(id) as DataShape + const message = data.message + id = message.id + } +})() + //// [controlFlowSelfReferentialLoop.js] "use strict"; @@ -204,3 +224,15 @@ function md5(string) { } } exports["default"] = md5; +function getObject(id) { + return {}; +} +; +(function () { + var id = 'a'; + while (1) { + var data = getObject(id); + var message = data.message; + id = message.id; + } +})(); diff --git a/tests/baselines/reference/controlFlowSelfReferentialLoop.symbols b/tests/baselines/reference/controlFlowSelfReferentialLoop.symbols index ac857a13f43..6247d792c19 100644 --- a/tests/baselines/reference/controlFlowSelfReferentialLoop.symbols +++ b/tests/baselines/reference/controlFlowSelfReferentialLoop.symbols @@ -831,3 +831,45 @@ function md5(string:string): void { export default md5; >md5 : Symbol(md5, Decl(controlFlowSelfReferentialLoop.ts, 0, 0)) +// Repro from #26655 + +interface DataShape { +>DataShape : Symbol(DataShape, Decl(controlFlowSelfReferentialLoop.ts, 99, 19)) + + message: { id: string } +>message : Symbol(DataShape.message, Decl(controlFlowSelfReferentialLoop.ts, 103, 21)) +>id : Symbol(id, Decl(controlFlowSelfReferentialLoop.ts, 104, 12)) +} + +function getObject(id: string | number) { +>getObject : Symbol(getObject, Decl(controlFlowSelfReferentialLoop.ts, 105, 1)) +>id : Symbol(id, Decl(controlFlowSelfReferentialLoop.ts, 107, 19)) + + return {} as any +} + +;(() => { + let id: string | number = 'a' +>id : Symbol(id, Decl(controlFlowSelfReferentialLoop.ts, 112, 5)) + + while (1) { + const data = getObject(id) as DataShape +>data : Symbol(data, Decl(controlFlowSelfReferentialLoop.ts, 114, 9)) +>getObject : Symbol(getObject, Decl(controlFlowSelfReferentialLoop.ts, 105, 1)) +>id : Symbol(id, Decl(controlFlowSelfReferentialLoop.ts, 112, 5)) +>DataShape : Symbol(DataShape, Decl(controlFlowSelfReferentialLoop.ts, 99, 19)) + + const message = data.message +>message : Symbol(message, Decl(controlFlowSelfReferentialLoop.ts, 115, 9)) +>data.message : Symbol(DataShape.message, Decl(controlFlowSelfReferentialLoop.ts, 103, 21)) +>data : Symbol(data, Decl(controlFlowSelfReferentialLoop.ts, 114, 9)) +>message : Symbol(DataShape.message, Decl(controlFlowSelfReferentialLoop.ts, 103, 21)) + + id = message.id +>id : Symbol(id, Decl(controlFlowSelfReferentialLoop.ts, 112, 5)) +>message.id : Symbol(id, Decl(controlFlowSelfReferentialLoop.ts, 104, 12)) +>message : Symbol(message, Decl(controlFlowSelfReferentialLoop.ts, 115, 9)) +>id : Symbol(id, Decl(controlFlowSelfReferentialLoop.ts, 104, 12)) + } +})() + diff --git a/tests/baselines/reference/controlFlowSelfReferentialLoop.types b/tests/baselines/reference/controlFlowSelfReferentialLoop.types index 202286e2eb5..6dba558bd71 100644 --- a/tests/baselines/reference/controlFlowSelfReferentialLoop.types +++ b/tests/baselines/reference/controlFlowSelfReferentialLoop.types @@ -1260,3 +1260,54 @@ function md5(string:string): void { export default md5; >md5 : (string: string) => void +// Repro from #26655 + +interface DataShape { + message: { id: string } +>message : { id: string; } +>id : string +} + +function getObject(id: string | number) { +>getObject : (id: string | number) => any +>id : string | number + + return {} as any +>{} as any : any +>{} : {} +} + +;(() => { +>(() => { let id: string | number = 'a' while (1) { const data = getObject(id) as DataShape const message = data.message id = message.id }})() : void +>(() => { let id: string | number = 'a' while (1) { const data = getObject(id) as DataShape const message = data.message id = message.id }}) : () => void +>() => { let id: string | number = 'a' while (1) { const data = getObject(id) as DataShape const message = data.message id = message.id }} : () => void + + let id: string | number = 'a' +>id : string | number +>'a' : "a" + + while (1) { +>1 : 1 + + const data = getObject(id) as DataShape +>data : DataShape +>getObject(id) as DataShape : DataShape +>getObject(id) : any +>getObject : (id: string | number) => any +>id : string + + const message = data.message +>message : { id: string; } +>data.message : { id: string; } +>data : DataShape +>message : { id: string; } + + id = message.id +>id = message.id : string +>id : string | number +>message.id : string +>message : { id: string; } +>id : string + } +})() + From 61f6d0380acd3714a633e8c7777235e8f8f9a38c Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Mon, 27 Aug 2018 08:54:02 -0700 Subject: [PATCH 052/163] Update user baselines (#26687) --- tests/baselines/reference/user/jimp.log | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/user/jimp.log b/tests/baselines/reference/user/jimp.log index 08123f69c4b..9757da0670e 100644 --- a/tests/baselines/reference/user/jimp.log +++ b/tests/baselines/reference/user/jimp.log @@ -1,6 +1,8 @@ Exit Code: 1 Standard output: -node_modules/jimp/jimp.d.ts(499,16): error TS7010: 'appendConstructorOption', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/jimp/jimp.d.ts(495,16): error TS7010: 'appendConstructorOption', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/jimp/jimp.d.ts(536,16): error TS7010: 'measureText', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/jimp/jimp.d.ts(537,16): error TS7010: 'measureTextHeight', which lacks return-type annotation, implicitly has an 'any' return type. From e411381266c8640526148e30db4233d4f966cb54 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 27 Aug 2018 09:38:52 -0700 Subject: [PATCH 053/163] Fix bug: Don't let empty signature documentation override other documentation (#26638) --- src/services/symbolDisplay.ts | 3 +- tests/cases/fourslash/commentsClass.ts | 12 +++--- .../cases/fourslash/commentsCommentParsing.ts | 2 +- .../fourslash/commentsExternalModules.ts | 4 +- .../fourslash/commentsImportDeclaration.ts | 2 +- tests/cases/fourslash/commentsInheritance.ts | 38 +++++++++---------- tests/cases/fourslash/commentsInterface.ts | 6 +-- tests/cases/fourslash/commentsModules.ts | 28 +++++++------- tests/cases/fourslash/commentsOverloads.ts | 30 +++++++-------- .../cases/fourslash/quickInfoCallProperty.ts | 11 ++++++ .../fourslash/quickInfoOnInternalAliases.ts | 2 +- 11 files changed, 75 insertions(+), 63 deletions(-) create mode 100644 tests/cases/fourslash/quickInfoCallProperty.ts diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 611bb26bf1e..d1d8709bef2 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -611,7 +611,8 @@ namespace ts.SymbolDisplay { displayParts.push(textPart(allSignatures.length === 2 ? "overload" : "overloads")); displayParts.push(punctuationPart(SyntaxKind.CloseParenToken)); } - documentation = signature.getDocumentationComment(typeChecker); + const docComment = signature.getDocumentationComment(typeChecker); + documentation = docComment.length === 0 ? undefined : docComment; tags = signature.getJsDocTags(); } diff --git a/tests/cases/fourslash/commentsClass.ts b/tests/cases/fourslash/commentsClass.ts index 79f1d05af66..87e9b9d3a48 100644 --- a/tests/cases/fourslash/commentsClass.ts +++ b/tests/cases/fourslash/commentsClass.ts @@ -1,6 +1,6 @@ /// -/////** This is class c2 without constuctor*/ +/////** This is class c2 without constructor*/ ////class c/*1*/2 { ////} ////var i/*2*/2 = new c/*28*/2(/*3*/); @@ -59,7 +59,7 @@ ////var myVar = new m.m2.c/*33*/1(); verify.quickInfos({ - 1: ["class c2", "This is class c2 without constuctor"], + 1: ["class c2", "This is class c2 without constructor"], 2: "var i2: c2" }); @@ -67,7 +67,7 @@ verify.signatureHelp({ marker: "3", docComment: "" }); verify.quickInfos({ 4: "var i2_c: typeof c2", - 5: ["class c2", "This is class c2 without constuctor"], + 5: ["class c2", "This is class c2 without constructor"], 6: "class c3", 7: "var i3: c3" }); @@ -107,7 +107,7 @@ verify.quickInfos({ }); goTo.marker('26'); -verify.completionListContains("c2", "class c2", "This is class c2 without constuctor"); +verify.completionListContains("c2", "class c2", "This is class c2 without constructor"); verify.completionListContains("i2", "var i2: c2", ""); verify.completionListContains("i2_c", "var i2_c: typeof c2", ""); verify.completionListContains("c3", "class c3", ""); @@ -131,10 +131,10 @@ verify.signatureHelp({ }); verify.quickInfos({ - 28: "constructor c2(): c2", + 28: ["constructor c2(): c2", "This is class c2 without constructor"], 29: ["constructor c3(): c3", "Constructor comment"], 30: ["constructor c4(): c4", "Constructor comment"], - 31: "constructor c5(): c5", + 31: ["constructor c5(): c5", "Class with statics"], 32: ["constructor c6(): c6", "constructor comment"], 33: ["constructor m.m2.c1(): m.m2.c1", "constructor comment"] }); diff --git a/tests/cases/fourslash/commentsCommentParsing.ts b/tests/cases/fourslash/commentsCommentParsing.ts index 2b59b35bd14..df3adca4c87 100644 --- a/tests/cases/fourslash/commentsCommentParsing.ts +++ b/tests/cases/fourslash/commentsCommentParsing.ts @@ -323,7 +323,7 @@ verify.quickInfos({ verify.signatureHelp({ marker: "26", overloadsCount: 2, docComment: "" }); verify.quickInfos({ - "26q": "function f1(b: string): any (+1 overload)", + "26q": ["function f1(b: string): any (+1 overload)", "fn f1 with number"], "26aq": "(parameter) b: string" }); diff --git a/tests/cases/fourslash/commentsExternalModules.ts b/tests/cases/fourslash/commentsExternalModules.ts index f9c619e5a17..c1c12d8a3ce 100644 --- a/tests/cases/fourslash/commentsExternalModules.ts +++ b/tests/cases/fourslash/commentsExternalModules.ts @@ -55,7 +55,7 @@ verify.quickInfoAt("6q", "function m1.fooExport(): number", "exported function") verify.quickInfoAt("7", "var myvar: m1.m2.c"); goTo.marker('8'); -verify.completionListContains("c", "constructor m1.m2.c(): m1.m2.c", ""); +verify.completionListContains("c", "constructor m1.m2.c(): m1.m2.c", "class comment;"); verify.completionListContains("i", "var m1.m2.i: m1.m2.c", "i"); goTo.file("commentsExternalModules_file1.ts"); @@ -78,5 +78,5 @@ verify.quickInfoAt("13q", "function extMod.m1.fooExport(): number", "exported fu verify.quickInfoAt("14", "var newVar: extMod.m1.m2.c"); goTo.marker('15'); -verify.completionListContains("c", "constructor extMod.m1.m2.c(): extMod.m1.m2.c", ""); +verify.completionListContains("c", "constructor extMod.m1.m2.c(): extMod.m1.m2.c", "class comment;"); verify.completionListContains("i", "var extMod.m1.m2.i: extMod.m1.m2.c", "i"); diff --git a/tests/cases/fourslash/commentsImportDeclaration.ts b/tests/cases/fourslash/commentsImportDeclaration.ts index bc343afeabf..b19eeba6885 100644 --- a/tests/cases/fourslash/commentsImportDeclaration.ts +++ b/tests/cases/fourslash/commentsImportDeclaration.ts @@ -49,7 +49,7 @@ verify.quickInfos({ verify.completions({ marker: "10", exact: [ - { name: "c", text: "constructor extMod.m1.m2.c(): extMod.m1.m2.c" }, + { name: "c", text: "constructor extMod.m1.m2.c(): extMod.m1.m2.c", documentation: "class comment;" }, { name: "i", text: "var extMod.m1.m2.i: extMod.m1.m2.c", documentation: "i" }, ], }); diff --git a/tests/cases/fourslash/commentsInheritance.ts b/tests/cases/fourslash/commentsInheritance.ts index 3443ec23177..aac3cf287f4 100644 --- a/tests/cases/fourslash/commentsInheritance.ts +++ b/tests/cases/fourslash/commentsInheritance.ts @@ -223,7 +223,7 @@ goTo.marker('1'); verify.completionListContains("i1_p1", "(property) i1.i1_p1: number", "i1_p1"); verify.completionListContains("i1_f1", "(method) i1.i1_f1(): void", "i1_f1"); -verify.completionListContains("i1_l1", "(property) i1.i1_l1: () => void", ""); +verify.completionListContains("i1_l1", "(property) i1.i1_l1: () => void", "i1_l1"); verify.completionListContains("i1_nc_p1", "(property) i1.i1_nc_p1: number", ""); verify.completionListContains("i1_nc_f1", "(method) i1.i1_nc_f1(): void", ""); verify.completionListContains("i1_nc_l1", "(property) i1.i1_nc_l1: () => void", ""); @@ -244,7 +244,7 @@ verify.quickInfos({ "3q": "(method) i1.i1_nc_f1(): void", "4q": "(method) i1.f1(): void", "5q": "(method) i1.nc_f1(): void", - l2q: "(property) i1.i1_l1: () => void", + l2q: ["(property) i1.i1_l1: () => void", "i1_l1"], l3q: "(property) i1.i1_nc_l1: () => void", l4q: "(property) i1.l1: () => void", l5q: "(property) i1.nc_l1: () => void" @@ -253,7 +253,7 @@ verify.quickInfos({ goTo.marker('6'); verify.completionListContains("i1_p1", "(property) c1.i1_p1: number", "i1_p1"); verify.completionListContains("i1_f1", "(method) c1.i1_f1(): void", "i1_f1"); -verify.completionListContains("i1_l1", "(property) c1.i1_l1: () => void", ""); +verify.completionListContains("i1_l1", "(property) c1.i1_l1: () => void", "i1_l1"); verify.completionListContains("i1_nc_p1", "(property) c1.i1_nc_p1: number", ""); verify.completionListContains("i1_nc_f1", "(method) c1.i1_nc_f1(): void", ""); verify.completionListContains("i1_nc_l1", "(property) c1.i1_nc_l1: () => void", ""); @@ -278,7 +278,7 @@ verify.quickInfos({ "8q": "(method) c1.i1_nc_f1(): void", "9q": ["(method) c1.f1(): void", "c1_f1"], "10q": ["(method) c1.nc_f1(): void", "c1_nc_f1"], - l7q: "(property) c1.i1_l1: () => void", + l7q: ["(property) c1.i1_l1: () => void", "i1_l1"], l8q: "(property) c1.i1_nc_l1: () => void", l9q: ["(property) c1.l1: () => void", "c1_l1"], l10q: ["(property) c1.nc_l1: () => void", "c1_nc_l1"], @@ -287,7 +287,7 @@ verify.quickInfos({ goTo.marker('11'); verify.completionListContains("i1_p1", "(property) i1.i1_p1: number", "i1_p1"); verify.completionListContains("i1_f1", "(method) i1.i1_f1(): void", "i1_f1"); -verify.completionListContains("i1_l1", "(property) i1.i1_l1: () => void", ""); +verify.completionListContains("i1_l1", "(property) i1.i1_l1: () => void", "i1_l1"); verify.completionListContains("i1_nc_p1", "(property) i1.i1_nc_p1: number", ""); verify.completionListContains("i1_nc_f1", "(method) i1.i1_nc_f1(): void", ""); verify.completionListContains("i1_nc_l1", "(property) i1.i1_nc_l1: () => void", ""); @@ -307,7 +307,7 @@ verify.quickInfos({ "13q": "(method) i1.i1_nc_f1(): void", "14q": "(method) i1.f1(): void", "15q": "(method) i1.nc_f1(): void", - l12q: "(property) i1.i1_l1: () => void", + l12q: ["(property) i1.i1_l1: () => void", "i1_l1"], l13q: "(property) i1.i1_nc_l1: () => void", l14q: "(property) i1.l1: () => void", l15q: "(property) i1.nc_l1: () => void", @@ -437,13 +437,13 @@ verify.completionListContains("c4_i", "var c4_i: c4", ""); goTo.marker('36'); verify.completionListContains("i2_p1", "(property) i2.i2_p1: number", "i2_p1"); verify.completionListContains("i2_f1", "(method) i2.i2_f1(): void", "i2_f1"); -verify.completionListContains("i2_l1", "(property) i2.i2_l1: () => void", ""); +verify.completionListContains("i2_l1", "(property) i2.i2_l1: () => void", "i2_l1"); verify.completionListContains("i2_nc_p1", "(property) i2.i2_nc_p1: number", ""); verify.completionListContains("i2_nc_f1", "(method) i2.i2_nc_f1(): void", ""); verify.completionListContains("i2_nc_l1", "(property) i2.i2_nc_l1: () => void", ""); verify.completionListContains("p1", "(property) i2.p1: number", "i2 p1"); verify.completionListContains("f1", "(method) i2.f1(): void", "i2 f1"); -verify.completionListContains("l1", "(property) i2.l1: () => void", ""); +verify.completionListContains("l1", "(property) i2.l1: () => void", "i2 l1"); verify.completionListContains("nc_p1", "(property) i2.nc_p1: number", ""); verify.completionListContains("nc_f1", "(method) i2.nc_f1(): void", ""); verify.completionListContains("nc_l1", "(property) i2.nc_l1: () => void", ""); @@ -460,22 +460,22 @@ verify.quickInfos({ "38q": "(method) i2.i2_nc_f1(): void", "39q": ["(method) i2.f1(): void", "i2 f1"], "40q": "(method) i2.nc_f1(): void", - "l37q": "(property) i2.i2_l1: () => void", + "l37q": ["(property) i2.i2_l1: () => void", "i2_l1"], "l38q": "(property) i2.i2_nc_l1: () => void", - "l39q": "(property) i2.l1: () => void", + "l39q": ["(property) i2.l1: () => void", "i2 l1"], "l40q": "(property) i2.nc_l1: () => void", }); goTo.marker('41'); verify.completionListContains("i2_p1", "(property) i2.i2_p1: number", "i2_p1"); verify.completionListContains("i2_f1", "(method) i2.i2_f1(): void", "i2_f1"); -verify.completionListContains("i2_l1", "(property) i2.i2_l1: () => void", ""); +verify.completionListContains("i2_l1", "(property) i2.i2_l1: () => void", "i2_l1"); verify.completionListContains("i2_nc_p1", "(property) i2.i2_nc_p1: number", ""); verify.completionListContains("i2_nc_f1", "(method) i2.i2_nc_f1(): void", ""); verify.completionListContains("i2_nc_l1", "(property) i2.i2_nc_l1: () => void", ""); verify.completionListContains("p1", "(property) i3.p1: number", "i3 p1"); verify.completionListContains("f1", "(method) i3.f1(): void", "i3 f1"); -verify.completionListContains("l1", "(property) i3.l1: () => void", ""); +verify.completionListContains("l1", "(property) i3.l1: () => void", "i3 l1"); verify.completionListContains("nc_p1", "(property) i3.nc_p1: number", ""); verify.completionListContains("nc_f1", "(method) i3.nc_f1(): void", ""); verify.completionListContains("nc_l1", "(property) i3.nc_l1: () => void", ""); @@ -490,22 +490,22 @@ verify.quickInfos({ "43q": "(method) i2.i2_nc_f1(): void", "44q": ["(method) i3.f1(): void", "i3 f1"], "45q": "(method) i3.nc_f1(): void", - l42q: "(property) i2.i2_l1: () => void", + l42q: ["(property) i2.i2_l1: () => void", "i2_l1"], l43q: "(property) i2.i2_nc_l1: () => void", - l44q: "(property) i3.l1: () => void", + l44q: ["(property) i3.l1: () => void", "i3 l1"], l45q: "(property) i3.nc_l1: () => void" }); goTo.marker('46'); verify.completionListContains("i2_p1", "(property) i2.i2_p1: number", "i2_p1"); verify.completionListContains("i2_f1", "(method) i2.i2_f1(): void", "i2_f1"); -verify.completionListContains("i2_l1", "(property) i2.i2_l1: () => void", ""); +verify.completionListContains("i2_l1", "(property) i2.i2_l1: () => void", "i2_l1"); verify.completionListContains("i2_nc_p1", "(property) i2.i2_nc_p1: number", ""); verify.completionListContains("i2_nc_f1", "(method) i2.i2_nc_f1(): void", ""); verify.completionListContains("i2_nc_l1", "(property) i2.i2_nc_l1: () => void", ""); verify.completionListContains("p1", "(property) i2.p1: number", "i2 p1"); verify.completionListContains("f1", "(method) i2.f1(): void", "i2 f1"); -verify.completionListContains("l1", "(property) i2.l1: () => void", ""); +verify.completionListContains("l1", "(property) i2.l1: () => void", "i2 l1"); verify.completionListContains("nc_p1", "(property) i2.nc_p1: number", ""); verify.completionListContains("nc_f1", "(method) i2.nc_f1(): void", ""); verify.completionListContains("nc_l1", "(property) i2.nc_l1: () => void", ""); @@ -520,9 +520,9 @@ verify.quickInfos({ "48q": "(method) i2.i2_nc_f1(): void", "49q": ["(method) i2.f1(): void", "i2 f1"], "50q": "(method) i2.nc_f1(): void", - l47q: "(property) i2.i2_l1: () => void", + l47q: ["(property) i2.i2_l1: () => void", "i2_l1"], l48q: "(property) i2.i2_nc_l1: () => void", - l49q: "(property) i2.l1: () => void", + l49q: ["(property) i2.l1: () => void", "i2 l1"], l40q: "(property) i2.nc_l1: () => void" }); @@ -537,7 +537,7 @@ verify.completionListContains("i2", "interface i2", ""); verify.completionListContains("i3", "interface i3", ""); verify.quickInfos({ - 52: "constructor c5(): c5", + 52: ["constructor c5(): c5", "c5 class"], 53: ["class c5", "c5 class"], 54: "(property) c5.b: number", 55: ["constructor c2(a: number): c2", "c2 constructor"], diff --git a/tests/cases/fourslash/commentsInterface.ts b/tests/cases/fourslash/commentsInterface.ts index 85c12118c34..fdeeb8bb3eb 100644 --- a/tests/cases/fourslash/commentsInterface.ts +++ b/tests/cases/fourslash/commentsInterface.ts @@ -96,7 +96,7 @@ verify.quickInfos({ verify.signatureHelp({ marker: "12", docComment: "", parameterDocComment: "param help" }); verify.quickInfos({ - "12q": "(property) i2.foo: (b: number) => string", + "12q": ["(property) i2.foo: (b: number) => string", "this is foo"], 13: "var i2_i_i2_si: number", "13q": "var i2_i: i2", @@ -186,7 +186,7 @@ verify.completionListContains("i3_i", "var i3_i: i3", ""); goTo.marker('41'); verify.quickInfoIs("(method) i3.f(a: number): string", "Function i3 f"); verify.completionListContains("f", "(method) i3.f(a: number): string", "Function i3 f"); -verify.completionListContains("l", "(property) i3.l: (b: number) => string", ""); +verify.completionListContains("l", "(property) i3.l: (b: number) => string", "i3 l"); verify.completionListContains("x", "(property) i3.x: number", "Comment i3 x"); verify.completionListContains("nc_f", "(method) i3.nc_f(a: number): string", ""); verify.completionListContains("nc_l", "(property) i3.nc_l: (b: number) => string", ""); @@ -195,7 +195,7 @@ verify.completionListContains("nc_x", "(property) i3.nc_x: number", ""); verify.signatureHelp({ marker: "42", docComment: "Function i3 f", parameterDocComment: "number parameter" }); verify.signatureHelp({ marker: "43", docComment: "", parameterDocComment: "comment i3 l b" }); -verify.quickInfoAt("43q", "(property) i3.l: (b: number) => string"); +verify.quickInfoAt("43q", "(property) i3.l: (b: number) => string", "i3 l"); verify.signatureHelp({ marker: "44", docComment: "" }); verify.quickInfoAt("44q", "(method) i3.nc_f(a: number): string"); diff --git a/tests/cases/fourslash/commentsModules.ts b/tests/cases/fourslash/commentsModules.ts index d36e530d9bd..545c1569096 100644 --- a/tests/cases/fourslash/commentsModules.ts +++ b/tests/cases/fourslash/commentsModules.ts @@ -119,8 +119,8 @@ verify.signatureHelp({ marker: "6", docComment: "exported function" }); verify.quickInfoAt("7", "var myvar: m1.m2.c"); goTo.marker('8'); -verify.quickInfoIs("constructor m1.m2.c(): m1.m2.c"); -verify.completionListContains("c", "constructor m1.m2.c(): m1.m2.c", ""); +verify.quickInfoIs("constructor m1.m2.c(): m1.m2.c", "class comment;"); +verify.completionListContains("c", "constructor m1.m2.c(): m1.m2.c", "class comment;"); verify.completionListContains("i", "var m1.m2.i: m1.m2.c", "i"); goTo.marker('9'); @@ -132,8 +132,8 @@ verify.completionListContains("m3", "namespace m2.m3"); verify.quickInfoIs("namespace m2.m3", "namespace comment of m2.m3"); goTo.marker('11'); -verify.quickInfoIs("constructor m2.m3.c(): m2.m3.c"); -verify.completionListContains("c", "constructor m2.m3.c(): m2.m3.c", ""); +verify.quickInfoIs("constructor m2.m3.c(): m2.m3.c", "Exported class comment"); +verify.completionListContains("c", "constructor m2.m3.c(): m2.m3.c", "Exported class comment"); goTo.marker('12'); verify.completionListContains("m3", "namespace m3", "namespace comment of m3.m4.m5"); @@ -148,8 +148,8 @@ verify.completionListContains("m5", "namespace m3.m4.m5"); verify.quickInfoIs("namespace m3.m4.m5", "namespace comment of m3.m4.m5"); goTo.marker('15'); -verify.quickInfoIs("constructor m3.m4.m5.c(): m3.m4.m5.c"); -verify.completionListContains("c", "constructor m3.m4.m5.c(): m3.m4.m5.c", ""); +verify.quickInfoIs("constructor m3.m4.m5.c(): m3.m4.m5.c", "Exported class comment"); +verify.completionListContains("c", "constructor m3.m4.m5.c(): m3.m4.m5.c", "Exported class comment"); goTo.marker('16'); verify.completionListContains("m4", "namespace m4", "namespace comment of m4.m5.m6"); @@ -168,8 +168,8 @@ verify.completionListContains("m7", "namespace m4.m5.m6.m7"); verify.quickInfoIs("namespace m4.m5.m6.m7"); goTo.marker('20'); -verify.completionListContains("c", "constructor m4.m5.m6.m7.c(): m4.m5.m6.m7.c", ""); -verify.quickInfoIs("constructor m4.m5.m6.m7.c(): m4.m5.m6.m7.c"); +verify.completionListContains("c", "constructor m4.m5.m6.m7.c(): m4.m5.m6.m7.c", "Exported class comment"); +verify.quickInfoIs("constructor m4.m5.m6.m7.c(): m4.m5.m6.m7.c", "Exported class comment"); goTo.marker('21'); verify.completionListContains("m5", "namespace m5"); @@ -188,8 +188,8 @@ verify.completionListContains("m8", "namespace m5.m6.m7.m8"); verify.quickInfoIs("namespace m5.m6.m7.m8", "namespace m8 comment"); goTo.marker('25'); -verify.completionListContains("c", "constructor m5.m6.m7.m8.c(): m5.m6.m7.m8.c", ""); -verify.quickInfoIs("constructor m5.m6.m7.m8.c(): m5.m6.m7.m8.c"); +verify.completionListContains("c", "constructor m5.m6.m7.m8.c(): m5.m6.m7.m8.c", "Exported class comment"); +verify.quickInfoIs("constructor m5.m6.m7.m8.c(): m5.m6.m7.m8.c", "Exported class comment"); goTo.marker('26'); verify.completionListContains("m6", "namespace m6"); @@ -204,8 +204,8 @@ verify.completionListContains("m8", "namespace m6.m7.m8"); verify.quickInfoIs("namespace m6.m7.m8"); goTo.marker('29'); -verify.completionListContains("c", "constructor m6.m7.m8.c(): m6.m7.m8.c", ""); -verify.quickInfoIs("constructor m6.m7.m8.c(): m6.m7.m8.c"); +verify.completionListContains("c", "constructor m6.m7.m8.c(): m6.m7.m8.c", "Exported class comment"); +verify.quickInfoIs("constructor m6.m7.m8.c(): m6.m7.m8.c", "Exported class comment"); goTo.marker('30'); verify.completionListContains("m7", "namespace m7"); @@ -220,8 +220,8 @@ verify.completionListContains("m9", "namespace m7.m8.m9"); verify.quickInfoIs("namespace m7.m8.m9", "namespace m9 comment"); goTo.marker('33'); -verify.completionListContains("c", "constructor m7.m8.m9.c(): m7.m8.m9.c", ""); -verify.quickInfoIs("constructor m7.m8.m9.c(): m7.m8.m9.c"); +verify.completionListContains("c", "constructor m7.m8.m9.c(): m7.m8.m9.c", "Exported class comment"); +verify.quickInfoIs("constructor m7.m8.m9.c(): m7.m8.m9.c", "Exported class comment"); goTo.marker('34'); verify.completionListContains("c", 'class c', ""); diff --git a/tests/cases/fourslash/commentsOverloads.ts b/tests/cases/fourslash/commentsOverloads.ts index a6c7170d2e9..372eedbb2da 100644 --- a/tests/cases/fourslash/commentsOverloads.ts +++ b/tests/cases/fourslash/commentsOverloads.ts @@ -227,9 +227,9 @@ verify.quickInfos({ 1: ["function f1(a: number): number (+1 overload)", "this is signature 1"], - 2: "function f1(b: string): number (+1 overload)", + 2: ["function f1(b: string): number (+1 overload)", "this is signature 1"], 3: ["function f1(a: number): number (+1 overload)", "this is signature 1"], - "4q": "function f1(b: string): number (+1 overload)", + "4q": ["function f1(b: string): number (+1 overload)", "this is signature 1"], o4q: ["function f1(a: number): number (+1 overload)", "this is signature 1"] }); @@ -237,11 +237,11 @@ verify.signatureHelp({ marker: "4", overloadsCount: 2 }); verify.signatureHelp({ marker: "o4", overloadsCount: 2, docComment: "this is signature 1", parameterDocComment: "param a" }); verify.quickInfos({ - 5: "function f2(a: number): number (+1 overload)", + 5: ["function f2(a: number): number (+1 overload)", "this is signature 2\nthis is f2 var comment"], 6: ["function f2(b: string): number (+1 overload)", "this is signature 2"], - 7: "function f2(a: number): number (+1 overload)", + 7: ["function f2(a: number): number (+1 overload)", "this is signature 2\nthis is f2 var comment"], "8q": ["function f2(b: string): number (+1 overload)", "this is signature 2"], - o8q: "function f2(a: number): number (+1 overload)" + o8q: ["function f2(a: number): number (+1 overload)", "this is signature 2\nthis is f2 var comment"], }); verify.signatureHelp( @@ -274,7 +274,7 @@ verify.signatureHelp( goTo.marker('17'); verify.completionListContains('f1', 'function f1(a: number): number (+1 overload)', 'this is signature 1'); -verify.completionListContains('f2', 'function f2(a: number): number (+1 overload)', ''); +verify.completionListContains('f2', 'function f2(a: number): number (+1 overload)', 'this is signature 2\nthis is f2 var comment'); verify.completionListContains('f3', 'function f3(a: number): number (+1 overload)', ''); verify.completionListContains('f4', 'function f4(a: number): number (+1 overload)', 'this is signature 4 - with number parameter'); @@ -303,7 +303,7 @@ verify.quickInfoAt("22q", "var i1_i: i1\n(b: string) => number (+1 overload)", " goTo.marker('23'); verify.completionListContains('foo', '(method) i1.foo(a: number): number (+1 overload)', 'foo 1'); -verify.completionListContains('foo2', '(method) i1.foo2(a: number): number (+1 overload)', ''); +verify.completionListContains('foo2', '(method) i1.foo2(a: number): number (+1 overload)', 'foo2 2'); verify.completionListContains('foo3', '(method) i1.foo3(a: number): number (+1 overload)', ''); verify.completionListContains('foo4', '(method) i1.foo4(a: number): number (+1 overload)', 'foo4 1'); @@ -314,7 +314,7 @@ verify.signatureHelp({ marker: "25", overloadsCount: 2, docComment: "foo 2" }); verify.quickInfoAt("25q", "(method) i1.foo(b: string): number (+1 overload)", "foo 2"); verify.signatureHelp({ marker: "26", overloadsCount: 2 }); -verify.quickInfoAt("26q", "(method) i1.foo2(a: number): number (+1 overload)"); +verify.quickInfoAt("26q", "(method) i1.foo2(a: number): number (+1 overload)", "foo2 2"); verify.signatureHelp({ marker: "27", overloadsCount: 2, docComment: "foo2 2" }); verify.quickInfoAt("27q", "(method) i1.foo2(b: string): number (+1 overload)", "foo2 2"); @@ -329,7 +329,7 @@ verify.signatureHelp({ marker: "30", overloadsCount: 2, docComment: "foo4 1" }); verify.quickInfoAt("30q", "(method) i1.foo4(a: number): number (+1 overload)", "foo4 1"); verify.signatureHelp({ marker: "31", overloadsCount: 2 }); -verify.quickInfoAt("31q", "(method) i1.foo4(b: string): number (+1 overload)"); +verify.quickInfoAt("31q", "(method) i1.foo4(b: string): number (+1 overload)", "foo4 1"); verify.signatureHelp({ marker: "32", overloadsCount: 2, docComment: "new 2" }); verify.quickInfoAt("32q", "var i2_i: i2\nnew (b: number) => any (+1 overload)", "new 2"); @@ -370,7 +370,7 @@ verify.quickInfoAt("43q", "var i4_i: i4\n(b: string) => number (+1 overload)"); goTo.marker('44'); verify.completionListContains('prop1', '(method) c.prop1(a: number): number (+1 overload)', ''); verify.completionListContains('prop2', '(method) c.prop2(a: number): number (+1 overload)', 'prop2 1'); -verify.completionListContains('prop3', '(method) c.prop3(a: number): number (+1 overload)', ''); +verify.completionListContains('prop3', '(method) c.prop3(a: number): number (+1 overload)', 'prop3 2'); verify.completionListContains('prop4', '(method) c.prop4(a: number): number (+1 overload)', 'prop4 1'); verify.completionListContains('prop5', '(method) c.prop5(a: number): number (+1 overload)', 'prop5 1'); @@ -384,10 +384,10 @@ verify.signatureHelp({ marker: "47", overloadsCount: 2, docComment: "prop2 1" }) verify.quickInfoAt("47q", "(method) c.prop2(a: number): number (+1 overload)", "prop2 1"); verify.signatureHelp({ marker: "48", overloadsCount: 2 }); -verify.quickInfoAt("48q", "(method) c.prop2(b: string): number (+1 overload)"); +verify.quickInfoAt("48q", "(method) c.prop2(b: string): number (+1 overload)", "prop2 1"); verify.signatureHelp({ marker: "49", overloadsCount: 2 }); -verify.quickInfoAt("49q", "(method) c.prop3(a: number): number (+1 overload)"); +verify.quickInfoAt("49q", "(method) c.prop3(a: number): number (+1 overload)", "prop3 2"); verify.signatureHelp({ marker: "50", overloadsCount: 2, docComment: "prop3 2" }); verify.quickInfoAt("50q", "(method) c.prop3(b: string): number (+1 overload)", "prop3 2"); @@ -487,11 +487,11 @@ verify.quickInfos({ 94: "(method) c.prop1(b: string): number (+1 overload)", 95: "(method) c.prop1(a: number): number (+1 overload)", 96: ["(method) c.prop2(a: number): number (+1 overload)", "prop2 1"], - 97: "(method) c.prop2(b: string): number (+1 overload)", + 97: ["(method) c.prop2(b: string): number (+1 overload)", "prop2 1"], 98: ["(method) c.prop2(a: number): number (+1 overload)", "prop2 1"], - 99: "(method) c.prop3(a: number): number (+1 overload)", + 99: ["(method) c.prop3(a: number): number (+1 overload)", "prop3 2"], 100: ["(method) c.prop3(b: string): number (+1 overload)", "prop3 2"], - 101: "(method) c.prop3(a: number): number (+1 overload)", + 101: ["(method) c.prop3(a: number): number (+1 overload)", "prop3 2"], 102: ["(method) c.prop4(a: number): number (+1 overload)", "prop4 1"], 103: ["(method) c.prop4(b: string): number (+1 overload)", "prop4 2"], 104: ["(method) c.prop4(a: number): number (+1 overload)", "prop4 1"], diff --git a/tests/cases/fourslash/quickInfoCallProperty.ts b/tests/cases/fourslash/quickInfoCallProperty.ts new file mode 100644 index 00000000000..a4c43f02e9f --- /dev/null +++ b/tests/cases/fourslash/quickInfoCallProperty.ts @@ -0,0 +1,11 @@ +/// + +////interface I { +//// /** Doc */ +//// m: () => void; +////} +////function f(x: I): void { +//// x./**/m(); +////} + +verify.quickInfoAt("", "(property) I.m: () => void", "Doc"); diff --git a/tests/cases/fourslash/quickInfoOnInternalAliases.ts b/tests/cases/fourslash/quickInfoOnInternalAliases.ts index f22b61ae86d..6626a8b1fdf 100644 --- a/tests/cases/fourslash/quickInfoOnInternalAliases.ts +++ b/tests/cases/fourslash/quickInfoOnInternalAliases.ts @@ -24,7 +24,7 @@ verify.quickInfos({ 2: ["(alias) class internalAlias\nimport internalAlias = m1.m2.c", "This is on import declaration"], 3: ["class m1.m2.c", "class comment;"], 4: "var newVar: internalAlias", - 5: "(alias) new internalAlias(): internalAlias\nimport internalAlias = m1.m2.c", + 5: ["(alias) new internalAlias(): internalAlias\nimport internalAlias = m1.m2.c", "This is on import declaration"], 6: "var anotherAliasVar: typeof internalAlias", 7: ["(alias) class internalAlias\nimport internalAlias = m1.m2.c", "This is on import declaration"], 8: "(alias) function internalFoo(): void\nimport internalFoo = m1.foo", From 6419240ab2668ff818c933796c2fc532588dbe50 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 27 Aug 2018 10:29:53 -0700 Subject: [PATCH 054/163] Declaration emit includes function properties (#26499) * Declaration emit includes function properties It does this by printing the type as an object literal type: ```ts function f() { } f.p = 1 ``` Appears in a d.ts as ```ts declare var f: { (): void; p: number; } ``` It would also be possible to represent it as a namespace merge. I'm not sure which is better. ```ts declare function f(): void; declare namespace f { export var p: number; } ``` In order to avoid a private-name-used error (though I think it was actually *unused*), I also had to change the nodeBuilder code to match. This is arguably harder to read. So it's possible that I should instead keep the nodeBuilder version as `typeof f` and make an exception for private name use. * Emit namespace merge instead of object type This makes the change smaller, overall. * Fix isJSContainerFunctionDeclaration+namespace merges Also improve emit style to match other namespace emit. * Add isPrivate + test case from PR comments --- src/compiler/checker.ts | 25 +- src/compiler/transformers/declarations.ts | 17 +- src/compiler/types.ts | 4 +- .../typeFromPropertyAssignment29.errors.txt | 58 +++-- .../reference/typeFromPropertyAssignment29.js | 130 +++++++++- .../typeFromPropertyAssignment29.symbols | 224 ++++++++++++------ .../typeFromPropertyAssignment29.types | 152 ++++++++++-- .../salsa/typeFromPropertyAssignment29.ts | 35 ++- 8 files changed, 540 insertions(+), 105 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f070d71bb16..a3cd01e3583 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27767,6 +27767,27 @@ namespace ts { hasModifier(parameter, ModifierFlags.ParameterPropertyModifier); } + function isJSContainerFunctionDeclaration(node: Declaration): boolean { + const declaration = getParseTreeNode(node, isFunctionDeclaration); + if (!declaration) { + return false; + } + const symbol = getSymbolOfNode(declaration); + if (!symbol || !(symbol.flags & SymbolFlags.Function)) { + return false; + } + return !!forEachEntry(getExportsOfSymbol(symbol), p => isPropertyAccessExpression(p.valueDeclaration)); + } + + function getPropertiesOfContainerFunction(node: Declaration): Symbol[] { + const declaration = getParseTreeNode(node, isFunctionDeclaration); + if (!declaration) { + return emptyArray; + } + const symbol = getSymbolOfNode(declaration); + return symbol && getPropertiesOfType(getTypeOfSymbol(symbol)) || emptyArray; + } + function getNodeCheckFlags(node: Node): NodeCheckFlags { return getNodeLinks(node).flags || 0; } @@ -27874,7 +27895,7 @@ namespace ts { } } - function createTypeOfDeclaration(declarationIn: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean) { + function createTypeOfDeclaration(declarationIn: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean) { const declaration = getParseTreeNode(declarationIn, isVariableLikeOrAccessor); if (!declaration) { return createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode; @@ -28007,6 +28028,8 @@ namespace ts { isImplementationOfOverload, isRequiredInitializedParameter, isOptionalUninitializedParameterProperty, + isJSContainerFunctionDeclaration, + getPropertiesOfContainerFunction, createTypeOfDeclaration, createReturnTypeOfSignatureDeclaration, createTypeOfExpression, diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 063b5f1cd1d..9974b60875b 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -971,7 +971,7 @@ namespace ts { } case SyntaxKind.FunctionDeclaration: { // Generators lose their generator-ness, excepting their return type - return cleanup(updateFunctionDeclaration( + const clean = cleanup(updateFunctionDeclaration( input, /*decorators*/ undefined, ensureModifiers(input, isPrivate), @@ -982,6 +982,21 @@ namespace ts { ensureType(input, input.type), /*body*/ undefined )); + if (clean && resolver.isJSContainerFunctionDeclaration(input)) { + const declarations = mapDefined(resolver.getPropertiesOfContainerFunction(input), p => { + if (!isPropertyAccessExpression(p.valueDeclaration)) { + return undefined; + } + const type = resolver.createTypeOfDeclaration(p.valueDeclaration, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker); + const varDecl = createVariableDeclaration(unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined); + return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([varDecl])); + }); + const namespaceDecl = createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input, isPrivate), input.name!, createModuleBlock(declarations), NodeFlags.Namespace); + return [clean, namespaceDecl]; + } + else { + return clean; + } } case SyntaxKind.ModuleDeclaration: { needsDeclare = false; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4330a776d04..3c66a3a9d57 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3374,7 +3374,9 @@ namespace ts { isImplementationOfOverload(node: FunctionLike): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean; - createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined; + isJSContainerFunctionDeclaration(node: FunctionDeclaration): boolean; + getPropertiesOfContainerFunction(node: Declaration): Symbol[]; + createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined; createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined; createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): Expression; diff --git a/tests/baselines/reference/typeFromPropertyAssignment29.errors.txt b/tests/baselines/reference/typeFromPropertyAssignment29.errors.txt index 173e08e9793..04c4dfc3de6 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment29.errors.txt +++ b/tests/baselines/reference/typeFromPropertyAssignment29.errors.txt @@ -1,15 +1,15 @@ -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(30,14): error TS2339: Property 'prop' does not exist on type '(n: number) => string'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(31,14): error TS2339: Property 'm' does not exist on type '(n: number) => string'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(34,22): error TS2339: Property 'prop' does not exist on type '(n: number) => string'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(34,42): error TS2339: Property 'm' does not exist on type '(n: number) => string'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(40,14): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(41,14): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(44,22): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(44,42): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(50,14): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(51,14): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(54,22): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'. -tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(54,42): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(60,14): error TS2339: Property 'prop' does not exist on type '(n: number) => string'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(61,14): error TS2339: Property 'm' does not exist on type '(n: number) => string'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(64,22): error TS2339: Property 'prop' does not exist on type '(n: number) => string'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(64,42): error TS2339: Property 'm' does not exist on type '(n: number) => string'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(70,14): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(71,14): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(74,22): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(74,42): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(80,14): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(81,14): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(84,22): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'. +tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(84,42): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'. ==== tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts (12 errors) ==== @@ -25,11 +25,12 @@ tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(54,42): error TS23 const ExpandoExpr = function (n: number) { return n.toString(); } - ExpandoExpr.prop = 2 + ExpandoExpr.prop = { x: 2 } + ExpandoExpr.prop = { y: "" } ExpandoExpr.m = function(n: number) { return n + 1; } - var n = ExpandoExpr.prop + ExpandoExpr.m(12) + ExpandoExpr(101).length + var n = (ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) + ExpandoExpr(101).length const ExpandoArrow = (n: number) => n.toString(); ExpandoArrow.prop = 2 @@ -38,6 +39,35 @@ tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts(54,42): error TS23 } + function ExpandoNested(n: number) { + const nested = function (m: number) { + return n + m; + }; + nested.total = n + 1_000_000; + return nested; + } + ExpandoNested.also = -1; + + function ExpandoMerge(n: number) { + return n * 100; + } + ExpandoMerge.p1 = 111 + namespace ExpandoMerge { + export var p2 = 222; + } + namespace ExpandoMerge { + export var p3 = 333; + } + var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge(1); + + namespace Ns { + function ExpandoNamespace(): void {} + ExpandoNamespace.p6 = 42; + export function foo() { + return ExpandoNamespace; + } + } + // Should not work in Typescript -- must be const var ExpandoExpr2 = function (n: number) { return n.toString(); diff --git a/tests/baselines/reference/typeFromPropertyAssignment29.js b/tests/baselines/reference/typeFromPropertyAssignment29.js index d17af851c52..8c2750ebb6d 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment29.js +++ b/tests/baselines/reference/typeFromPropertyAssignment29.js @@ -11,11 +11,12 @@ var n = ExpandoDecl.prop + ExpandoDecl.m(12) + ExpandoDecl(101).length const ExpandoExpr = function (n: number) { return n.toString(); } -ExpandoExpr.prop = 2 +ExpandoExpr.prop = { x: 2 } +ExpandoExpr.prop = { y: "" } ExpandoExpr.m = function(n: number) { return n + 1; } -var n = ExpandoExpr.prop + ExpandoExpr.m(12) + ExpandoExpr(101).length +var n = (ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) + ExpandoExpr(101).length const ExpandoArrow = (n: number) => n.toString(); ExpandoArrow.prop = 2 @@ -24,6 +25,35 @@ ExpandoArrow.m = function(n: number) { } +function ExpandoNested(n: number) { + const nested = function (m: number) { + return n + m; + }; + nested.total = n + 1_000_000; + return nested; +} +ExpandoNested.also = -1; + +function ExpandoMerge(n: number) { + return n * 100; +} +ExpandoMerge.p1 = 111 +namespace ExpandoMerge { + export var p2 = 222; +} +namespace ExpandoMerge { + export var p3 = 333; +} +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge(1); + +namespace Ns { + function ExpandoNamespace(): void {} + ExpandoNamespace.p6 = 42; + export function foo() { + return ExpandoNamespace; + } +} + // Should not work in Typescript -- must be const var ExpandoExpr2 = function (n: number) { return n.toString(); @@ -68,16 +98,45 @@ var n = ExpandoDecl.prop + ExpandoDecl.m(12) + ExpandoDecl(101).length; var ExpandoExpr = function (n) { return n.toString(); }; -ExpandoExpr.prop = 2; +ExpandoExpr.prop = { x: 2 }; +ExpandoExpr.prop = { y: "" }; ExpandoExpr.m = function (n) { return n + 1; }; -var n = ExpandoExpr.prop + ExpandoExpr.m(12) + ExpandoExpr(101).length; +var n = (ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) + ExpandoExpr(101).length; var ExpandoArrow = function (n) { return n.toString(); }; ExpandoArrow.prop = 2; ExpandoArrow.m = function (n) { return n + 1; }; +function ExpandoNested(n) { + var nested = function (m) { + return n + m; + }; + nested.total = n + 1000000; + return nested; +} +ExpandoNested.also = -1; +function ExpandoMerge(n) { + return n * 100; +} +ExpandoMerge.p1 = 111; +(function (ExpandoMerge) { + ExpandoMerge.p2 = 222; +})(ExpandoMerge || (ExpandoMerge = {})); +(function (ExpandoMerge) { + ExpandoMerge.p3 = 333; +})(ExpandoMerge || (ExpandoMerge = {})); +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge(1); +var Ns; +(function (Ns) { + function ExpandoNamespace() { } + ExpandoNamespace.p6 = 42; + function foo() { + return ExpandoNamespace; + } + Ns.foo = foo; +})(Ns || (Ns = {})); // Should not work in Typescript -- must be const var ExpandoExpr2 = function (n) { return n.toString(); @@ -111,3 +170,66 @@ ExpandoExpr3.m = function (n) { return n + 1; }; var n = ExpandoExpr3.prop + ExpandoExpr3.m(13) + new ExpandoExpr3().n; + + +//// [typeFromPropertyAssignment29.d.ts] +declare function ExpandoDecl(n: number): string; +declare namespace ExpandoDecl { + var prop: number; + var m: (n: number) => number; +} +declare var n: number; +declare const ExpandoExpr: { + (n: number): string; + prop: { + x: number; + y?: undefined; + } | { + y: string; + x?: undefined; + }; + m(n: number): number; +}; +declare var n: number; +declare const ExpandoArrow: { + (n: number): string; + prop: number; + m(n: number): number; +}; +declare function ExpandoNested(n: number): { + (m: number): number; + total: number; +}; +declare namespace ExpandoNested { + var also: number; +} +declare function ExpandoMerge(n: number): number; +declare namespace ExpandoMerge { + var p1: number; +} +declare namespace ExpandoMerge { + var p2: number; +} +declare namespace ExpandoMerge { + var p3: number; +} +declare var n: number; +declare namespace Ns { + function ExpandoNamespace(): void; + namespace ExpandoNamespace { + var p6: number; + } + function foo(): typeof ExpandoNamespace; +} +declare var ExpandoExpr2: (n: number) => string; +declare var n: number; +declare class ExpandoClass { + n: number; +} +declare var n: number; +declare var ExpandoExpr3: { + new (): { + n: number; + }; +}; +declare var n: number; diff --git a/tests/baselines/reference/typeFromPropertyAssignment29.symbols b/tests/baselines/reference/typeFromPropertyAssignment29.symbols index 4435e67886f..2e51e26304b 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment29.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment29.symbols @@ -23,7 +23,7 @@ ExpandoDecl.m = function(n: number) { >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 4, 25)) } var n = ExpandoDecl.prop + ExpandoDecl.m(12) + ExpandoDecl(101).length ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 16, 3), Decl(typeFromPropertyAssignment29.ts, 33, 3), Decl(typeFromPropertyAssignment29.ts, 43, 3), Decl(typeFromPropertyAssignment29.ts, 53, 3)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) >ExpandoDecl.prop : Symbol(ExpandoDecl.prop, Decl(typeFromPropertyAssignment29.ts, 2, 1)) >ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 3, 20)) >prop : Symbol(ExpandoDecl.prop, Decl(typeFromPropertyAssignment29.ts, 2, 1)) @@ -35,7 +35,7 @@ var n = ExpandoDecl.prop + ExpandoDecl.m(12) + ExpandoDecl(101).length >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) const ExpandoExpr = function (n: number) { ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 12, 20)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 9, 30)) return n.toString(); @@ -43,131 +43,223 @@ const ExpandoExpr = function (n: number) { >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 9, 30)) >toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) } -ExpandoExpr.prop = 2 ->ExpandoExpr.prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 12, 20)) ->prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1)) +ExpandoExpr.prop = { x: 2 } +>ExpandoExpr.prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) +>x : Symbol(x, Decl(typeFromPropertyAssignment29.ts, 12, 20)) + +ExpandoExpr.prop = { y: "" } +>ExpandoExpr.prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) +>y : Symbol(y, Decl(typeFromPropertyAssignment29.ts, 13, 20)) ExpandoExpr.m = function(n: number) { ->ExpandoExpr.m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 12, 20)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 12, 20)) ->m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 12, 20)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 13, 25)) +>ExpandoExpr.m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 14, 25)) return n + 1; ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 13, 25)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 14, 25)) } -var n = ExpandoExpr.prop + ExpandoExpr.m(12) + ExpandoExpr(101).length ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 16, 3), Decl(typeFromPropertyAssignment29.ts, 33, 3), Decl(typeFromPropertyAssignment29.ts, 43, 3), Decl(typeFromPropertyAssignment29.ts, 53, 3)) ->ExpandoExpr.prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 12, 20)) ->prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1)) ->ExpandoExpr.m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 12, 20)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 12, 20)) ->m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 12, 20)) +var n = (ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) + ExpandoExpr(101).length +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) +>ExpandoExpr.prop.x : Symbol(x, Decl(typeFromPropertyAssignment29.ts, 12, 20)) +>ExpandoExpr.prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) +>x : Symbol(x, Decl(typeFromPropertyAssignment29.ts, 12, 20)) +>ExpandoExpr.m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 13, 28)) >ExpandoExpr(101).length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 12, 20)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) const ExpandoArrow = (n: number) => n.toString(); ->ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 18, 5), Decl(typeFromPropertyAssignment29.ts, 19, 21)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 18, 22)) +>ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 20, 21)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 19, 22)) >n.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 18, 22)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 19, 22)) >toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) ExpandoArrow.prop = 2 ->ExpandoArrow.prop : Symbol(ExpandoArrow.prop, Decl(typeFromPropertyAssignment29.ts, 18, 49)) ->ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 18, 5), Decl(typeFromPropertyAssignment29.ts, 19, 21)) ->prop : Symbol(ExpandoArrow.prop, Decl(typeFromPropertyAssignment29.ts, 18, 49)) +>ExpandoArrow.prop : Symbol(ExpandoArrow.prop, Decl(typeFromPropertyAssignment29.ts, 19, 49)) +>ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 20, 21)) +>prop : Symbol(ExpandoArrow.prop, Decl(typeFromPropertyAssignment29.ts, 19, 49)) ExpandoArrow.m = function(n: number) { ->ExpandoArrow.m : Symbol(ExpandoArrow.m, Decl(typeFromPropertyAssignment29.ts, 19, 21)) ->ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 18, 5), Decl(typeFromPropertyAssignment29.ts, 19, 21)) ->m : Symbol(ExpandoArrow.m, Decl(typeFromPropertyAssignment29.ts, 19, 21)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 20, 26)) +>ExpandoArrow.m : Symbol(ExpandoArrow.m, Decl(typeFromPropertyAssignment29.ts, 20, 21)) +>ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 20, 21)) +>m : Symbol(ExpandoArrow.m, Decl(typeFromPropertyAssignment29.ts, 20, 21)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 21, 26)) return n + 1; ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 20, 26)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 21, 26)) } +function ExpandoNested(n: number) { +>ExpandoNested : Symbol(ExpandoNested, Decl(typeFromPropertyAssignment29.ts, 24, 1)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 26, 23)) + + const nested = function (m: number) { +>nested : Symbol(nested, Decl(typeFromPropertyAssignment29.ts, 27, 9)) +>m : Symbol(m, Decl(typeFromPropertyAssignment29.ts, 27, 29)) + + return n + m; +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 26, 23)) +>m : Symbol(m, Decl(typeFromPropertyAssignment29.ts, 27, 29)) + + }; + nested.total = n + 1_000_000; +>nested.total : Symbol(nested.total, Decl(typeFromPropertyAssignment29.ts, 29, 6)) +>nested : Symbol(nested, Decl(typeFromPropertyAssignment29.ts, 27, 9)) +>total : Symbol(nested.total, Decl(typeFromPropertyAssignment29.ts, 29, 6)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 26, 23)) + + return nested; +>nested : Symbol(nested, Decl(typeFromPropertyAssignment29.ts, 27, 9)) +} +ExpandoNested.also = -1; +>ExpandoNested.also : Symbol(ExpandoNested.also, Decl(typeFromPropertyAssignment29.ts, 32, 1)) +>ExpandoNested : Symbol(ExpandoNested, Decl(typeFromPropertyAssignment29.ts, 24, 1)) +>also : Symbol(ExpandoNested.also, Decl(typeFromPropertyAssignment29.ts, 32, 1)) + +function ExpandoMerge(n: number) { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 35, 22)) + + return n * 100; +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 35, 22)) +} +ExpandoMerge.p1 = 111 +>ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment29.ts, 37, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment29.ts, 37, 1)) + +namespace ExpandoMerge { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) + + export var p2 = 222; +>p2 : Symbol(p2, Decl(typeFromPropertyAssignment29.ts, 40, 14)) +} +namespace ExpandoMerge { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) + + export var p3 = 333; +>p3 : Symbol(p3, Decl(typeFromPropertyAssignment29.ts, 43, 14)) +} +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge(1); +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) +>ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment29.ts, 37, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment29.ts, 37, 1)) +>ExpandoMerge.p2 : Symbol(ExpandoMerge.p2, Decl(typeFromPropertyAssignment29.ts, 40, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>p2 : Symbol(ExpandoMerge.p2, Decl(typeFromPropertyAssignment29.ts, 40, 14)) +>ExpandoMerge.p3 : Symbol(ExpandoMerge.p3, Decl(typeFromPropertyAssignment29.ts, 43, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>p3 : Symbol(ExpandoMerge.p3, Decl(typeFromPropertyAssignment29.ts, 43, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) + +namespace Ns { +>Ns : Symbol(Ns, Decl(typeFromPropertyAssignment29.ts, 45, 78)) + + function ExpandoNamespace(): void {} +>ExpandoNamespace : Symbol(ExpandoNamespace, Decl(typeFromPropertyAssignment29.ts, 47, 14)) + + ExpandoNamespace.p6 = 42; +>ExpandoNamespace.p6 : Symbol(ExpandoNamespace.p6, Decl(typeFromPropertyAssignment29.ts, 48, 40)) +>ExpandoNamespace : Symbol(ExpandoNamespace, Decl(typeFromPropertyAssignment29.ts, 47, 14)) +>p6 : Symbol(ExpandoNamespace.p6, Decl(typeFromPropertyAssignment29.ts, 48, 40)) + + export function foo() { +>foo : Symbol(foo, Decl(typeFromPropertyAssignment29.ts, 49, 29)) + + return ExpandoNamespace; +>ExpandoNamespace : Symbol(ExpandoNamespace, Decl(typeFromPropertyAssignment29.ts, 47, 14)) + } +} + // Should not work in Typescript -- must be const var ExpandoExpr2 = function (n: number) { ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 26, 3), Decl(typeFromPropertyAssignment29.ts, 29, 21)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 26, 29)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 56, 29)) return n.toString(); >n.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 26, 29)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 56, 29)) >toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) } ExpandoExpr2.prop = 2 ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 26, 3), Decl(typeFromPropertyAssignment29.ts, 29, 21)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) ExpandoExpr2.m = function(n: number) { ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 26, 3), Decl(typeFromPropertyAssignment29.ts, 29, 21)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 30, 26)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 60, 26)) return n + 1; ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 30, 26)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 60, 26)) } var n = ExpandoExpr2.prop + ExpandoExpr2.m(12) + ExpandoExpr2(101).length ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 16, 3), Decl(typeFromPropertyAssignment29.ts, 33, 3), Decl(typeFromPropertyAssignment29.ts, 43, 3), Decl(typeFromPropertyAssignment29.ts, 53, 3)) ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 26, 3), Decl(typeFromPropertyAssignment29.ts, 29, 21)) ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 26, 3), Decl(typeFromPropertyAssignment29.ts, 29, 21)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) >ExpandoExpr2(101).length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 26, 3), Decl(typeFromPropertyAssignment29.ts, 29, 21)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) // Should not work in typescript -- classes already have statics class ExpandoClass { ->ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 33, 73)) +>ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 63, 73)) n = 1001; ->n : Symbol(ExpandoClass.n, Decl(typeFromPropertyAssignment29.ts, 36, 20)) +>n : Symbol(ExpandoClass.n, Decl(typeFromPropertyAssignment29.ts, 66, 20)) } ExpandoClass.prop = 2 ->ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 33, 73)) +>ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 63, 73)) ExpandoClass.m = function(n: number) { ->ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 33, 73)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 40, 26)) +>ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 63, 73)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 70, 26)) return n + 1; ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 40, 26)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 70, 26)) } var n = ExpandoClass.prop + ExpandoClass.m(12) + new ExpandoClass().n ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 16, 3), Decl(typeFromPropertyAssignment29.ts, 33, 3), Decl(typeFromPropertyAssignment29.ts, 43, 3), Decl(typeFromPropertyAssignment29.ts, 53, 3)) ->ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 33, 73)) ->ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 33, 73)) ->new ExpandoClass().n : Symbol(ExpandoClass.n, Decl(typeFromPropertyAssignment29.ts, 36, 20)) ->ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 33, 73)) ->n : Symbol(ExpandoClass.n, Decl(typeFromPropertyAssignment29.ts, 36, 20)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) +>ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 63, 73)) +>ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 63, 73)) +>new ExpandoClass().n : Symbol(ExpandoClass.n, Decl(typeFromPropertyAssignment29.ts, 66, 20)) +>ExpandoClass : Symbol(ExpandoClass, Decl(typeFromPropertyAssignment29.ts, 63, 73)) +>n : Symbol(ExpandoClass.n, Decl(typeFromPropertyAssignment29.ts, 66, 20)) // Class expressions shouldn't work in typescript either var ExpandoExpr3 = class { ->ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 46, 3)) +>ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 76, 3)) n = 10001; ->n : Symbol(ExpandoExpr3.n, Decl(typeFromPropertyAssignment29.ts, 46, 26)) +>n : Symbol(ExpandoExpr3.n, Decl(typeFromPropertyAssignment29.ts, 76, 26)) } ExpandoExpr3.prop = 3 ->ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 46, 3)) +>ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 76, 3)) ExpandoExpr3.m = function(n: number) { ->ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 46, 3)) ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 50, 26)) +>ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 76, 3)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 80, 26)) return n + 1; ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 50, 26)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 80, 26)) } var n = ExpandoExpr3.prop + ExpandoExpr3.m(13) + new ExpandoExpr3().n ->n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 16, 3), Decl(typeFromPropertyAssignment29.ts, 33, 3), Decl(typeFromPropertyAssignment29.ts, 43, 3), Decl(typeFromPropertyAssignment29.ts, 53, 3)) ->ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 46, 3)) ->ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 46, 3)) ->new ExpandoExpr3().n : Symbol(ExpandoExpr3.n, Decl(typeFromPropertyAssignment29.ts, 46, 26)) ->ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 46, 3)) ->n : Symbol(ExpandoExpr3.n, Decl(typeFromPropertyAssignment29.ts, 46, 26)) +>n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) +>ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 76, 3)) +>ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 76, 3)) +>new ExpandoExpr3().n : Symbol(ExpandoExpr3.n, Decl(typeFromPropertyAssignment29.ts, 76, 26)) +>ExpandoExpr3 : Symbol(ExpandoExpr3, Decl(typeFromPropertyAssignment29.ts, 76, 3)) +>n : Symbol(ExpandoExpr3.n, Decl(typeFromPropertyAssignment29.ts, 76, 26)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment29.types b/tests/baselines/reference/typeFromPropertyAssignment29.types index eaf8ed66123..1421ec885c5 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment29.types +++ b/tests/baselines/reference/typeFromPropertyAssignment29.types @@ -48,8 +48,8 @@ var n = ExpandoDecl.prop + ExpandoDecl.m(12) + ExpandoDecl(101).length >length : number const ExpandoExpr = function (n: number) { ->ExpandoExpr : { (n: number): string; prop: number; m(n: number): number; } ->function (n: number) { return n.toString();} : { (n: number): string; prop: number; m(n: number): number; } +>ExpandoExpr : { (n: number): string; prop: { x: number; y?: undefined; } | { y: string; x?: undefined; }; m(n: number): number; } +>function (n: number) { return n.toString();} : { (n: number): string; prop: { x: number; y?: undefined; } | { y: string; x?: undefined; }; m(n: number): number; } >n : number return n.toString(); @@ -58,17 +58,28 @@ const ExpandoExpr = function (n: number) { >n : number >toString : (radix?: number) => string } -ExpandoExpr.prop = 2 ->ExpandoExpr.prop = 2 : 2 ->ExpandoExpr.prop : number ->ExpandoExpr : { (n: number): string; prop: number; m(n: number): number; } ->prop : number +ExpandoExpr.prop = { x: 2 } +>ExpandoExpr.prop = { x: 2 } : { x: number; } +>ExpandoExpr.prop : { x: number; y?: undefined; } | { y: string; x?: undefined; } +>ExpandoExpr : { (n: number): string; prop: { x: number; y?: undefined; } | { y: string; x?: undefined; }; m(n: number): number; } +>prop : { x: number; y?: undefined; } | { y: string; x?: undefined; } +>{ x: 2 } : { x: number; } +>x : number >2 : 2 +ExpandoExpr.prop = { y: "" } +>ExpandoExpr.prop = { y: "" } : { y: string; } +>ExpandoExpr.prop : { x: number; y?: undefined; } | { y: string; x?: undefined; } +>ExpandoExpr : { (n: number): string; prop: { x: number; y?: undefined; } | { y: string; x?: undefined; }; m(n: number): number; } +>prop : { x: number; y?: undefined; } | { y: string; x?: undefined; } +>{ y: "" } : { y: string; } +>y : string +>"" : "" + ExpandoExpr.m = function(n: number) { >ExpandoExpr.m = function(n: number) { return n + 1;} : (n: number) => number >ExpandoExpr.m : (n: number) => number ->ExpandoExpr : { (n: number): string; prop: number; m(n: number): number; } +>ExpandoExpr : { (n: number): string; prop: { x: number; y?: undefined; } | { y: string; x?: undefined; }; m(n: number): number; } >m : (n: number) => number >function(n: number) { return n + 1;} : (n: number) => number >n : number @@ -78,21 +89,26 @@ ExpandoExpr.m = function(n: number) { >n : number >1 : 1 } -var n = ExpandoExpr.prop + ExpandoExpr.m(12) + ExpandoExpr(101).length +var n = (ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) + ExpandoExpr(101).length >n : number ->ExpandoExpr.prop + ExpandoExpr.m(12) + ExpandoExpr(101).length : number ->ExpandoExpr.prop + ExpandoExpr.m(12) : number ->ExpandoExpr.prop : number ->ExpandoExpr : { (n: number): string; prop: number; m(n: number): number; } ->prop : number +>(ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) + ExpandoExpr(101).length : number +>(ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) : number +>(ExpandoExpr.prop.x || 0) : 0 +>ExpandoExpr.prop.x || 0 : 0 +>ExpandoExpr.prop.x : undefined +>ExpandoExpr.prop : { y: string; x?: undefined; } +>ExpandoExpr : { (n: number): string; prop: { x: number; y?: undefined; } | { y: string; x?: undefined; }; m(n: number): number; } +>prop : { y: string; x?: undefined; } +>x : undefined +>0 : 0 >ExpandoExpr.m(12) : number >ExpandoExpr.m : (n: number) => number ->ExpandoExpr : { (n: number): string; prop: number; m(n: number): number; } +>ExpandoExpr : { (n: number): string; prop: { x: number; y?: undefined; } | { y: string; x?: undefined; }; m(n: number): number; } >m : (n: number) => number >12 : 12 >ExpandoExpr(101).length : number >ExpandoExpr(101) : string ->ExpandoExpr : { (n: number): string; prop: number; m(n: number): number; } +>ExpandoExpr : { (n: number): string; prop: { x: number; y?: undefined; } | { y: string; x?: undefined; }; m(n: number): number; } >101 : 101 >length : number @@ -127,6 +143,110 @@ ExpandoArrow.m = function(n: number) { } +function ExpandoNested(n: number) { +>ExpandoNested : { (n: number): { (m: number): number; total: number; }; also: number; } +>n : number + + const nested = function (m: number) { +>nested : { (m: number): number; total: number; } +>function (m: number) { return n + m; } : { (m: number): number; total: number; } +>m : number + + return n + m; +>n + m : number +>n : number +>m : number + + }; + nested.total = n + 1_000_000; +>nested.total = n + 1_000_000 : number +>nested.total : number +>nested : { (m: number): number; total: number; } +>total : number +>n + 1_000_000 : number +>n : number +>1_000_000 : 1000000 + + return nested; +>nested : { (m: number): number; total: number; } +} +ExpandoNested.also = -1; +>ExpandoNested.also = -1 : -1 +>ExpandoNested.also : number +>ExpandoNested : { (n: number): { (m: number): number; total: number; }; also: number; } +>also : number +>-1 : -1 +>1 : 1 + +function ExpandoMerge(n: number) { +>ExpandoMerge : typeof ExpandoMerge +>n : number + + return n * 100; +>n * 100 : number +>n : number +>100 : 100 +} +ExpandoMerge.p1 = 111 +>ExpandoMerge.p1 = 111 : 111 +>ExpandoMerge.p1 : number +>ExpandoMerge : typeof ExpandoMerge +>p1 : number +>111 : 111 + +namespace ExpandoMerge { +>ExpandoMerge : typeof ExpandoMerge + + export var p2 = 222; +>p2 : number +>222 : 222 +} +namespace ExpandoMerge { +>ExpandoMerge : typeof ExpandoMerge + + export var p3 = 333; +>p3 : number +>333 : 333 +} +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge(1); +>n : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge(1) : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 : number +>ExpandoMerge.p1 : number +>ExpandoMerge : typeof ExpandoMerge +>p1 : number +>ExpandoMerge.p2 : number +>ExpandoMerge : typeof ExpandoMerge +>p2 : number +>ExpandoMerge.p3 : number +>ExpandoMerge : typeof ExpandoMerge +>p3 : number +>ExpandoMerge(1) : number +>ExpandoMerge : typeof ExpandoMerge +>1 : 1 + +namespace Ns { +>Ns : typeof Ns + + function ExpandoNamespace(): void {} +>ExpandoNamespace : { (): void; p6: number; } + + ExpandoNamespace.p6 = 42; +>ExpandoNamespace.p6 = 42 : 42 +>ExpandoNamespace.p6 : number +>ExpandoNamespace : { (): void; p6: number; } +>p6 : number +>42 : 42 + + export function foo() { +>foo : () => { (): void; p6: number; } + + return ExpandoNamespace; +>ExpandoNamespace : { (): void; p6: number; } + } +} + // Should not work in Typescript -- must be const var ExpandoExpr2 = function (n: number) { >ExpandoExpr2 : (n: number) => string diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts index 70199b00398..1882731c8f1 100644 --- a/tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts @@ -1,3 +1,4 @@ +// @declaration: true function ExpandoDecl(n: number) { return n.toString(); } @@ -10,11 +11,12 @@ var n = ExpandoDecl.prop + ExpandoDecl.m(12) + ExpandoDecl(101).length const ExpandoExpr = function (n: number) { return n.toString(); } -ExpandoExpr.prop = 2 +ExpandoExpr.prop = { x: 2 } +ExpandoExpr.prop = { y: "" } ExpandoExpr.m = function(n: number) { return n + 1; } -var n = ExpandoExpr.prop + ExpandoExpr.m(12) + ExpandoExpr(101).length +var n = (ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) + ExpandoExpr(101).length const ExpandoArrow = (n: number) => n.toString(); ExpandoArrow.prop = 2 @@ -23,6 +25,35 @@ ExpandoArrow.m = function(n: number) { } +function ExpandoNested(n: number) { + const nested = function (m: number) { + return n + m; + }; + nested.total = n + 1_000_000; + return nested; +} +ExpandoNested.also = -1; + +function ExpandoMerge(n: number) { + return n * 100; +} +ExpandoMerge.p1 = 111 +namespace ExpandoMerge { + export var p2 = 222; +} +namespace ExpandoMerge { + export var p3 = 333; +} +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge(1); + +namespace Ns { + function ExpandoNamespace(): void {} + ExpandoNamespace.p6 = 42; + export function foo() { + return ExpandoNamespace; + } +} + // Should not work in Typescript -- must be const var ExpandoExpr2 = function (n: number) { return n.toString(); From 0a59da1a2cfe2e035c197f8cf206cdc4eb18f95e Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 27 Aug 2018 10:30:25 -0700 Subject: [PATCH 055/163] In pickLongestCandidateSignature, instantiate using inferred type arguments (#26646) --- src/compiler/checker.ts | 53 ++++++++++++------- .../fourslash/quickInfoCanBeTruncated.ts | 2 +- .../signatureHelpExplicitTypeArguments.ts | 2 +- .../cases/fourslash/signatureHelpInference.ts | 12 +++++ .../fourslash/trailingCommaSignatureHelp.ts | 2 +- 5 files changed, 49 insertions(+), 22 deletions(-) create mode 100644 tests/cases/fourslash/signatureHelpInference.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a3cd01e3583..a551108f75c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18638,7 +18638,7 @@ namespace ts { return getInferredTypes(context); } - function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray, excludeArgument: boolean[] | undefined, context: InferenceContext): Type[] { + function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: ReadonlyArray, excludeArgument: ReadonlyArray | undefined, context: InferenceContext): Type[] { // Clear out all the inference results from the last time inferTypeArguments was called on this context for (const inference of context.inferences) { // As an optimization, we don't have to clear (and later recompute) inferred types @@ -19052,19 +19052,7 @@ namespace ts { // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; - let excludeArgument: boolean[] | undefined; - if (!isDecorator && !isSingleNonGenericCandidate) { - // We do not need to call `getEffectiveArgumentCount` here as it only - // applies when calculating the number of arguments for a decorator. - for (let i = 0; i < args.length; i++) { - if (isContextSensitive(args[i])) { - if (!excludeArgument) { - excludeArgument = new Array(args.length); - } - excludeArgument[i] = true; - } - } - } + let excludeArgument = !isDecorator && !isSingleNonGenericCandidate ? getExcludeArgument(args) : undefined; // The following variables are captured and modified by calls to chooseOverload. // If overload resolution or type argument inference fails, we want to report the @@ -19227,6 +19215,21 @@ namespace ts { } } + function getExcludeArgument(args: ReadonlyArray): boolean[] | undefined { + let excludeArgument: boolean[] | undefined; + // We do not need to call `getEffectiveArgumentCount` here as it only + // applies when calculating the number of arguments for a decorator. + for (let i = 0; i < args.length; i++) { + if (isContextSensitive(args[i])) { + if (!excludeArgument) { + excludeArgument = new Array(args.length); + } + excludeArgument[i] = true; + } + } + return excludeArgument; + } + // No signature was applicable. We have already reported the errors for the invalid signature. // If this is a type resolution session, e.g. Language Service, try to get better information than anySignature. function getCandidateForOverloadFailure( @@ -19305,17 +19308,29 @@ namespace ts { return candidate; } - const typeArgumentNodes: ReadonlyArray = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments || emptyArray : emptyArray; + const typeArgumentNodes: ReadonlyArray | undefined = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined; + const instantiated = typeArgumentNodes + ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isInJavaScriptFile(node))) + : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args); + candidates[bestIndex] = instantiated; + return instantiated; + } + + function getTypeArgumentsFromNodes(typeArgumentNodes: ReadonlyArray, typeParameters: ReadonlyArray, isJs: boolean): ReadonlyArray { const typeArguments = typeArgumentNodes.map(getTypeOfNode); while (typeArguments.length > typeParameters.length) { typeArguments.pop(); } while (typeArguments.length < typeParameters.length) { - typeArguments.push(getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node))); + typeArguments.push(getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isJs)); } - const instantiated = createSignatureInstantiation(candidate, typeArguments); - candidates[bestIndex] = instantiated; - return instantiated; + return typeArguments; + } + + function inferSignatureInstantiationForOverloadFailure(node: CallLikeExpression, typeParameters: ReadonlyArray, candidate: Signature, args: ReadonlyArray): Signature { + const inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); + const typeArgumentTypes = inferTypeArguments(node, candidate, args, getExcludeArgument(args), inferenceContext); + return createSignatureInstantiation(candidate, typeArgumentTypes); } function getLongestCandidateIndex(candidates: Signature[], argsCount: number): number { diff --git a/tests/cases/fourslash/quickInfoCanBeTruncated.ts b/tests/cases/fourslash/quickInfoCanBeTruncated.ts index bdf64323636..25ca216a075 100644 --- a/tests/cases/fourslash/quickInfoCanBeTruncated.ts +++ b/tests/cases/fourslash/quickInfoCanBeTruncated.ts @@ -519,7 +519,7 @@ verify.quickInfoIs(`type Less = "_1" | "_2" | "_3" | "_4" | "_5" | "_6" | "_7" | goTo.marker("3"); verify.signatureHelp({ marker: "3", - text: `f(s: "_0" | "_1" | "_2" | "_3" | "_4" | "_5" | "_6" | "_7" | "_8" | "_9" | "_10" | "_11" | "_12" | "_13" | "_14" | "_15" | "_16" | "_17" | "_18" | "_19" | "_20" | "_21" | "_22" | "_23" | "_24" | ... 474 more ... | "_499", x: never, y: string): void` + text: `f(s: "_499", x: "_0" | "_1" | "_2" | "_3" | "_4" | "_5" | "_6" | "_7" | "_8" | "_9" | "_10" | "_11" | "_12" | "_13" | "_14" | "_15" | "_16" | "_17" | "_18" | "_19" | "_20" | "_21" | "_22" | "_23" | "_24" | ... 473 more ... | "_498", y: string): void` }); goTo.marker("4"); verify.quickInfoIs(`type Decomposed = { diff --git a/tests/cases/fourslash/signatureHelpExplicitTypeArguments.ts b/tests/cases/fourslash/signatureHelpExplicitTypeArguments.ts index 2511cfecc19..b1af18469a8 100644 --- a/tests/cases/fourslash/signatureHelpExplicitTypeArguments.ts +++ b/tests/cases/fourslash/signatureHelpExplicitTypeArguments.ts @@ -8,7 +8,7 @@ verify.signatureHelp( { marker: "1", text: "f(x: number, y: string): number" }, - { marker: "2", text: "f(x: {}, y: {}): {}" }, + { marker: "2", text: "f(x: boolean, y: string): boolean" }, // too few -- fill in rest with {} { marker: "3", text: "f(x: number, y: {}): number" }, // too many -- ignore extra type arguments diff --git a/tests/cases/fourslash/signatureHelpInference.ts b/tests/cases/fourslash/signatureHelpInference.ts new file mode 100644 index 00000000000..186dba9c31d --- /dev/null +++ b/tests/cases/fourslash/signatureHelpInference.ts @@ -0,0 +1,12 @@ +/// + +////declare function f(a: T, b: T, c: T): void; +////f("x", /**/); + +verify.signatureHelp({ + marker: "", + text: 'f(a: "x", b: "x", c: "x"): void', + parameterCount: 3, + parameterName: "b", + parameterSpan: 'b: "x"', +}); diff --git a/tests/cases/fourslash/trailingCommaSignatureHelp.ts b/tests/cases/fourslash/trailingCommaSignatureHelp.ts index 362f7145c03..e22ea1c33d3 100644 --- a/tests/cases/fourslash/trailingCommaSignatureHelp.ts +++ b/tests/cases/fourslash/trailingCommaSignatureHelp.ts @@ -25,6 +25,6 @@ verify.signatureHelp( }, { marker: "b", - text: "f(a: {}): {}", + text: "f(a: 2): 2", }, ); From 0dbad04c3fa77c4a41c78d559ffd5aa1e1ee4b1c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 27 Aug 2018 13:32:01 -0700 Subject: [PATCH 056/163] Distribute indexed accesses when simplifying them (#26281) * unknownify accesses * Move to simplify to break less with fewer changes * Accept baselines for now * Always propegate any as an index type * Fix flow control in the presence of simplifiable types * Add spy repro from #25181 * Retain errorType when it is used as a marker for the lack of a constraint * Small refinement * Add new test * Move most potentially recursive types from isIdenticalTo into structuredTypeRelatedTo to match the non-identity relations * Fix nits * Doesnt need to be undefineable at all --- src/compiler/checker.ts | 157 ++++++++---------- .../reference/assignmentCompatForEnums.types | 2 +- ...entedTypeBracketAccessIndexSignature.types | 8 +- ...mentedTypeBracketNamedPropertyAccess.types | 4 +- .../reference/binaryIntegerLiteral.types | 6 +- .../reference/binaryIntegerLiteralES6.types | 6 +- ...larlySimplifyingConditionalTypesNoCrash.js | 55 ++++++ ...SimplifyingConditionalTypesNoCrash.symbols | 154 +++++++++++++++++ ...lySimplifyingConditionalTypesNoCrash.types | 92 ++++++++++ ...onditionalTypesExcessProperties.errors.txt | 10 +- .../reference/defaultIndexProps2.types | 2 +- .../deferredLookupTypeResolution2.errors.txt | 31 ---- tests/baselines/reference/enumBasics.types | 4 +- tests/baselines/reference/enumIndexer.types | 2 +- ...edAccessMethodIntersectionCanBeAccessed.js | 31 ++++ ...essMethodIntersectionCanBeAccessed.symbols | 69 ++++++++ ...ccessMethodIntersectionCanBeAccessed.types | 59 +++++++ .../reference/indexClassByNumber.types | 2 +- .../indexedAccessRelation.errors.txt | 37 +++++ .../reference/indexedAccessRelation.types | 2 +- .../reference/indexingTypesWithNever.types | 4 +- .../limitDeepInstantiations.errors.txt | 5 +- .../reference/limitDeepInstantiations.types | 2 +- ...5LibES6ArrayLibES6WellknownSymbolLib.types | 2 +- .../reference/newWithSpreadES5.types | 18 +- .../reference/newWithSpreadES6.types | 18 +- .../noImplicitAnyIndexingSuppressed.types | 16 +- .../nonPrimitiveIndexingWithForIn.types | 4 +- ...imitiveIndexingWithForInSupressError.types | 4 +- .../reference/numericIndexingResults.types | 28 ++-- ...atureHidingMembersOfExtendedFunction.types | 8 +- ...atureHidingMembersOfExtendedFunction.types | 8 +- ...ringNamedPropertyOfIllegalCharacters.types | 16 +- .../reference/octalIntegerLiteral.types | 6 +- .../reference/octalIntegerLiteralES6.types | 6 +- .../protoAsIndexInIndexExpression.types | 2 +- .../baselines/reference/protoInIndexer.types | 2 +- .../spyComparisonChecking.errors.txt | 29 ++++ .../reference/spyComparisonChecking.js | 34 ++++ .../reference/spyComparisonChecking.symbols | 75 +++++++++ .../reference/spyComparisonChecking.types | 62 +++++++ .../reference/superSymbolIndexedAccess1.types | 4 +- .../reference/superSymbolIndexedAccess5.types | 4 +- .../reference/superSymbolIndexedAccess6.types | 4 +- .../reference/symbolProperty55.types | 2 +- .../reference/symbolProperty56.types | 4 +- .../reference/symbolProperty57.types | 4 +- .../reference/systemJsForInNoException.types | 2 +- .../templateStringInIndexExpression.types | 2 +- .../templateStringInIndexExpressionES6.types | 2 +- ...sIndexOnExistingReadonlyFieldIsNotNever.js | 60 +++++++ ...xOnExistingReadonlyFieldIsNotNever.symbols | 76 +++++++++ ...dexOnExistingReadonlyFieldIsNotNever.types | 57 +++++++ .../reference/unionTypeIndexSignature.types | 20 +-- .../varianceCallbacksAndIndexedAccesses.js | 36 ++++ ...arianceCallbacksAndIndexedAccesses.symbols | 121 ++++++++++++++ .../varianceCallbacksAndIndexedAccesses.types | 81 +++++++++ ...larlySimplifyingConditionalTypesNoCrash.ts | 48 ++++++ ...edAccessMethodIntersectionCanBeAccessed.ts | 20 +++ tests/cases/compiler/spyComparisonChecking.ts | 23 +++ ...sIndexOnExistingReadonlyFieldIsNotNever.ts | 22 +++ .../varianceCallbacksAndIndexedAccesses.ts | 32 ++++ 62 files changed, 1462 insertions(+), 244 deletions(-) create mode 100644 tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.js create mode 100644 tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.symbols create mode 100644 tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.types delete mode 100644 tests/baselines/reference/deferredLookupTypeResolution2.errors.txt create mode 100644 tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.js create mode 100644 tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.symbols create mode 100644 tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.types create mode 100644 tests/baselines/reference/indexedAccessRelation.errors.txt create mode 100644 tests/baselines/reference/spyComparisonChecking.errors.txt create mode 100644 tests/baselines/reference/spyComparisonChecking.js create mode 100644 tests/baselines/reference/spyComparisonChecking.symbols create mode 100644 tests/baselines/reference/spyComparisonChecking.types create mode 100644 tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.js create mode 100644 tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.symbols create mode 100644 tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.types create mode 100644 tests/baselines/reference/varianceCallbacksAndIndexedAccesses.js create mode 100644 tests/baselines/reference/varianceCallbacksAndIndexedAccesses.symbols create mode 100644 tests/baselines/reference/varianceCallbacksAndIndexedAccesses.types create mode 100644 tests/cases/compiler/circularlySimplifyingConditionalTypesNoCrash.ts create mode 100644 tests/cases/compiler/genericIndexedAccessMethodIntersectionCanBeAccessed.ts create mode 100644 tests/cases/compiler/spyComparisonChecking.ts create mode 100644 tests/cases/compiler/thisIndexOnExistingReadonlyFieldIsNotNever.ts create mode 100644 tests/cases/compiler/varianceCallbacksAndIndexedAccesses.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a551108f75c..9c0f3cd643f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6901,7 +6901,7 @@ namespace ts { function getConstraintOfIndexedAccess(type: IndexedAccessType) { const objectType = getBaseConstraintOfType(type.objectType) || type.objectType; const indexType = getBaseConstraintOfType(type.indexType) || type.indexType; - const constraint = !isGenericObjectType(objectType) && !isGenericIndexType(indexType) ? getIndexedAccessType(objectType, indexType) : undefined; + const constraint = !isGenericObjectType(objectType) && !isGenericIndexType(indexType) ? getIndexedAccessType(objectType, indexType, /*accessNode*/ undefined, errorType) : undefined; return constraint && constraint !== errorType ? constraint : undefined; } @@ -7064,7 +7064,7 @@ namespace ts { if (t.flags & TypeFlags.IndexedAccess) { const baseObjectType = getBaseConstraint((t).objectType); const baseIndexType = getBaseConstraint((t).indexType); - const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; + const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType, /*accessNode*/ undefined, errorType) : undefined; return baseIndexedAccess && baseIndexedAccess !== errorType ? getBaseConstraint(baseIndexedAccess) : undefined; } if (t.flags & TypeFlags.Conditional) { @@ -9149,7 +9149,7 @@ namespace ts { return false; } - function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | undefined, cacheSymbol: boolean) { + function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | undefined, cacheSymbol: boolean, missingType: Type) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; const propName = isTypeUsableAsLateBoundName(indexType) ? getLateBoundNameFromType(indexType) : accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ? @@ -9162,7 +9162,7 @@ namespace ts { markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === SyntaxKind.ThisKeyword); if (isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) { error(accessExpression.argumentExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop)); - return errorType; + return missingType; } if (cacheSymbol) { getNodeLinks(accessNode!).resolvedSymbol = prop; @@ -9221,7 +9221,7 @@ namespace ts { } } } - return anyType; + return missingType; } } if (isJSLiteralType(objectType)) { @@ -9239,7 +9239,10 @@ namespace ts { error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); } } - return errorType; + if (isTypeAny(indexType)) { + return indexType; + } + return missingType; } function isGenericObjectType(type: Type): boolean { @@ -9250,22 +9253,6 @@ namespace ts { return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.Index); } - // Return true if the given type is a non-generic object type with a string index signature and no - // other members. - function isStringIndexOnlyType(type: Type): boolean { - if (type.flags & TypeFlags.Object && !isGenericMappedType(type)) { - const t = resolveStructuredTypeMembers(type); - return t.properties.length === 0 && - t.callSignatures.length === 0 && t.constructSignatures.length === 0 && - !!t.stringIndexInfo && !t.numberIndexInfo; - } - return false; - } - - function isMappedTypeToNever(type: Type): boolean { - return !!(getObjectFlags(type) & ObjectFlags.Mapped) && getTemplateTypeFromMappedType(type as MappedType) === neverType; - } - function getSimplifiedType(type: Type): Type { return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(type) : type; } @@ -9280,35 +9267,12 @@ namespace ts { // We recursively simplify the object type as it may in turn be an indexed access type. For example, with // '{ [P in T]: { [Q in U]: number } }[T][U]' we want to first simplify the inner indexed access type. const objectType = getSimplifiedType(type.objectType); - if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType)) { - // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or - // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a - // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed - // access types with default property values as expressed by D. - if (some((objectType).types, isStringIndexOnlyType)) { - const regularTypes: Type[] = []; - const stringIndexTypes: Type[] = []; - for (const t of (objectType).types) { - if (isStringIndexOnlyType(t)) { - stringIndexTypes.push(getIndexTypeOfType(t, IndexKind.String)!); - } - else { - regularTypes.push(t); - } - } - return type.simplified = getUnionType([ - getSimplifiedType(getIndexedAccessType(getIntersectionType(regularTypes), type.indexType)), - getIntersectionType(stringIndexTypes) - ]); - } - // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or - // more mapped types with a template type `never`, '(U & V & { [P in T]: never })[K]', return a - // transformed type that removes the never-mapped type: '(U & V)[K]'. This mirrors what would happen - // eventually anyway, but it easier to reason about. - if (some((objectType).types, isMappedTypeToNever)) { - const nonNeverTypes = filter((objectType).types, t => !isMappedTypeToNever(t)); - return type.simplified = getSimplifiedType(getIndexedAccessType(getIntersectionType(nonNeverTypes), type.indexType)); - } + const indexType = getSimplifiedType(type.indexType); + if (objectType.flags & TypeFlags.Union) { + return type.simplified = mapType(objectType, t => getSimplifiedType(getIndexedAccessType(t, indexType))); + } + if (objectType.flags & TypeFlags.Intersection) { + return type.simplified = getIntersectionType(map((objectType as IntersectionType).types, t => getSimplifiedType(getIndexedAccessType(t, indexType)))); } // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we @@ -9332,7 +9296,7 @@ namespace ts { return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); } - function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode): Type { + function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode, missingType = accessNode ? errorType : unknownType): Type { if (objectType === wildcardType || indexType === wildcardType) { return wildcardType; } @@ -9360,15 +9324,15 @@ namespace ts { if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Boolean)) { const propTypes: Type[] = []; for (const t of (indexType).types) { - const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false); - if (propType === errorType) { - return errorType; + const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false, missingType); + if (propType === missingType) { + return missingType; } propTypes.push(propType); } return getUnionType(propTypes); } - return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true); + return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true, missingType); } function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) { @@ -10532,8 +10496,12 @@ namespace ts { return false; } + function isOrHasGenericConditional(type: Type): boolean { + return !!(type.flags & TypeFlags.Conditional || (type.flags & TypeFlags.Intersection && some((type as IntersectionType).types, isOrHasGenericConditional))); + } + function elaborateError(node: Expression | undefined, source: Type, target: Type): boolean { - if (!node) return false; + if (!node || isOrHasGenericConditional(target)) return false; switch (node.kind) { case SyntaxKind.JsxExpression: case SyntaxKind.ParenthesizedExpression: @@ -10566,9 +10534,9 @@ namespace ts { let reportedError = false; for (let status = iterator.next(); !status.done; status = iterator.next()) { const { errorNode: prop, innerExpression: next, nameType, errorMessage } = status.value; - const sourcePropType = getIndexedAccessType(source, nameType); - const targetPropType = getIndexedAccessType(target, nameType); - if (!isTypeAssignableTo(sourcePropType, targetPropType)) { + const sourcePropType = getIndexedAccessType(source, nameType, /*accessNode*/ undefined, errorType); + const targetPropType = getIndexedAccessType(target, nameType, /*accessNode*/ undefined, errorType); + if (sourcePropType !== errorType && targetPropType !== errorType && !isTypeAssignableTo(sourcePropType, targetPropType)) { const elaborated = next && elaborateError(next, sourcePropType, targetPropType); if (elaborated) { reportedError = true; @@ -11287,7 +11255,7 @@ namespace ts { function isIdenticalTo(source: Type, target: Type): Ternary { let result: Ternary; const flags = source.flags & target.flags; - if (flags & TypeFlags.Object) { + if (flags & TypeFlags.Object || flags & TypeFlags.IndexedAccess || flags & TypeFlags.Conditional || flags & TypeFlags.Index || flags & TypeFlags.Substitution) { return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false); } if (flags & (TypeFlags.Union | TypeFlags.Intersection)) { @@ -11297,32 +11265,6 @@ namespace ts { } } } - if (flags & TypeFlags.Index) { - return isRelatedTo((source).type, (target).type, /*reportErrors*/ false); - } - if (flags & TypeFlags.IndexedAccess) { - if (result = isRelatedTo((source).objectType, (target).objectType, /*reportErrors*/ false)) { - if (result &= isRelatedTo((source).indexType, (target).indexType, /*reportErrors*/ false)) { - return result; - } - } - } - if (flags & TypeFlags.Conditional) { - if ((source).root.isDistributive === (target).root.isDistributive) { - if (result = isRelatedTo((source).checkType, (target).checkType, /*reportErrors*/ false)) { - if (result &= isRelatedTo((source).extendsType, (target).extendsType, /*reportErrors*/ false)) { - if (result &= isRelatedTo(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target), /*reportErrors*/ false)) { - if (result &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), /*reportErrors*/ false)) { - return result; - } - } - } - } - } - } - if (flags & TypeFlags.Substitution) { - return isRelatedTo((source).substitute, (target).substitute, /*reportErrors*/ false); - } return Ternary.False; } @@ -11634,6 +11576,37 @@ namespace ts { } function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary { + const flags = source.flags & target.flags; + if (relation === identityRelation && !(flags & TypeFlags.Object)) { + if (flags & TypeFlags.Index) { + return isRelatedTo((source).type, (target).type, /*reportErrors*/ false); + } + let result = Ternary.False; + if (flags & TypeFlags.IndexedAccess) { + if (result = isRelatedTo((source).objectType, (target).objectType, /*reportErrors*/ false)) { + if (result &= isRelatedTo((source).indexType, (target).indexType, /*reportErrors*/ false)) { + return result; + } + } + } + if (flags & TypeFlags.Conditional) { + if ((source).root.isDistributive === (target).root.isDistributive) { + if (result = isRelatedTo((source).checkType, (target).checkType, /*reportErrors*/ false)) { + if (result &= isRelatedTo((source).extendsType, (target).extendsType, /*reportErrors*/ false)) { + if (result &= isRelatedTo(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target), /*reportErrors*/ false)) { + if (result &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), /*reportErrors*/ false)) { + return result; + } + } + } + } + } + } + if (flags & TypeFlags.Substitution) { + return isRelatedTo((source).substitute, (target).substitute, /*reportErrors*/ false); + } + return Ternary.False; + } let result: Ternary; let originalErrorInfo: DiagnosticMessageChain | undefined; const saveErrorInfo = errorInfo; @@ -14151,10 +14124,10 @@ namespace ts { getInitialTypeOfBindingElement(node); } - function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression) { - return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ? + function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression, reference: Node) { + return getConstraintForLocation(node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ? getInitialType(node) : - getAssignedType(node); + getAssignedType(node), reference); } function isEmptyArrayAssignment(node: VariableDeclaration | BindingElement | Expression) { @@ -14540,11 +14513,11 @@ namespace ts { if (isEmptyArrayAssignment(node)) { return getEvolvingArrayType(neverType); } - const assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node)); + const assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node, reference)); return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType; } if (declaredType.flags & TypeFlags.Union) { - return getAssignmentReducedType(declaredType, getInitialOrAssignedType(node)); + return getAssignmentReducedType(declaredType, getInitialOrAssignedType(node, reference)); } return declaredType; } diff --git a/tests/baselines/reference/assignmentCompatForEnums.types b/tests/baselines/reference/assignmentCompatForEnums.types index 8d2fdf0a8b3..6ad83f3d75e 100644 --- a/tests/baselines/reference/assignmentCompatForEnums.types +++ b/tests/baselines/reference/assignmentCompatForEnums.types @@ -23,7 +23,7 @@ function foo() { var x: TokenType = list['one']; >x : TokenType ->list['one'] : any +>list['one'] : error >list : {} >'one' : "one" } diff --git a/tests/baselines/reference/augmentedTypeBracketAccessIndexSignature.types b/tests/baselines/reference/augmentedTypeBracketAccessIndexSignature.types index eb23cfaa9e6..62e04728b39 100644 --- a/tests/baselines/reference/augmentedTypeBracketAccessIndexSignature.types +++ b/tests/baselines/reference/augmentedTypeBracketAccessIndexSignature.types @@ -16,14 +16,14 @@ interface Function { } var a = {}[0]; // Should be Foo ->a : any ->{}[0] : any +>a : error +>{}[0] : error >{} : {} >0 : 0 var b = (() => { })[0]; // Should be Bar ->b : any ->(() => { })[0] : any +>b : error +>(() => { })[0] : error >(() => { }) : () => void >() => { } : () => void >0 : 0 diff --git a/tests/baselines/reference/augmentedTypeBracketNamedPropertyAccess.types b/tests/baselines/reference/augmentedTypeBracketNamedPropertyAccess.types index eb90adefde2..81291506485 100644 --- a/tests/baselines/reference/augmentedTypeBracketNamedPropertyAccess.types +++ b/tests/baselines/reference/augmentedTypeBracketNamedPropertyAccess.types @@ -22,8 +22,8 @@ var r1 = o['data']; // Should be number >'data' : "data" var r2 = o['functionData']; // Should be any (no property found) ->r2 : any ->o['functionData'] : any +>r2 : error +>o['functionData'] : error >o : {} >'functionData' : "functionData" diff --git a/tests/baselines/reference/binaryIntegerLiteral.types b/tests/baselines/reference/binaryIntegerLiteral.types index 070ae22d796..1e2fc019e5f 100644 --- a/tests/baselines/reference/binaryIntegerLiteral.types +++ b/tests/baselines/reference/binaryIntegerLiteral.types @@ -79,7 +79,7 @@ obj1["26"]; // string >"26" : "26" obj1["0b11010"]; // any ->obj1["0b11010"] : any +>obj1["0b11010"] : error >obj1 : { 0b11010: string; a: number; bin1: number; b: number; 0B111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111101001010100000010111110001111111111: boolean; } >"0b11010" : "0b11010" @@ -119,7 +119,7 @@ obj2["26"]; // string >"26" : "26" obj2["0B11010"]; // any ->obj2["0B11010"] : any +>obj2["0B11010"] : error >obj2 : { 0B11010: string; a: number; bin2: number; b: number; 0B11111111111111111111111111111111111111111111111101001010100000010111110001111111111: boolean; } >"0B11010" : "0B11010" @@ -149,7 +149,7 @@ obj2["9.671406556917009e+24"]; // boolean >"9.671406556917009e+24" : "9.671406556917009e+24" obj2["Infinity"]; // any ->obj2["Infinity"] : any +>obj2["Infinity"] : error >obj2 : { 0B11010: string; a: number; bin2: number; b: number; 0B11111111111111111111111111111111111111111111111101001010100000010111110001111111111: boolean; } >"Infinity" : "Infinity" diff --git a/tests/baselines/reference/binaryIntegerLiteralES6.types b/tests/baselines/reference/binaryIntegerLiteralES6.types index fe9f65a1f71..78de8bd9fbc 100644 --- a/tests/baselines/reference/binaryIntegerLiteralES6.types +++ b/tests/baselines/reference/binaryIntegerLiteralES6.types @@ -79,7 +79,7 @@ obj1["26"]; // string >"26" : "26" obj1["0b11010"]; // any ->obj1["0b11010"] : any +>obj1["0b11010"] : error >obj1 : { 0b11010: string; a: number; bin1: number; b: number; 0B111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111101001010100000010111110001111111111: boolean; } >"0b11010" : "0b11010" @@ -119,7 +119,7 @@ obj2["26"]; // string >"26" : "26" obj2["0B11010"]; // any ->obj2["0B11010"] : any +>obj2["0B11010"] : error >obj2 : { 0B11010: string; a: number; bin2: number; b: number; 0B11111111111111111111111111111111111111111111111101001010100000010111110001111111111: boolean; } >"0B11010" : "0B11010" @@ -149,7 +149,7 @@ obj2["9.671406556917009e+24"]; // boolean >"9.671406556917009e+24" : "9.671406556917009e+24" obj2["Infinity"]; // any ->obj2["Infinity"] : any +>obj2["Infinity"] : error >obj2 : { 0B11010: string; a: number; bin2: number; b: number; 0B11111111111111111111111111111111111111111111111101001010100000010111110001111111111: boolean; } >"Infinity" : "Infinity" diff --git a/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.js b/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.js new file mode 100644 index 00000000000..724a8f8dbea --- /dev/null +++ b/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.js @@ -0,0 +1,55 @@ +//// [circularlySimplifyingConditionalTypesNoCrash.ts] +type Omit = Pick>; + +type Shared< // Circularly self constraining type, defered thanks to mapping + InjectedProps, + DecorationTargetProps extends Shared + > = { + [P in Extract]: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; + }; + +interface ComponentClass

{ + defaultProps?: Partial

; // Inference target is also mapped _and_ optional +} + +interface InferableComponentEnhancerWithProps { +

>( + component: ComponentClass

+ ): ComponentClass> & TNeedsProps> & { WrappedComponent: ComponentClass

} +} // Then intersected with and indexed via Omit and & + +interface Connect { // Then strictly compared with another signature in its context + ( + mapStateToProps: unknown, + ): InferableComponentEnhancerWithProps; + + ( + mapStateToProps: null | undefined, + mapDispatchToProps: unknown, + mergeProps: null | undefined, + options: unknown + ): InferableComponentEnhancerWithProps; +} + +declare var connect: Connect; + +const myStoreConnect: Connect = function( + mapStateToProps?: any, + mapDispatchToProps?: any, + mergeProps?: any, + options: unknown = {}, +) { + return connect( + mapStateToProps, + mapDispatchToProps, + mergeProps, + options, + ); +}; + +//// [circularlySimplifyingConditionalTypesNoCrash.js] +"use strict"; +var myStoreConnect = function (mapStateToProps, mapDispatchToProps, mergeProps, options) { + if (options === void 0) { options = {}; } + return connect(mapStateToProps, mapDispatchToProps, mergeProps, options); +}; diff --git a/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.symbols b/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.symbols new file mode 100644 index 00000000000..97abdadf2b3 --- /dev/null +++ b/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.symbols @@ -0,0 +1,154 @@ +=== tests/cases/compiler/circularlySimplifyingConditionalTypesNoCrash.ts === +type Omit = Pick>; +>Omit : Symbol(Omit, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 0)) +>T : Symbol(T, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 10)) +>K : Symbol(K, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 12)) +>T : Symbol(T, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 10)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 10)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 10)) +>K : Symbol(K, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 12)) + +type Shared< // Circularly self constraining type, defered thanks to mapping +>Shared : Symbol(Shared, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 63)) + + InjectedProps, +>InjectedProps : Symbol(InjectedProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 2, 12)) + + DecorationTargetProps extends Shared +>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 3, 18)) +>Shared : Symbol(Shared, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 63)) +>InjectedProps : Symbol(InjectedProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 2, 12)) +>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 3, 18)) + + > = { + [P in Extract]: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 6, 9)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>InjectedProps : Symbol(InjectedProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 2, 12)) +>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 3, 18)) +>InjectedProps : Symbol(InjectedProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 2, 12)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 6, 9)) +>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 3, 18)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 6, 9)) +>DecorationTargetProps : Symbol(DecorationTargetProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 3, 18)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 6, 9)) + + }; + +interface ComponentClass

{ +>ComponentClass : Symbol(ComponentClass, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 7, 6)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 9, 25)) + + defaultProps?: Partial

; // Inference target is also mapped _and_ optional +>defaultProps : Symbol(ComponentClass.defaultProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 9, 29)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 9, 25)) +} + +interface InferableComponentEnhancerWithProps { +>InferableComponentEnhancerWithProps : Symbol(InferableComponentEnhancerWithProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 11, 1)) +>TInjectedProps : Symbol(TInjectedProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 13, 46)) +>TNeedsProps : Symbol(TNeedsProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 13, 61)) + +

>( +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 14, 5)) +>Shared : Symbol(Shared, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 63)) +>TInjectedProps : Symbol(TInjectedProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 13, 46)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 14, 5)) + + component: ComponentClass

+>component : Symbol(component, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 14, 42)) +>ComponentClass : Symbol(ComponentClass, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 7, 6)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 14, 5)) + + ): ComponentClass> & TNeedsProps> & { WrappedComponent: ComponentClass

} +>ComponentClass : Symbol(ComponentClass, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 7, 6)) +>Omit : Symbol(Omit, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 0)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 14, 5)) +>Shared : Symbol(Shared, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 0, 63)) +>TInjectedProps : Symbol(TInjectedProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 13, 46)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 14, 5)) +>TNeedsProps : Symbol(TNeedsProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 13, 61)) +>WrappedComponent : Symbol(WrappedComponent, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 16, 81)) +>ComponentClass : Symbol(ComponentClass, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 7, 6)) +>P : Symbol(P, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 14, 5)) + +} // Then intersected with and indexed via Omit and & + +interface Connect { // Then strictly compared with another signature in its context +>Connect : Symbol(Connect, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 17, 1)) + + ( +>TStateProps : Symbol(TStateProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 20, 5)) +>TOwnProps : Symbol(TOwnProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 20, 17)) + + mapStateToProps: unknown, +>mapStateToProps : Symbol(mapStateToProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 20, 29)) + + ): InferableComponentEnhancerWithProps; +>InferableComponentEnhancerWithProps : Symbol(InferableComponentEnhancerWithProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 11, 1)) +>TStateProps : Symbol(TStateProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 20, 5)) +>TOwnProps : Symbol(TOwnProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 20, 17)) + + ( +>TDispatchProps : Symbol(TDispatchProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 24, 5)) +>TOwnProps : Symbol(TOwnProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 24, 20)) + + mapStateToProps: null | undefined, +>mapStateToProps : Symbol(mapStateToProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 24, 32)) + + mapDispatchToProps: unknown, +>mapDispatchToProps : Symbol(mapDispatchToProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 25, 42)) + + mergeProps: null | undefined, +>mergeProps : Symbol(mergeProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 26, 36)) + + options: unknown +>options : Symbol(options, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 27, 37)) + + ): InferableComponentEnhancerWithProps; +>InferableComponentEnhancerWithProps : Symbol(InferableComponentEnhancerWithProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 11, 1)) +>TDispatchProps : Symbol(TDispatchProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 24, 5)) +>TOwnProps : Symbol(TOwnProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 24, 20)) +} + +declare var connect: Connect; +>connect : Symbol(connect, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 32, 11)) +>Connect : Symbol(Connect, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 17, 1)) + +const myStoreConnect: Connect = function( +>myStoreConnect : Symbol(myStoreConnect, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 34, 5)) +>Connect : Symbol(Connect, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 17, 1)) + + mapStateToProps?: any, +>mapStateToProps : Symbol(mapStateToProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 34, 41)) + + mapDispatchToProps?: any, +>mapDispatchToProps : Symbol(mapDispatchToProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 35, 26)) + + mergeProps?: any, +>mergeProps : Symbol(mergeProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 36, 29)) + + options: unknown = {}, +>options : Symbol(options, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 37, 21)) + +) { + return connect( +>connect : Symbol(connect, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 32, 11)) + + mapStateToProps, +>mapStateToProps : Symbol(mapStateToProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 34, 41)) + + mapDispatchToProps, +>mapDispatchToProps : Symbol(mapDispatchToProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 35, 26)) + + mergeProps, +>mergeProps : Symbol(mergeProps, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 36, 29)) + + options, +>options : Symbol(options, Decl(circularlySimplifyingConditionalTypesNoCrash.ts, 37, 21)) + + ); +}; diff --git a/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.types b/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.types new file mode 100644 index 00000000000..4a3a1fdbe53 --- /dev/null +++ b/tests/baselines/reference/circularlySimplifyingConditionalTypesNoCrash.types @@ -0,0 +1,92 @@ +=== tests/cases/compiler/circularlySimplifyingConditionalTypesNoCrash.ts === +type Omit = Pick>; +>Omit : Pick> + +type Shared< // Circularly self constraining type, defered thanks to mapping +>Shared : Shared + + InjectedProps, + DecorationTargetProps extends Shared + > = { + [P in Extract]: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; + }; + +interface ComponentClass

{ + defaultProps?: Partial

; // Inference target is also mapped _and_ optional +>defaultProps : Partial

| undefined +} + +interface InferableComponentEnhancerWithProps { +

>( + component: ComponentClass

+>component : ComponentClass

+ + ): ComponentClass> & TNeedsProps> & { WrappedComponent: ComponentClass

} +>WrappedComponent : ComponentClass

+ +} // Then intersected with and indexed via Omit and & + +interface Connect { // Then strictly compared with another signature in its context + ( + mapStateToProps: unknown, +>mapStateToProps : unknown + + ): InferableComponentEnhancerWithProps; + + ( + mapStateToProps: null | undefined, +>mapStateToProps : null | undefined +>null : null + + mapDispatchToProps: unknown, +>mapDispatchToProps : unknown + + mergeProps: null | undefined, +>mergeProps : null | undefined +>null : null + + options: unknown +>options : unknown + + ): InferableComponentEnhancerWithProps; +} + +declare var connect: Connect; +>connect : Connect + +const myStoreConnect: Connect = function( +>myStoreConnect : Connect +>function( mapStateToProps?: any, mapDispatchToProps?: any, mergeProps?: any, options: unknown = {},) { return connect( mapStateToProps, mapDispatchToProps, mergeProps, options, );} : (mapStateToProps?: any, mapDispatchToProps?: any, mergeProps?: any, options?: unknown) => InferableComponentEnhancerWithProps<{}, {}> + + mapStateToProps?: any, +>mapStateToProps : any + + mapDispatchToProps?: any, +>mapDispatchToProps : any + + mergeProps?: any, +>mergeProps : any + + options: unknown = {}, +>options : unknown +>{} : {} + +) { + return connect( +>connect( mapStateToProps, mapDispatchToProps, mergeProps, options, ) : InferableComponentEnhancerWithProps<{}, {}> +>connect : Connect + + mapStateToProps, +>mapStateToProps : any + + mapDispatchToProps, +>mapDispatchToProps : any + + mergeProps, +>mergeProps : any + + options, +>options : unknown + + ); +}; diff --git a/tests/baselines/reference/conditionalTypesExcessProperties.errors.txt b/tests/baselines/reference/conditionalTypesExcessProperties.errors.txt index a01cb8c8986..54e8c8742a7 100644 --- a/tests/baselines/reference/conditionalTypesExcessProperties.errors.txt +++ b/tests/baselines/reference/conditionalTypesExcessProperties.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/types/conditional/conditionalTypesExcessProperties.ts(8,5): error TS2322: Type '{ test: string; arg: A; }' is not assignable to type 'Something'. Type '{ test: string; arg: A; }' is not assignable to type 'A extends object ? { arg: A; } : { arg?: undefined; }'. -tests/cases/conformance/types/conditional/conditionalTypesExcessProperties.ts(9,33): error TS2322: Type 'A' is not assignable to type 'Something["arr"]'. - Type 'object' is not assignable to type 'Something["arr"]'. +tests/cases/conformance/types/conditional/conditionalTypesExcessProperties.ts(9,33): error TS2322: Type '{ test: string; arg: A; arr: A; }' is not assignable to type 'Something'. + Object literal may only specify known properties, and 'arr' does not exist in type 'Something'. ==== tests/cases/conformance/types/conditional/conditionalTypesExcessProperties.ts (2 errors) ==== @@ -17,8 +17,8 @@ tests/cases/conformance/types/conditional/conditionalTypesExcessProperties.ts(9, !!! error TS2322: Type '{ test: string; arg: A; }' is not assignable to type 'Something'. !!! error TS2322: Type '{ test: string; arg: A; }' is not assignable to type 'A extends object ? { arg: A; } : { arg?: undefined; }'. sa = { test: 'bye', arg: a, arr: a } // excess - ~~~ -!!! error TS2322: Type 'A' is not assignable to type 'Something["arr"]'. -!!! error TS2322: Type 'object' is not assignable to type 'Something["arr"]'. + ~~~~~~ +!!! error TS2322: Type '{ test: string; arg: A; arr: A; }' is not assignable to type 'Something'. +!!! error TS2322: Object literal may only specify known properties, and 'arr' does not exist in type 'Something'. } \ No newline at end of file diff --git a/tests/baselines/reference/defaultIndexProps2.types b/tests/baselines/reference/defaultIndexProps2.types index a50e4af450e..28c49de3f89 100644 --- a/tests/baselines/reference/defaultIndexProps2.types +++ b/tests/baselines/reference/defaultIndexProps2.types @@ -23,7 +23,7 @@ var o = {v:"Yo2"}; // WScript.Echo(o[0]); 1[0]; ->1[0] : any +>1[0] : error >1 : 1 >0 : 0 diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt b/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt deleted file mode 100644 index 88bcd2c4340..00000000000 --- a/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt +++ /dev/null @@ -1,31 +0,0 @@ -tests/cases/compiler/deferredLookupTypeResolution2.ts(14,13): error TS2536: Type '({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. -tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. - - -==== tests/cases/compiler/deferredLookupTypeResolution2.ts (2 errors) ==== - // Repro from #17456 - - type StringContains = ({ [K in S]: 'true' } & { [key: string]: 'false'})[L]; - - type ObjectHasKey = StringContains, L>; - - type A = ObjectHasKey; - - type B = ObjectHasKey<[string, number], '1'>; // "true" - type C = ObjectHasKey<[string, number], '2'>; // "false" - type D = A<[string]>; // "true" - - // Error, "false" not handled - type E = { true: 'true' }[ObjectHasKey]; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2536: Type '({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. - - type Juxtapose = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey]; - - // Error, "otherwise" is missing - type DeepError = { true: 'true' }[Juxtapose]; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. - - type DeepOK = { true: 'true', otherwise: 'false' }[Juxtapose]; - \ No newline at end of file diff --git a/tests/baselines/reference/enumBasics.types b/tests/baselines/reference/enumBasics.types index 697d5b40f6f..0ca967cc258 100644 --- a/tests/baselines/reference/enumBasics.types +++ b/tests/baselines/reference/enumBasics.types @@ -141,7 +141,7 @@ enum E7 { A = 'foo'['foo'] >A : E7 ->'foo'['foo'] : any +>'foo'['foo'] : error >'foo' : "foo" >'foo' : "foo" } @@ -152,7 +152,7 @@ enum E8 { B = 'foo'['foo'] >B : E8 ->'foo'['foo'] : any +>'foo'['foo'] : error >'foo' : "foo" >'foo' : "foo" } diff --git a/tests/baselines/reference/enumIndexer.types b/tests/baselines/reference/enumIndexer.types index 6c6e50822b5..a47e9da8c9a 100644 --- a/tests/baselines/reference/enumIndexer.types +++ b/tests/baselines/reference/enumIndexer.types @@ -31,7 +31,7 @@ var x = _arr.map(o => MyEnumType[o.key] === enumValue); // these are not same ty >o => MyEnumType[o.key] === enumValue : (o: { key: string; }) => boolean >o : { key: string; } >MyEnumType[o.key] === enumValue : boolean ->MyEnumType[o.key] : any +>MyEnumType[o.key] : error >MyEnumType : typeof MyEnumType >o.key : string >o : { key: string; } diff --git a/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.js b/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.js new file mode 100644 index 00000000000..091fd6abbd0 --- /dev/null +++ b/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.js @@ -0,0 +1,31 @@ +//// [genericIndexedAccessMethodIntersectionCanBeAccessed.ts] +type ExtendedService = { + [K in keyof T]: T[K] & { + __$daemonMode?: string; + __$action?: string; + }; +}; + +type Service = { + [K in keyof T]: T[K] & {id?: string}; +}; + +export const createService = ( + ServiceCtr: ExtendedService & Service +) => { + Object.keys(ServiceCtr).forEach(key => { + const method = (ServiceCtr)[key as keyof T]; + const {__$daemonMode, __$action, id} = method; + }) +} + + +//// [genericIndexedAccessMethodIntersectionCanBeAccessed.js] +"use strict"; +exports.__esModule = true; +exports.createService = function (ServiceCtr) { + Object.keys(ServiceCtr).forEach(function (key) { + var method = (ServiceCtr)[key]; + var __$daemonMode = method.__$daemonMode, __$action = method.__$action, id = method.id; + }); +}; diff --git a/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.symbols b/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.symbols new file mode 100644 index 00000000000..2b619c997dc --- /dev/null +++ b/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.symbols @@ -0,0 +1,69 @@ +=== tests/cases/compiler/genericIndexedAccessMethodIntersectionCanBeAccessed.ts === +type ExtendedService = { +>ExtendedService : Symbol(ExtendedService, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 0, 0)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 0, 21)) + + [K in keyof T]: T[K] & { +>K : Symbol(K, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 1, 5)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 0, 21)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 0, 21)) +>K : Symbol(K, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 1, 5)) + + __$daemonMode?: string; +>__$daemonMode : Symbol(__$daemonMode, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 1, 28)) + + __$action?: string; +>__$action : Symbol(__$action, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 2, 31)) + + }; +}; + +type Service = { +>Service : Symbol(Service, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 5, 2)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 7, 13)) + + [K in keyof T]: T[K] & {id?: string}; +>K : Symbol(K, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 8, 5)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 7, 13)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 7, 13)) +>K : Symbol(K, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 8, 5)) +>id : Symbol(id, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 8, 28)) + +}; + +export const createService = ( +>createService : Symbol(createService, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 11, 12)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 11, 30)) + + ServiceCtr: ExtendedService & Service +>ServiceCtr : Symbol(ServiceCtr, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 11, 33)) +>ExtendedService : Symbol(ExtendedService, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 0, 0)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 11, 30)) +>Service : Symbol(Service, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 5, 2)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 11, 30)) + +) => { + Object.keys(ServiceCtr).forEach(key => { +>Object.keys(ServiceCtr).forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --)) +>ServiceCtr : Symbol(ServiceCtr, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 11, 33)) +>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) +>key : Symbol(key, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 14, 36)) + + const method = (ServiceCtr)[key as keyof T]; +>method : Symbol(method, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 15, 13)) +>ServiceCtr : Symbol(ServiceCtr, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 11, 33)) +>key : Symbol(key, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 14, 36)) +>T : Symbol(T, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 11, 30)) + + const {__$daemonMode, __$action, id} = method; +>__$daemonMode : Symbol(__$daemonMode, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 16, 15)) +>__$action : Symbol(__$action, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 16, 29)) +>id : Symbol(id, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 16, 40)) +>method : Symbol(method, Decl(genericIndexedAccessMethodIntersectionCanBeAccessed.ts, 15, 13)) + + }) +} + diff --git a/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.types b/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.types new file mode 100644 index 00000000000..d16a75912f4 --- /dev/null +++ b/tests/baselines/reference/genericIndexedAccessMethodIntersectionCanBeAccessed.types @@ -0,0 +1,59 @@ +=== tests/cases/compiler/genericIndexedAccessMethodIntersectionCanBeAccessed.ts === +type ExtendedService = { +>ExtendedService : ExtendedService + + [K in keyof T]: T[K] & { + __$daemonMode?: string; +>__$daemonMode : string | undefined + + __$action?: string; +>__$action : string | undefined + + }; +}; + +type Service = { +>Service : Service + + [K in keyof T]: T[K] & {id?: string}; +>id : string | undefined + +}; + +export const createService = ( +>createService : (ServiceCtr: ExtendedService & Service) => void +>( ServiceCtr: ExtendedService & Service) => { Object.keys(ServiceCtr).forEach(key => { const method = (ServiceCtr)[key as keyof T]; const {__$daemonMode, __$action, id} = method; })} : (ServiceCtr: ExtendedService & Service) => void + + ServiceCtr: ExtendedService & Service +>ServiceCtr : ExtendedService & Service + +) => { + Object.keys(ServiceCtr).forEach(key => { +>Object.keys(ServiceCtr).forEach(key => { const method = (ServiceCtr)[key as keyof T]; const {__$daemonMode, __$action, id} = method; }) : void +>Object.keys(ServiceCtr).forEach : (callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void +>Object.keys(ServiceCtr) : string[] +>Object.keys : (o: {}) => string[] +>Object : ObjectConstructor +>keys : (o: {}) => string[] +>ServiceCtr : ExtendedService & Service +>forEach : (callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void +>key => { const method = (ServiceCtr)[key as keyof T]; const {__$daemonMode, __$action, id} = method; } : (key: string) => void +>key : string + + const method = (ServiceCtr)[key as keyof T]; +>method : (ExtendedService & Service)[keyof T] +>(ServiceCtr)[key as keyof T] : (ExtendedService & Service)[keyof T] +>(ServiceCtr) : ExtendedService & Service +>ServiceCtr : ExtendedService & Service +>key as keyof T : keyof T +>key : string + + const {__$daemonMode, __$action, id} = method; +>__$daemonMode : string | undefined +>__$action : string | undefined +>id : string | undefined +>method : (ExtendedService & Service)[keyof T] + + }) +} + diff --git a/tests/baselines/reference/indexClassByNumber.types b/tests/baselines/reference/indexClassByNumber.types index dfd27305ba9..0da451adb36 100644 --- a/tests/baselines/reference/indexClassByNumber.types +++ b/tests/baselines/reference/indexClassByNumber.types @@ -11,7 +11,7 @@ var f = new foo(); f[0] = 4; // Shouldn't be allowed >f[0] = 4 : 4 ->f[0] : any +>f[0] : error >f : foo >0 : 0 >4 : 4 diff --git a/tests/baselines/reference/indexedAccessRelation.errors.txt b/tests/baselines/reference/indexedAccessRelation.errors.txt new file mode 100644 index 00000000000..84e65df856d --- /dev/null +++ b/tests/baselines/reference/indexedAccessRelation.errors.txt @@ -0,0 +1,37 @@ +tests/cases/compiler/indexedAccessRelation.ts(16,23): error TS2345: Argument of type '{ a: T; }' is not assignable to parameter of type 'Pick, "a">'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'S["a"] & T'. + Type 'Foo' is not assignable to type 'S["a"] & T'. + Type 'Foo' is not assignable to type 'S["a"]'. + Type 'T' is not assignable to type 'S["a"]'. + Type 'Foo' is not assignable to type 'S["a"]'. + + +==== tests/cases/compiler/indexedAccessRelation.ts (1 errors) ==== + // Repro from #14723 + + class Component { + setState(state: Pick) {} + } + + export interface State { + a?: T; + } + + class Foo {} + + class Comp extends Component> + { + foo(a: T) { + this.setState({ a: a }); + ~~~~~~~~ +!!! error TS2345: Argument of type '{ a: T; }' is not assignable to parameter of type 'Pick, "a">'. +!!! error TS2345: Types of property 'a' are incompatible. +!!! error TS2345: Type 'T' is not assignable to type 'S["a"] & T'. +!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"] & T'. +!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"]'. +!!! error TS2345: Type 'T' is not assignable to type 'S["a"]'. +!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"]'. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/indexedAccessRelation.types b/tests/baselines/reference/indexedAccessRelation.types index 6d2ee19dda2..180cff338cc 100644 --- a/tests/baselines/reference/indexedAccessRelation.types +++ b/tests/baselines/reference/indexedAccessRelation.types @@ -26,7 +26,7 @@ class Comp extends Component> >a : T this.setState({ a: a }); ->this.setState({ a: a }) : void +>this.setState({ a: a }) : any >this.setState : (state: Pick, K>) => void >this : this >setState : (state: Pick, K>) => void diff --git a/tests/baselines/reference/indexingTypesWithNever.types b/tests/baselines/reference/indexingTypesWithNever.types index 7994116d84c..bf141ae0059 100644 --- a/tests/baselines/reference/indexingTypesWithNever.types +++ b/tests/baselines/reference/indexingTypesWithNever.types @@ -69,8 +69,8 @@ declare function genericFn3< // Should be never const result5 = genericFn3({ g: "gtest", h: "htest" }, "g", "h"); // 'g' & 'h' will reduce to never ->result5 : error ->genericFn3({ g: "gtest", h: "htest" }, "g", "h") : error +>result5 : unknown +>genericFn3({ g: "gtest", h: "htest" }, "g", "h") : unknown >genericFn3 : (obj: T, u: U, v: V) => T[U & V] >{ g: "gtest", h: "htest" } : { g: string; h: string; } >g : string diff --git a/tests/baselines/reference/limitDeepInstantiations.errors.txt b/tests/baselines/reference/limitDeepInstantiations.errors.txt index 2b68b787437..2cf5aade7fd 100644 --- a/tests/baselines/reference/limitDeepInstantiations.errors.txt +++ b/tests/baselines/reference/limitDeepInstantiations.errors.txt @@ -1,7 +1,8 @@ tests/cases/compiler/limitDeepInstantiations.ts(3,35): error TS2502: '"true"' is referenced directly or indirectly in its own type annotation. +tests/cases/compiler/limitDeepInstantiations.ts(5,13): error TS2344: Type '"false"' does not satisfy the constraint '"true"'. -==== tests/cases/compiler/limitDeepInstantiations.ts (1 errors) ==== +==== tests/cases/compiler/limitDeepInstantiations.ts (2 errors) ==== // Repro from #14837 type Foo = { "true": Foo> }[T]; @@ -9,4 +10,6 @@ tests/cases/compiler/limitDeepInstantiations.ts(3,35): error TS2502: '"true"' is !!! error TS2502: '"true"' is referenced directly or indirectly in its own type annotation. let f1: Foo<"true", {}>; let f2: Foo<"false", {}>; + ~~~~~~~ +!!! error TS2344: Type '"false"' does not satisfy the constraint '"true"'. \ No newline at end of file diff --git a/tests/baselines/reference/limitDeepInstantiations.types b/tests/baselines/reference/limitDeepInstantiations.types index 04899df77db..bce090db14b 100644 --- a/tests/baselines/reference/limitDeepInstantiations.types +++ b/tests/baselines/reference/limitDeepInstantiations.types @@ -9,5 +9,5 @@ let f1: Foo<"true", {}>; >f1 : any let f2: Foo<"false", {}>; ->f2 : any +>f2 : unknown diff --git a/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types b/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types index caca4cf8759..830cbe6a0f4 100644 --- a/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types +++ b/tests/baselines/reference/modularizeLibrary_UsingES5LibES6ArrayLibES6WellknownSymbolLib.types @@ -28,7 +28,7 @@ let a = ['c', 'd']; a[Symbol.isConcatSpreadable] = false; >a[Symbol.isConcatSpreadable] = false : false ->a[Symbol.isConcatSpreadable] : any +>a[Symbol.isConcatSpreadable] : error >a : string[] >Symbol.isConcatSpreadable : symbol >Symbol : SymbolConstructor diff --git a/tests/baselines/reference/newWithSpreadES5.types b/tests/baselines/reference/newWithSpreadES5.types index 14b53040a02..f40235832bb 100644 --- a/tests/baselines/reference/newWithSpreadES5.types +++ b/tests/baselines/reference/newWithSpreadES5.types @@ -445,9 +445,9 @@ new h["a-b"]["a-b"](1, 2, ...a, "string"); // Element access expression with a number new i["a-b"][1](1, 2, "string"); ->new i["a-b"][1](1, 2, "string") : any ->i["a-b"][1] : any ->i["a-b"] : any +>new i["a-b"][1](1, 2, "string") : error +>i["a-b"][1] : error +>i["a-b"] : error >i : C[][] >"a-b" : "a-b" >1 : 1 @@ -456,9 +456,9 @@ new i["a-b"][1](1, 2, "string"); >"string" : "string" new i["a-b"][1](1, 2, ...a); ->new i["a-b"][1](1, 2, ...a) : any ->i["a-b"][1] : any ->i["a-b"] : any +>new i["a-b"][1](1, 2, ...a) : error +>i["a-b"][1] : error +>i["a-b"] : error >i : C[][] >"a-b" : "a-b" >1 : 1 @@ -468,9 +468,9 @@ new i["a-b"][1](1, 2, ...a); >a : string[] new i["a-b"][1](1, 2, ...a, "string"); ->new i["a-b"][1](1, 2, ...a, "string") : any ->i["a-b"][1] : any ->i["a-b"] : any +>new i["a-b"][1](1, 2, ...a, "string") : error +>i["a-b"][1] : error +>i["a-b"] : error >i : C[][] >"a-b" : "a-b" >1 : 1 diff --git a/tests/baselines/reference/newWithSpreadES6.types b/tests/baselines/reference/newWithSpreadES6.types index 5914425b096..ab2cf6b3d1d 100644 --- a/tests/baselines/reference/newWithSpreadES6.types +++ b/tests/baselines/reference/newWithSpreadES6.types @@ -446,9 +446,9 @@ new h["a-b"]["a-b"](1, 2, ...a, "string"); // Element access expression with a number new i["a-b"][1](1, 2, "string"); ->new i["a-b"][1](1, 2, "string") : any ->i["a-b"][1] : any ->i["a-b"] : any +>new i["a-b"][1](1, 2, "string") : error +>i["a-b"][1] : error +>i["a-b"] : error >i : C[][] >"a-b" : "a-b" >1 : 1 @@ -457,9 +457,9 @@ new i["a-b"][1](1, 2, "string"); >"string" : "string" new i["a-b"][1](1, 2, ...a); ->new i["a-b"][1](1, 2, ...a) : any ->i["a-b"][1] : any ->i["a-b"] : any +>new i["a-b"][1](1, 2, ...a) : error +>i["a-b"][1] : error +>i["a-b"] : error >i : C[][] >"a-b" : "a-b" >1 : 1 @@ -469,9 +469,9 @@ new i["a-b"][1](1, 2, ...a); >a : string[] new i["a-b"][1](1, 2, ...a, "string"); ->new i["a-b"][1](1, 2, ...a, "string") : any ->i["a-b"][1] : any ->i["a-b"] : any +>new i["a-b"][1](1, 2, ...a, "string") : error +>i["a-b"][1] : error +>i["a-b"] : error >i : C[][] >"a-b" : "a-b" >1 : 1 diff --git a/tests/baselines/reference/noImplicitAnyIndexingSuppressed.types b/tests/baselines/reference/noImplicitAnyIndexingSuppressed.types index 3b004aa9589..fe34cdbc130 100644 --- a/tests/baselines/reference/noImplicitAnyIndexingSuppressed.types +++ b/tests/baselines/reference/noImplicitAnyIndexingSuppressed.types @@ -24,8 +24,8 @@ var strRepresentation2 = MyEmusEnum[MyEmusEnum.emu] // Should be okay, as we suppress implicit 'any' property access checks var strRepresentation3 = MyEmusEnum["monehh"]; ->strRepresentation3 : any ->MyEmusEnum["monehh"] : any +>strRepresentation3 : error +>MyEmusEnum["monehh"] : error >MyEmusEnum : typeof MyEmusEnum >"monehh" : "monehh" @@ -39,15 +39,15 @@ var strRepresentation4 = MyEmusEnum["emu"]; // Should be okay, as we suppress implicit 'any' property access checks var x = {}["hi"]; ->x : any ->{}["hi"] : any +>x : error +>{}["hi"] : error >{} : {} >"hi" : "hi" // Should be okay, as we suppress implicit 'any' property access checks var y = {}[10]; ->y : any ->{}[10] : any +>y : error +>{}[10] : error >{} : {} >10 : 10 @@ -61,8 +61,8 @@ var emptyObj = {}; // Should be okay, as we suppress implicit 'any' property access checks var z1 = emptyObj[hi]; ->z1 : any ->emptyObj[hi] : any +>z1 : error +>emptyObj[hi] : error >emptyObj : {} >hi : any diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForIn.types b/tests/baselines/reference/nonPrimitiveIndexingWithForIn.types index 44e2b3f4d50..430e03652d7 100644 --- a/tests/baselines/reference/nonPrimitiveIndexingWithForIn.types +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForIn.types @@ -7,8 +7,8 @@ for (var key in a) { >a : object var value = a[key]; ->value : any ->a[key] : any +>value : error +>a[key] : error >a : object >key : string } diff --git a/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.types b/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.types index 3fafa40b596..9c094010701 100644 --- a/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.types +++ b/tests/baselines/reference/nonPrimitiveIndexingWithForInSupressError.types @@ -7,8 +7,8 @@ for (var key in a) { >a : object var value = a[key]; ->value : any ->a[key] : any +>value : error +>a[key] : error >a : object >key : string } diff --git a/tests/baselines/reference/numericIndexingResults.types b/tests/baselines/reference/numericIndexingResults.types index db4d341b560..f4e0d168e6e 100644 --- a/tests/baselines/reference/numericIndexingResults.types +++ b/tests/baselines/reference/numericIndexingResults.types @@ -30,8 +30,8 @@ var r2 = c['2']; >'2' : "2" var r3 = c['3']; ->r3 : any ->c['3'] : any +>r3 : error +>c['3'] : error >c : C >'3' : "3" @@ -80,8 +80,8 @@ var r2 = i['2']; >'2' : "2" var r3 = i['3']; ->r3 : any ->i['3'] : any +>r3 : error +>i['3'] : error >i : I >'3' : "3" @@ -129,8 +129,8 @@ var r2 = a['2']; >'2' : "2" var r3 = a['3']; ->r3 : any ->a['3'] : any +>r3 : error +>a['3'] : error >a : { [x: number]: string; 1: string; "2": string; } >'3' : "3" @@ -162,20 +162,20 @@ var b: { [x: number]: string } = { 1: '', "2": '' } >'' : "" var r1a = b['1']; ->r1a : any ->b['1'] : any +>r1a : error +>b['1'] : error >b : { [x: number]: string; } >'1' : "1" var r2a = b['2']; ->r2a : any ->b['2'] : any +>r2a : error +>b['2'] : error >b : { [x: number]: string; } >'2' : "2" var r3 = b['3']; ->r3 : any ->b['3'] : any +>r3 : error +>b['3'] : error >b : { [x: number]: string; } >'3' : "3" @@ -221,8 +221,8 @@ var r2b = b2['2']; >'2' : "2" var r3 = b2['3']; ->r3 : any ->b2['3'] : any +>r3 : error +>b2['3'] : error >b2 : { [x: number]: string; 1: string; "2": string; } >'3' : "3" diff --git a/tests/baselines/reference/objectTypeWithCallSignatureHidingMembersOfExtendedFunction.types b/tests/baselines/reference/objectTypeWithCallSignatureHidingMembersOfExtendedFunction.types index d36ef8866c7..3ee91c6aff3 100644 --- a/tests/baselines/reference/objectTypeWithCallSignatureHidingMembersOfExtendedFunction.types +++ b/tests/baselines/reference/objectTypeWithCallSignatureHidingMembersOfExtendedFunction.types @@ -55,8 +55,8 @@ var r1d = i.data; >data : number var r1e = i['hm']; // should be Object ->r1e : any ->i['hm'] : any +>r1e : error +>i['hm'] : error >i : I >'hm' : "hm" @@ -104,8 +104,8 @@ var r2d = x.data; >data : number var r2e = x['hm']; // should be Object ->r2e : any ->x['hm'] : any +>r2e : error +>x['hm'] : error >x : { (): void; apply(a: any, b?: any): void; call(thisArg: number, ...argArray: number[]): any; } >'hm' : "hm" diff --git a/tests/baselines/reference/objectTypeWithConstructSignatureHidingMembersOfExtendedFunction.types b/tests/baselines/reference/objectTypeWithConstructSignatureHidingMembersOfExtendedFunction.types index 8bb1785516b..6e00a2ea1e9 100644 --- a/tests/baselines/reference/objectTypeWithConstructSignatureHidingMembersOfExtendedFunction.types +++ b/tests/baselines/reference/objectTypeWithConstructSignatureHidingMembersOfExtendedFunction.types @@ -52,8 +52,8 @@ var r1d = i.data; >data : number var r1e = i['hm']; // should be Object ->r1e : any ->i['hm'] : any +>r1e : error +>i['hm'] : error >i : I >'hm' : "hm" @@ -101,8 +101,8 @@ var r2d = x.data; >data : number var r2e = x['hm']; // should be Object ->r2e : any ->x['hm'] : any +>r2e : error +>x['hm'] : error >x : { new (): number; apply(a: any, b?: any): void; call(thisArg: number, ...argArray: number[]): any; } >'hm' : "hm" diff --git a/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.types b/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.types index d110e79e26e..ad30405de0e 100644 --- a/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.types +++ b/tests/baselines/reference/objectTypeWithStringNamedPropertyOfIllegalCharacters.types @@ -28,8 +28,8 @@ var r = c[" "]; >" " : " " var r2 = c[" "]; ->r2 : any ->c[" "] : any +>r2 : error +>c[" "] : error >c : C >" " : " " @@ -67,8 +67,8 @@ var r = i[" "]; >" " : " " var r2 = i[" "]; ->r2 : any ->i[" "] : any +>r2 : error +>i[" "] : error >i : I >" " : " " @@ -106,8 +106,8 @@ var r = a[" "]; >" " : " " var r2 = a[" "]; ->r2 : any ->a[" "] : any +>r2 : error +>a[" "] : error >a : { " ": number; "a b": string; "~!@#$%^&*()_+{}|:'<>?\/.,`": number; } >" " : " " @@ -148,8 +148,8 @@ var r = b[" "]; >" " : " " var r2 = b[" "]; ->r2 : any ->b[" "] : any +>r2 : error +>b[" "] : error >b : { " ": number; "a b": string; "~!@#$%^&*()_+{}|:'<>?\/.,`": number; } >" " : " " diff --git a/tests/baselines/reference/octalIntegerLiteral.types b/tests/baselines/reference/octalIntegerLiteral.types index 160a1460977..5b3e484821e 100644 --- a/tests/baselines/reference/octalIntegerLiteral.types +++ b/tests/baselines/reference/octalIntegerLiteral.types @@ -69,7 +69,7 @@ obj1[0o45436]; // string >0o45436 : 19230 obj1["0o45436"]; // any ->obj1["0o45436"] : any +>obj1["0o45436"] : error >obj1 : { 0o45436: string; a: number; b: number; oct1: number; 0o7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777: boolean; } >"0o45436" : "0o45436" @@ -109,7 +109,7 @@ obj2[0O45436]; // string >0O45436 : 19230 obj2["0O45436"]; // any ->obj2["0O45436"] : any +>obj2["0O45436"] : error >obj2 : { 0O45436: string; a: number; b: number; oct2: number; 0o7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777: boolean; } >"0O45436" : "0O45436" @@ -149,7 +149,7 @@ obj2["5.462437423415177e+244"]; // boolean >"5.462437423415177e+244" : "5.462437423415177e+244" obj2["Infinity"]; // any ->obj2["Infinity"] : any +>obj2["Infinity"] : error >obj2 : { 0O45436: string; a: number; b: number; oct2: number; 0o7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777: boolean; } >"Infinity" : "Infinity" diff --git a/tests/baselines/reference/octalIntegerLiteralES6.types b/tests/baselines/reference/octalIntegerLiteralES6.types index 0c799a44697..8f1e7256b17 100644 --- a/tests/baselines/reference/octalIntegerLiteralES6.types +++ b/tests/baselines/reference/octalIntegerLiteralES6.types @@ -69,7 +69,7 @@ obj1[0o45436]; // string >0o45436 : 19230 obj1["0o45436"]; // any ->obj1["0o45436"] : any +>obj1["0o45436"] : error >obj1 : { 0o45436: string; a: number; b: number; oct1: number; 0o7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777: boolean; } >"0o45436" : "0o45436" @@ -109,7 +109,7 @@ obj2[0O45436]; // string >0O45436 : 19230 obj2["0O45436"]; // any ->obj2["0O45436"] : any +>obj2["0O45436"] : error >obj2 : { 0O45436: string; a: number; b: number; oct2: number; 0o7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777: boolean; } >"0O45436" : "0O45436" @@ -149,7 +149,7 @@ obj2["5.462437423415177e+244"]; // boolean >"5.462437423415177e+244" : "5.462437423415177e+244" obj2["Infinity"]; // any ->obj2["Infinity"] : any +>obj2["Infinity"] : error >obj2 : { 0O45436: string; a: number; b: number; oct2: number; 0o7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777: boolean; } >"Infinity" : "Infinity" diff --git a/tests/baselines/reference/protoAsIndexInIndexExpression.types b/tests/baselines/reference/protoAsIndexInIndexExpression.types index 7d276199063..2da76f32f4a 100644 --- a/tests/baselines/reference/protoAsIndexInIndexExpression.types +++ b/tests/baselines/reference/protoAsIndexInIndexExpression.types @@ -15,7 +15,7 @@ var WorkspacePrototype = { }; WorkspacePrototype['__proto__'] = EntityPrototype; >WorkspacePrototype['__proto__'] = EntityPrototype : any ->WorkspacePrototype['__proto__'] : any +>WorkspacePrototype['__proto__'] : error >WorkspacePrototype : { serialize: () => any; } >'__proto__' : "__proto__" >EntityPrototype : any diff --git a/tests/baselines/reference/protoInIndexer.types b/tests/baselines/reference/protoInIndexer.types index c15f98b75ff..e47bb0dd341 100644 --- a/tests/baselines/reference/protoInIndexer.types +++ b/tests/baselines/reference/protoInIndexer.types @@ -5,7 +5,7 @@ class X { constructor() { this['__proto__'] = null; // used to cause ICE >this['__proto__'] = null : null ->this['__proto__'] : any +>this['__proto__'] : error >this : this >'__proto__' : "__proto__" >null : null diff --git a/tests/baselines/reference/spyComparisonChecking.errors.txt b/tests/baselines/reference/spyComparisonChecking.errors.txt new file mode 100644 index 00000000000..8b057dd30ed --- /dev/null +++ b/tests/baselines/reference/spyComparisonChecking.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/spyComparisonChecking.ts(20,32): error TS2339: Property 'returnValue' does not exist on type 'Function'. + + +==== tests/cases/compiler/spyComparisonChecking.ts (1 errors) ==== + interface Spy { + (...params: any[]): any; + + identity: string; + and: Function; + mostRecentCall: { args: any[]; }; + argsForCall: any[]; + } + + type SpyObj = T & { + [k in keyof T]: Spy; + } + + declare function createSpyObj( + name: string, names: Array): SpyObj; + + function mock(spyName: string, methodNames: Array): SpyObj { + const spyObj = createSpyObj(spyName, methodNames); + for (const methodName of methodNames) { + spyObj[methodName].and.returnValue(1); + ~~~~~~~~~~~ +!!! error TS2339: Property 'returnValue' does not exist on type 'Function'. + } + return spyObj; + } \ No newline at end of file diff --git a/tests/baselines/reference/spyComparisonChecking.js b/tests/baselines/reference/spyComparisonChecking.js new file mode 100644 index 00000000000..918c4e149e9 --- /dev/null +++ b/tests/baselines/reference/spyComparisonChecking.js @@ -0,0 +1,34 @@ +//// [spyComparisonChecking.ts] +interface Spy { + (...params: any[]): any; + + identity: string; + and: Function; + mostRecentCall: { args: any[]; }; + argsForCall: any[]; +} + +type SpyObj = T & { + [k in keyof T]: Spy; +} + +declare function createSpyObj( + name: string, names: Array): SpyObj; + +function mock(spyName: string, methodNames: Array): SpyObj { + const spyObj = createSpyObj(spyName, methodNames); + for (const methodName of methodNames) { + spyObj[methodName].and.returnValue(1); + } + return spyObj; +} + +//// [spyComparisonChecking.js] +function mock(spyName, methodNames) { + var spyObj = createSpyObj(spyName, methodNames); + for (var _i = 0, methodNames_1 = methodNames; _i < methodNames_1.length; _i++) { + var methodName = methodNames_1[_i]; + spyObj[methodName].and.returnValue(1); + } + return spyObj; +} diff --git a/tests/baselines/reference/spyComparisonChecking.symbols b/tests/baselines/reference/spyComparisonChecking.symbols new file mode 100644 index 00000000000..50d8afaa0d1 --- /dev/null +++ b/tests/baselines/reference/spyComparisonChecking.symbols @@ -0,0 +1,75 @@ +=== tests/cases/compiler/spyComparisonChecking.ts === +interface Spy { +>Spy : Symbol(Spy, Decl(spyComparisonChecking.ts, 0, 0)) + + (...params: any[]): any; +>params : Symbol(params, Decl(spyComparisonChecking.ts, 1, 5)) + + identity: string; +>identity : Symbol(Spy.identity, Decl(spyComparisonChecking.ts, 1, 28)) + + and: Function; +>and : Symbol(Spy.and, Decl(spyComparisonChecking.ts, 3, 21)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + mostRecentCall: { args: any[]; }; +>mostRecentCall : Symbol(Spy.mostRecentCall, Decl(spyComparisonChecking.ts, 4, 18)) +>args : Symbol(args, Decl(spyComparisonChecking.ts, 5, 21)) + + argsForCall: any[]; +>argsForCall : Symbol(Spy.argsForCall, Decl(spyComparisonChecking.ts, 5, 37)) +} + +type SpyObj = T & { +>SpyObj : Symbol(SpyObj, Decl(spyComparisonChecking.ts, 7, 1)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 9, 12)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 9, 12)) + + [k in keyof T]: Spy; +>k : Symbol(k, Decl(spyComparisonChecking.ts, 10, 5)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 9, 12)) +>Spy : Symbol(Spy, Decl(spyComparisonChecking.ts, 0, 0)) +} + +declare function createSpyObj( +>createSpyObj : Symbol(createSpyObj, Decl(spyComparisonChecking.ts, 11, 1)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 13, 30)) + + name: string, names: Array): SpyObj; +>name : Symbol(name, Decl(spyComparisonChecking.ts, 13, 33)) +>names : Symbol(names, Decl(spyComparisonChecking.ts, 14, 17)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 13, 30)) +>SpyObj : Symbol(SpyObj, Decl(spyComparisonChecking.ts, 7, 1)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 13, 30)) + +function mock(spyName: string, methodNames: Array): SpyObj { +>mock : Symbol(mock, Decl(spyComparisonChecking.ts, 14, 52)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 16, 14)) +>spyName : Symbol(spyName, Decl(spyComparisonChecking.ts, 16, 17)) +>methodNames : Symbol(methodNames, Decl(spyComparisonChecking.ts, 16, 33)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 16, 14)) +>SpyObj : Symbol(SpyObj, Decl(spyComparisonChecking.ts, 7, 1)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 16, 14)) + + const spyObj = createSpyObj(spyName, methodNames); +>spyObj : Symbol(spyObj, Decl(spyComparisonChecking.ts, 17, 9)) +>createSpyObj : Symbol(createSpyObj, Decl(spyComparisonChecking.ts, 11, 1)) +>T : Symbol(T, Decl(spyComparisonChecking.ts, 16, 14)) +>spyName : Symbol(spyName, Decl(spyComparisonChecking.ts, 16, 17)) +>methodNames : Symbol(methodNames, Decl(spyComparisonChecking.ts, 16, 33)) + + for (const methodName of methodNames) { +>methodName : Symbol(methodName, Decl(spyComparisonChecking.ts, 18, 14)) +>methodNames : Symbol(methodNames, Decl(spyComparisonChecking.ts, 16, 33)) + + spyObj[methodName].and.returnValue(1); +>spyObj[methodName].and : Symbol(Spy.and, Decl(spyComparisonChecking.ts, 3, 21)) +>spyObj : Symbol(spyObj, Decl(spyComparisonChecking.ts, 17, 9)) +>methodName : Symbol(methodName, Decl(spyComparisonChecking.ts, 18, 14)) +>and : Symbol(Spy.and, Decl(spyComparisonChecking.ts, 3, 21)) + } + return spyObj; +>spyObj : Symbol(spyObj, Decl(spyComparisonChecking.ts, 17, 9)) +} diff --git a/tests/baselines/reference/spyComparisonChecking.types b/tests/baselines/reference/spyComparisonChecking.types new file mode 100644 index 00000000000..3401bc45ac4 --- /dev/null +++ b/tests/baselines/reference/spyComparisonChecking.types @@ -0,0 +1,62 @@ +=== tests/cases/compiler/spyComparisonChecking.ts === +interface Spy { + (...params: any[]): any; +>params : any[] + + identity: string; +>identity : string + + and: Function; +>and : Function + + mostRecentCall: { args: any[]; }; +>mostRecentCall : { args: any[]; } +>args : any[] + + argsForCall: any[]; +>argsForCall : any[] +} + +type SpyObj = T & { +>SpyObj : SpyObj + + [k in keyof T]: Spy; +} + +declare function createSpyObj( +>createSpyObj : (name: string, names: (keyof T)[]) => SpyObj + + name: string, names: Array): SpyObj; +>name : string +>names : (keyof T)[] + +function mock(spyName: string, methodNames: Array): SpyObj { +>mock : (spyName: string, methodNames: (keyof T)[]) => SpyObj +>spyName : string +>methodNames : (keyof T)[] + + const spyObj = createSpyObj(spyName, methodNames); +>spyObj : SpyObj +>createSpyObj(spyName, methodNames) : SpyObj +>createSpyObj : (name: string, names: (keyof T)[]) => SpyObj +>spyName : string +>methodNames : (keyof T)[] + + for (const methodName of methodNames) { +>methodName : keyof T +>methodNames : (keyof T)[] + + spyObj[methodName].and.returnValue(1); +>spyObj[methodName].and.returnValue(1) : any +>spyObj[methodName].and.returnValue : any +>spyObj[methodName].and : Function +>spyObj[methodName] : SpyObj[keyof T] +>spyObj : SpyObj +>methodName : keyof T +>and : Function +>returnValue : any +>1 : 1 + } + return spyObj; +>spyObj : SpyObj +} diff --git a/tests/baselines/reference/superSymbolIndexedAccess1.types b/tests/baselines/reference/superSymbolIndexedAccess1.types index 11b67cadfcd..46e21336436 100644 --- a/tests/baselines/reference/superSymbolIndexedAccess1.types +++ b/tests/baselines/reference/superSymbolIndexedAccess1.types @@ -28,8 +28,8 @@ class Bar extends Foo { >symbol : symbol return super[symbol](); ->super[symbol]() : any ->super[symbol] : any +>super[symbol]() : error +>super[symbol] : error >super : Foo >symbol : symbol } diff --git a/tests/baselines/reference/superSymbolIndexedAccess5.types b/tests/baselines/reference/superSymbolIndexedAccess5.types index cbbd98ee320..b0395936a8a 100644 --- a/tests/baselines/reference/superSymbolIndexedAccess5.types +++ b/tests/baselines/reference/superSymbolIndexedAccess5.types @@ -23,8 +23,8 @@ class Bar extends Foo { >symbol : any return super[symbol](); ->super[symbol]() : any ->super[symbol] : any +>super[symbol]() : error +>super[symbol] : error >super : Foo >symbol : any } diff --git a/tests/baselines/reference/superSymbolIndexedAccess6.types b/tests/baselines/reference/superSymbolIndexedAccess6.types index dab66292718..e60869d6fe6 100644 --- a/tests/baselines/reference/superSymbolIndexedAccess6.types +++ b/tests/baselines/reference/superSymbolIndexedAccess6.types @@ -23,8 +23,8 @@ class Bar extends Foo { >symbol : any return super[symbol](); ->super[symbol]() : any ->super[symbol] : any +>super[symbol]() : error +>super[symbol] : error >super : typeof Foo >symbol : any } diff --git a/tests/baselines/reference/symbolProperty55.types b/tests/baselines/reference/symbolProperty55.types index 3c185f96d1e..d96b8b43751 100644 --- a/tests/baselines/reference/symbolProperty55.types +++ b/tests/baselines/reference/symbolProperty55.types @@ -21,7 +21,7 @@ module M { // The following should be of type 'any'. This is because even though obj has a property keyed by Symbol.iterator, // the key passed in here is the *wrong* Symbol.iterator. It is not the iterator property of the global Symbol. obj[Symbol.iterator]; ->obj[Symbol.iterator] : any +>obj[Symbol.iterator] : error >obj : { [Symbol.iterator]: number; } >Symbol.iterator : symbol >Symbol : SymbolConstructor diff --git a/tests/baselines/reference/symbolProperty56.types b/tests/baselines/reference/symbolProperty56.types index 1f061739c41..b6731ed5e80 100644 --- a/tests/baselines/reference/symbolProperty56.types +++ b/tests/baselines/reference/symbolProperty56.types @@ -21,9 +21,9 @@ module M { // The following should be of type 'any'. This is because even though obj has a property keyed by Symbol.iterator, // the key passed in here is the *wrong* Symbol.iterator. It is not the iterator property of the global Symbol. obj[Symbol["iterator"]]; ->obj[Symbol["iterator"]] : any +>obj[Symbol["iterator"]] : error >obj : { [Symbol.iterator]: number; } ->Symbol["iterator"] : any +>Symbol["iterator"] : error >Symbol : {} >"iterator" : "iterator" } diff --git a/tests/baselines/reference/symbolProperty57.types b/tests/baselines/reference/symbolProperty57.types index 88dca83627f..eeb00489bb2 100644 --- a/tests/baselines/reference/symbolProperty57.types +++ b/tests/baselines/reference/symbolProperty57.types @@ -14,9 +14,9 @@ var obj = { // Should give type 'any'. obj[Symbol["nonsense"]]; ->obj[Symbol["nonsense"]] : any +>obj[Symbol["nonsense"]] : error >obj : { [Symbol.iterator]: number; } ->Symbol["nonsense"] : any +>Symbol["nonsense"] : error >Symbol : SymbolConstructor >"nonsense" : "nonsense" diff --git a/tests/baselines/reference/systemJsForInNoException.types b/tests/baselines/reference/systemJsForInNoException.types index 6d9dbbb6e7b..31bef844a6f 100644 --- a/tests/baselines/reference/systemJsForInNoException.types +++ b/tests/baselines/reference/systemJsForInNoException.types @@ -14,7 +14,7 @@ for (var key in obj) >console.log : (message?: any, ...optionalParams: any[]) => void >console : Console >log : (message?: any, ...optionalParams: any[]) => void ->obj[key] : any +>obj[key] : error >obj : { a: number; } >key : string diff --git a/tests/baselines/reference/templateStringInIndexExpression.types b/tests/baselines/reference/templateStringInIndexExpression.types index f0faac5f45c..9ad6b1e141d 100644 --- a/tests/baselines/reference/templateStringInIndexExpression.types +++ b/tests/baselines/reference/templateStringInIndexExpression.types @@ -1,6 +1,6 @@ === tests/cases/conformance/es6/templates/templateStringInIndexExpression.ts === `abc${0}abc`[`0`]; ->`abc${0}abc`[`0`] : any +>`abc${0}abc`[`0`] : error >`abc${0}abc` : string >0 : 0 >`0` : "0" diff --git a/tests/baselines/reference/templateStringInIndexExpressionES6.types b/tests/baselines/reference/templateStringInIndexExpressionES6.types index eabc71c9fac..d86fb2309e7 100644 --- a/tests/baselines/reference/templateStringInIndexExpressionES6.types +++ b/tests/baselines/reference/templateStringInIndexExpressionES6.types @@ -1,6 +1,6 @@ === tests/cases/conformance/es6/templates/templateStringInIndexExpressionES6.ts === `abc${0}abc`[`0`]; ->`abc${0}abc`[`0`] : any +>`abc${0}abc`[`0`] : error >`abc${0}abc` : string >0 : 0 >`0` : "0" diff --git a/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.js b/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.js new file mode 100644 index 00000000000..56273a2b006 --- /dev/null +++ b/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.js @@ -0,0 +1,60 @@ +//// [thisIndexOnExistingReadonlyFieldIsNotNever.ts] +declare class Component { + readonly props: Readonly<{ children?: unknown }> & Readonly

; + state: Readonly; +} +interface CoachMarkAnchorProps { + anchorRef?: (anchor: C) => void; +} +type AnchorType

= Component

; + +class CoachMarkAnchorDecorator { + decorateComponent

(anchor: P) { + return class CoachMarkAnchor extends Component> & P, {}> { + private _onAnchorRef = (anchor: AnchorType

) => { + const anchorRef = this.props.anchorRef; + if (anchorRef) { + anchorRef(anchor); + } + } + }; + } +} + + +//// [thisIndexOnExistingReadonlyFieldIsNotNever.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + } + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var CoachMarkAnchorDecorator = /** @class */ (function () { + function CoachMarkAnchorDecorator() { + } + CoachMarkAnchorDecorator.prototype.decorateComponent = function (anchor) { + return /** @class */ (function (_super) { + __extends(CoachMarkAnchor, _super); + function CoachMarkAnchor() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._onAnchorRef = function (anchor) { + var anchorRef = _this.props.anchorRef; + if (anchorRef) { + anchorRef(anchor); + } + }; + return _this; + } + return CoachMarkAnchor; + }(Component)); + }; + return CoachMarkAnchorDecorator; +}()); diff --git a/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.symbols b/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.symbols new file mode 100644 index 00000000000..6cedbe269bf --- /dev/null +++ b/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.symbols @@ -0,0 +1,76 @@ +=== tests/cases/compiler/thisIndexOnExistingReadonlyFieldIsNotNever.ts === +declare class Component { +>Component : Symbol(Component, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 0)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 24)) +>S : Symbol(S, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 26)) + + readonly props: Readonly<{ children?: unknown }> & Readonly

; +>props : Symbol(Component.props, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 36)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>children : Symbol(children, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 1, 30)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 24)) + + state: Readonly; +>state : Symbol(Component.state, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 1, 67)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>S : Symbol(S, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 26)) +} +interface CoachMarkAnchorProps { +>CoachMarkAnchorProps : Symbol(CoachMarkAnchorProps, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 3, 1)) +>C : Symbol(C, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 4, 31)) + + anchorRef?: (anchor: C) => void; +>anchorRef : Symbol(CoachMarkAnchorProps.anchorRef, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 4, 35)) +>anchor : Symbol(anchor, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 5, 17)) +>C : Symbol(C, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 4, 31)) +} +type AnchorType

= Component

; +>AnchorType : Symbol(AnchorType, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 6, 1)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 7, 16)) +>Component : Symbol(Component, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 0)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 7, 16)) + +class CoachMarkAnchorDecorator { +>CoachMarkAnchorDecorator : Symbol(CoachMarkAnchorDecorator, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 7, 34)) + + decorateComponent

(anchor: P) { +>decorateComponent : Symbol(CoachMarkAnchorDecorator.decorateComponent, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 9, 32)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 10, 22)) +>anchor : Symbol(anchor, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 10, 25)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 10, 22)) + + return class CoachMarkAnchor extends Component> & P, {}> { +>CoachMarkAnchor : Symbol(CoachMarkAnchor, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 11, 14)) +>Component : Symbol(Component, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 0)) +>CoachMarkAnchorProps : Symbol(CoachMarkAnchorProps, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 3, 1)) +>AnchorType : Symbol(AnchorType, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 6, 1)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 10, 22)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 10, 22)) + + private _onAnchorRef = (anchor: AnchorType

) => { +>_onAnchorRef : Symbol(CoachMarkAnchor._onAnchorRef, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 11, 101)) +>anchor : Symbol(anchor, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 12, 36)) +>AnchorType : Symbol(AnchorType, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 6, 1)) +>P : Symbol(P, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 10, 22)) + + const anchorRef = this.props.anchorRef; +>anchorRef : Symbol(anchorRef, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 13, 21)) +>this.props.anchorRef : Symbol(anchorRef, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 4, 35)) +>this.props : Symbol(Component.props, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 36)) +>this : Symbol(CoachMarkAnchor, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 11, 14)) +>props : Symbol(Component.props, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 0, 36)) +>anchorRef : Symbol(anchorRef, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 4, 35)) + + if (anchorRef) { +>anchorRef : Symbol(anchorRef, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 13, 21)) + + anchorRef(anchor); +>anchorRef : Symbol(anchorRef, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 13, 21)) +>anchor : Symbol(anchor, Decl(thisIndexOnExistingReadonlyFieldIsNotNever.ts, 12, 36)) + } + } + }; + } +} + diff --git a/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.types b/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.types new file mode 100644 index 00000000000..30dfd635724 --- /dev/null +++ b/tests/baselines/reference/thisIndexOnExistingReadonlyFieldIsNotNever.types @@ -0,0 +1,57 @@ +=== tests/cases/compiler/thisIndexOnExistingReadonlyFieldIsNotNever.ts === +declare class Component { +>Component : Component + + readonly props: Readonly<{ children?: unknown }> & Readonly

; +>props : Readonly<{ children?: unknown; }> & Readonly

+>children : unknown + + state: Readonly; +>state : Readonly +} +interface CoachMarkAnchorProps { + anchorRef?: (anchor: C) => void; +>anchorRef : ((anchor: C) => void) | undefined +>anchor : C +} +type AnchorType

= Component

; +>AnchorType : Component + +class CoachMarkAnchorDecorator { +>CoachMarkAnchorDecorator : CoachMarkAnchorDecorator + + decorateComponent

(anchor: P) { +>decorateComponent :

(anchor: P) => typeof CoachMarkAnchor +>anchor : P + + return class CoachMarkAnchor extends Component> & P, {}> { +>class CoachMarkAnchor extends Component> & P, {}> { private _onAnchorRef = (anchor: AnchorType

) => { const anchorRef = this.props.anchorRef; if (anchorRef) { anchorRef(anchor); } } } : typeof CoachMarkAnchor +>CoachMarkAnchor : typeof CoachMarkAnchor +>Component : Component> & P, {}> + + private _onAnchorRef = (anchor: AnchorType

) => { +>_onAnchorRef : (anchor: Component) => void +>(anchor: AnchorType

) => { const anchorRef = this.props.anchorRef; if (anchorRef) { anchorRef(anchor); } } : (anchor: Component) => void +>anchor : Component + + const anchorRef = this.props.anchorRef; +>anchorRef : (CoachMarkAnchorProps> & P)["anchorRef"] | undefined +>this.props.anchorRef : (CoachMarkAnchorProps> & P)["anchorRef"] | undefined +>this.props : Readonly<{ children?: unknown; }> & Readonly> & P> +>this : this +>props : Readonly<{ children?: unknown; }> & Readonly> & P> +>anchorRef : (CoachMarkAnchorProps> & P)["anchorRef"] | undefined + + if (anchorRef) { +>anchorRef : (CoachMarkAnchorProps> & P)["anchorRef"] | undefined + + anchorRef(anchor); +>anchorRef(anchor) : void +>anchorRef : (anchor: Component) => void +>anchor : Component + } + } + }; + } +} + diff --git a/tests/baselines/reference/unionTypeIndexSignature.types b/tests/baselines/reference/unionTypeIndexSignature.types index b8dc9900404..f20d879a548 100644 --- a/tests/baselines/reference/unionTypeIndexSignature.types +++ b/tests/baselines/reference/unionTypeIndexSignature.types @@ -32,16 +32,16 @@ var unionOfTypesWithAndWithoutStringSignature: { [a: string]: number; } | boolea >a : string anyVar = unionOfTypesWithAndWithoutStringSignature["hello"]; // any ->anyVar = unionOfTypesWithAndWithoutStringSignature["hello"] : any +>anyVar = unionOfTypesWithAndWithoutStringSignature["hello"] : error >anyVar : number ->unionOfTypesWithAndWithoutStringSignature["hello"] : any +>unionOfTypesWithAndWithoutStringSignature["hello"] : error >unionOfTypesWithAndWithoutStringSignature : boolean | { [a: string]: number; } >"hello" : "hello" anyVar = unionOfTypesWithAndWithoutStringSignature[10]; // any ->anyVar = unionOfTypesWithAndWithoutStringSignature[10] : any +>anyVar = unionOfTypesWithAndWithoutStringSignature[10] : error >anyVar : number ->unionOfTypesWithAndWithoutStringSignature[10] : any +>unionOfTypesWithAndWithoutStringSignature[10] : error >unionOfTypesWithAndWithoutStringSignature : boolean | { [a: string]: number; } >10 : 10 @@ -53,9 +53,9 @@ var unionOfDifferentReturnType1: { [a: number]: number; } | { [a: number]: Date; >a : number numOrDate = unionOfDifferentReturnType1["hello"]; // any ->numOrDate = unionOfDifferentReturnType1["hello"] : any +>numOrDate = unionOfDifferentReturnType1["hello"] : error >numOrDate : number | Date ->unionOfDifferentReturnType1["hello"] : any +>unionOfDifferentReturnType1["hello"] : error >unionOfDifferentReturnType1 : { [a: number]: number; } | { [a: number]: Date; } >"hello" : "hello" @@ -71,16 +71,16 @@ var unionOfTypesWithAndWithoutStringSignature1: { [a: number]: number; } | boole >a : number anyVar = unionOfTypesWithAndWithoutStringSignature1["hello"]; // any ->anyVar = unionOfTypesWithAndWithoutStringSignature1["hello"] : any +>anyVar = unionOfTypesWithAndWithoutStringSignature1["hello"] : error >anyVar : number ->unionOfTypesWithAndWithoutStringSignature1["hello"] : any +>unionOfTypesWithAndWithoutStringSignature1["hello"] : error >unionOfTypesWithAndWithoutStringSignature1 : boolean | { [a: number]: number; } >"hello" : "hello" anyVar = unionOfTypesWithAndWithoutStringSignature1[10]; // any ->anyVar = unionOfTypesWithAndWithoutStringSignature1[10] : any +>anyVar = unionOfTypesWithAndWithoutStringSignature1[10] : error >anyVar : number ->unionOfTypesWithAndWithoutStringSignature1[10] : any +>unionOfTypesWithAndWithoutStringSignature1[10] : error >unionOfTypesWithAndWithoutStringSignature1 : boolean | { [a: number]: number; } >10 : 10 diff --git a/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.js b/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.js new file mode 100644 index 00000000000..ec188824455 --- /dev/null +++ b/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.js @@ -0,0 +1,36 @@ +//// [varianceCallbacksAndIndexedAccesses.ts] +type Source = { + (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; +} + +interface Action1 { + (arg: T): void; +} +interface MessageEventLike { + source: WindowLike; + origin: string; + data: T; +} +interface PostMessageObject { + postMessage(message: T, host: string): void; +} +interface WindowLike extends PostMessageObject { + addEventListener(type: "message", handler: Action1>): void; + addEventListener(type: string, handler: Action1): void; + removeEventListener(type: "message", handler: Action1>): void; + removeEventListener(type: string, handler: Action1): void; +} +type Target = { + (type: "message", handler: Action1>): void; + (type: string, handler: Action1): void; +}; + +function f1(s: Source, t: Target) { + t = s; +} + +//// [varianceCallbacksAndIndexedAccesses.js] +function f1(s, t) { + t = s; +} diff --git a/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.symbols b/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.symbols new file mode 100644 index 00000000000..343d146b5fd --- /dev/null +++ b/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.symbols @@ -0,0 +1,121 @@ +=== tests/cases/compiler/varianceCallbacksAndIndexedAccesses.ts === +type Source = { +>Source : Symbol(Source, Decl(varianceCallbacksAndIndexedAccesses.ts, 0, 0)) + + (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; +>K : Symbol(K, Decl(varianceCallbacksAndIndexedAccesses.ts, 1, 5)) +>WindowEventMap : Symbol(WindowEventMap, Decl(lib.dom.d.ts, --, --)) +>type : Symbol(type, Decl(varianceCallbacksAndIndexedAccesses.ts, 1, 37)) +>K : Symbol(K, Decl(varianceCallbacksAndIndexedAccesses.ts, 1, 5)) +>listener : Symbol(listener, Decl(varianceCallbacksAndIndexedAccesses.ts, 1, 45)) +>this : Symbol(this, Decl(varianceCallbacksAndIndexedAccesses.ts, 1, 57)) +>Window : Symbol(Window, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>ev : Symbol(ev, Decl(varianceCallbacksAndIndexedAccesses.ts, 1, 70)) +>WindowEventMap : Symbol(WindowEventMap, Decl(lib.dom.d.ts, --, --)) +>K : Symbol(K, Decl(varianceCallbacksAndIndexedAccesses.ts, 1, 5)) +>options : Symbol(options, Decl(varianceCallbacksAndIndexedAccesses.ts, 1, 101)) +>AddEventListenerOptions : Symbol(AddEventListenerOptions, Decl(lib.dom.d.ts, --, --)) + + (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; +>type : Symbol(type, Decl(varianceCallbacksAndIndexedAccesses.ts, 2, 3)) +>listener : Symbol(listener, Decl(varianceCallbacksAndIndexedAccesses.ts, 2, 16)) +>EventListenerOrEventListenerObject : Symbol(EventListenerOrEventListenerObject, Decl(lib.dom.d.ts, --, --)) +>options : Symbol(options, Decl(varianceCallbacksAndIndexedAccesses.ts, 2, 62)) +>AddEventListenerOptions : Symbol(AddEventListenerOptions, Decl(lib.dom.d.ts, --, --)) +} + +interface Action1 { +>Action1 : Symbol(Action1, Decl(varianceCallbacksAndIndexedAccesses.ts, 3, 1)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 5, 18)) + + (arg: T): void; +>arg : Symbol(arg, Decl(varianceCallbacksAndIndexedAccesses.ts, 6, 5)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 5, 18)) +} +interface MessageEventLike { +>MessageEventLike : Symbol(MessageEventLike, Decl(varianceCallbacksAndIndexedAccesses.ts, 7, 1)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 8, 27)) + + source: WindowLike; +>source : Symbol(MessageEventLike.source, Decl(varianceCallbacksAndIndexedAccesses.ts, 8, 31)) +>WindowLike : Symbol(WindowLike, Decl(varianceCallbacksAndIndexedAccesses.ts, 15, 1)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 8, 27)) + + origin: string; +>origin : Symbol(MessageEventLike.origin, Decl(varianceCallbacksAndIndexedAccesses.ts, 9, 26)) + + data: T; +>data : Symbol(MessageEventLike.data, Decl(varianceCallbacksAndIndexedAccesses.ts, 10, 19)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 8, 27)) +} +interface PostMessageObject { +>PostMessageObject : Symbol(PostMessageObject, Decl(varianceCallbacksAndIndexedAccesses.ts, 12, 1)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 13, 28)) + + postMessage(message: T, host: string): void; +>postMessage : Symbol(PostMessageObject.postMessage, Decl(varianceCallbacksAndIndexedAccesses.ts, 13, 32)) +>message : Symbol(message, Decl(varianceCallbacksAndIndexedAccesses.ts, 14, 16)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 13, 28)) +>host : Symbol(host, Decl(varianceCallbacksAndIndexedAccesses.ts, 14, 27)) +} +interface WindowLike extends PostMessageObject { +>WindowLike : Symbol(WindowLike, Decl(varianceCallbacksAndIndexedAccesses.ts, 15, 1)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 16, 21)) +>PostMessageObject : Symbol(PostMessageObject, Decl(varianceCallbacksAndIndexedAccesses.ts, 12, 1)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 16, 21)) + + addEventListener(type: "message", handler: Action1>): void; +>addEventListener : Symbol(WindowLike.addEventListener, Decl(varianceCallbacksAndIndexedAccesses.ts, 16, 54), Decl(varianceCallbacksAndIndexedAccesses.ts, 17, 83)) +>type : Symbol(type, Decl(varianceCallbacksAndIndexedAccesses.ts, 17, 21)) +>handler : Symbol(handler, Decl(varianceCallbacksAndIndexedAccesses.ts, 17, 37)) +>Action1 : Symbol(Action1, Decl(varianceCallbacksAndIndexedAccesses.ts, 3, 1)) +>MessageEventLike : Symbol(MessageEventLike, Decl(varianceCallbacksAndIndexedAccesses.ts, 7, 1)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 16, 21)) + + addEventListener(type: string, handler: Action1): void; +>addEventListener : Symbol(WindowLike.addEventListener, Decl(varianceCallbacksAndIndexedAccesses.ts, 16, 54), Decl(varianceCallbacksAndIndexedAccesses.ts, 17, 83)) +>type : Symbol(type, Decl(varianceCallbacksAndIndexedAccesses.ts, 18, 21)) +>handler : Symbol(handler, Decl(varianceCallbacksAndIndexedAccesses.ts, 18, 34)) +>Action1 : Symbol(Action1, Decl(varianceCallbacksAndIndexedAccesses.ts, 3, 1)) + + removeEventListener(type: "message", handler: Action1>): void; +>removeEventListener : Symbol(WindowLike.removeEventListener, Decl(varianceCallbacksAndIndexedAccesses.ts, 18, 64), Decl(varianceCallbacksAndIndexedAccesses.ts, 19, 86)) +>type : Symbol(type, Decl(varianceCallbacksAndIndexedAccesses.ts, 19, 24)) +>handler : Symbol(handler, Decl(varianceCallbacksAndIndexedAccesses.ts, 19, 40)) +>Action1 : Symbol(Action1, Decl(varianceCallbacksAndIndexedAccesses.ts, 3, 1)) +>MessageEventLike : Symbol(MessageEventLike, Decl(varianceCallbacksAndIndexedAccesses.ts, 7, 1)) +>T : Symbol(T, Decl(varianceCallbacksAndIndexedAccesses.ts, 16, 21)) + + removeEventListener(type: string, handler: Action1): void; +>removeEventListener : Symbol(WindowLike.removeEventListener, Decl(varianceCallbacksAndIndexedAccesses.ts, 18, 64), Decl(varianceCallbacksAndIndexedAccesses.ts, 19, 86)) +>type : Symbol(type, Decl(varianceCallbacksAndIndexedAccesses.ts, 20, 24)) +>handler : Symbol(handler, Decl(varianceCallbacksAndIndexedAccesses.ts, 20, 37)) +>Action1 : Symbol(Action1, Decl(varianceCallbacksAndIndexedAccesses.ts, 3, 1)) +} +type Target = { +>Target : Symbol(Target, Decl(varianceCallbacksAndIndexedAccesses.ts, 21, 1)) + + (type: "message", handler: Action1>): void; +>type : Symbol(type, Decl(varianceCallbacksAndIndexedAccesses.ts, 23, 5)) +>handler : Symbol(handler, Decl(varianceCallbacksAndIndexedAccesses.ts, 23, 21)) +>Action1 : Symbol(Action1, Decl(varianceCallbacksAndIndexedAccesses.ts, 3, 1)) +>MessageEventLike : Symbol(MessageEventLike, Decl(varianceCallbacksAndIndexedAccesses.ts, 7, 1)) + + (type: string, handler: Action1): void; +>type : Symbol(type, Decl(varianceCallbacksAndIndexedAccesses.ts, 24, 5)) +>handler : Symbol(handler, Decl(varianceCallbacksAndIndexedAccesses.ts, 24, 18)) +>Action1 : Symbol(Action1, Decl(varianceCallbacksAndIndexedAccesses.ts, 3, 1)) + +}; + +function f1(s: Source, t: Target) { +>f1 : Symbol(f1, Decl(varianceCallbacksAndIndexedAccesses.ts, 25, 2)) +>s : Symbol(s, Decl(varianceCallbacksAndIndexedAccesses.ts, 27, 12)) +>Source : Symbol(Source, Decl(varianceCallbacksAndIndexedAccesses.ts, 0, 0)) +>t : Symbol(t, Decl(varianceCallbacksAndIndexedAccesses.ts, 27, 22)) +>Target : Symbol(Target, Decl(varianceCallbacksAndIndexedAccesses.ts, 21, 1)) + + t = s; +>t : Symbol(t, Decl(varianceCallbacksAndIndexedAccesses.ts, 27, 22)) +>s : Symbol(s, Decl(varianceCallbacksAndIndexedAccesses.ts, 27, 12)) +} diff --git a/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.types b/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.types new file mode 100644 index 00000000000..6b4d90767b6 --- /dev/null +++ b/tests/baselines/reference/varianceCallbacksAndIndexedAccesses.types @@ -0,0 +1,81 @@ +=== tests/cases/compiler/varianceCallbacksAndIndexedAccesses.ts === +type Source = { +>Source : Source + + (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; +>type : K +>listener : (this: Window, ev: WindowEventMap[K]) => any +>this : Window +>ev : WindowEventMap[K] +>options : boolean | AddEventListenerOptions + + (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; +>type : string +>listener : EventListenerOrEventListenerObject +>options : boolean | AddEventListenerOptions +} + +interface Action1 { + (arg: T): void; +>arg : T +} +interface MessageEventLike { + source: WindowLike; +>source : WindowLike + + origin: string; +>origin : string + + data: T; +>data : T +} +interface PostMessageObject { + postMessage(message: T, host: string): void; +>postMessage : (message: T, host: string) => void +>message : T +>host : string +} +interface WindowLike extends PostMessageObject { + addEventListener(type: "message", handler: Action1>): void; +>addEventListener : { (type: "message", handler: Action1>): void; (type: string, handler: Action1): void; } +>type : "message" +>handler : Action1> + + addEventListener(type: string, handler: Action1): void; +>addEventListener : { (type: "message", handler: Action1>): void; (type: string, handler: Action1): void; } +>type : string +>handler : Action1 + + removeEventListener(type: "message", handler: Action1>): void; +>removeEventListener : { (type: "message", handler: Action1>): void; (type: string, handler: Action1): void; } +>type : "message" +>handler : Action1> + + removeEventListener(type: string, handler: Action1): void; +>removeEventListener : { (type: "message", handler: Action1>): void; (type: string, handler: Action1): void; } +>type : string +>handler : Action1 +} +type Target = { +>Target : Target + + (type: "message", handler: Action1>): void; +>type : "message" +>handler : Action1> + + (type: string, handler: Action1): void; +>type : string +>handler : Action1 + +}; + +function f1(s: Source, t: Target) { +>f1 : (s: Source, t: Target) => void +>s : Source +>t : Target + + t = s; +>t = s : Source +>t : Target +>s : Source +} diff --git a/tests/cases/compiler/circularlySimplifyingConditionalTypesNoCrash.ts b/tests/cases/compiler/circularlySimplifyingConditionalTypesNoCrash.ts new file mode 100644 index 00000000000..ccacb10dd2d --- /dev/null +++ b/tests/cases/compiler/circularlySimplifyingConditionalTypesNoCrash.ts @@ -0,0 +1,48 @@ +// @strict: true +type Omit = Pick>; + +type Shared< // Circularly self constraining type, defered thanks to mapping + InjectedProps, + DecorationTargetProps extends Shared + > = { + [P in Extract]: InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P] : never; + }; + +interface ComponentClass

{ + defaultProps?: Partial

; // Inference target is also mapped _and_ optional +} + +interface InferableComponentEnhancerWithProps { +

>( + component: ComponentClass

+ ): ComponentClass> & TNeedsProps> & { WrappedComponent: ComponentClass

} +} // Then intersected with and indexed via Omit and & + +interface Connect { // Then strictly compared with another signature in its context + ( + mapStateToProps: unknown, + ): InferableComponentEnhancerWithProps; + + ( + mapStateToProps: null | undefined, + mapDispatchToProps: unknown, + mergeProps: null | undefined, + options: unknown + ): InferableComponentEnhancerWithProps; +} + +declare var connect: Connect; + +const myStoreConnect: Connect = function( + mapStateToProps?: any, + mapDispatchToProps?: any, + mergeProps?: any, + options: unknown = {}, +) { + return connect( + mapStateToProps, + mapDispatchToProps, + mergeProps, + options, + ); +}; \ No newline at end of file diff --git a/tests/cases/compiler/genericIndexedAccessMethodIntersectionCanBeAccessed.ts b/tests/cases/compiler/genericIndexedAccessMethodIntersectionCanBeAccessed.ts new file mode 100644 index 00000000000..b4d604ff90a --- /dev/null +++ b/tests/cases/compiler/genericIndexedAccessMethodIntersectionCanBeAccessed.ts @@ -0,0 +1,20 @@ +// @strict: true +type ExtendedService = { + [K in keyof T]: T[K] & { + __$daemonMode?: string; + __$action?: string; + }; +}; + +type Service = { + [K in keyof T]: T[K] & {id?: string}; +}; + +export const createService = ( + ServiceCtr: ExtendedService & Service +) => { + Object.keys(ServiceCtr).forEach(key => { + const method = (ServiceCtr)[key as keyof T]; + const {__$daemonMode, __$action, id} = method; + }) +} diff --git a/tests/cases/compiler/spyComparisonChecking.ts b/tests/cases/compiler/spyComparisonChecking.ts new file mode 100644 index 00000000000..68b53de98db --- /dev/null +++ b/tests/cases/compiler/spyComparisonChecking.ts @@ -0,0 +1,23 @@ +interface Spy { + (...params: any[]): any; + + identity: string; + and: Function; + mostRecentCall: { args: any[]; }; + argsForCall: any[]; +} + +type SpyObj = T & { + [k in keyof T]: Spy; +} + +declare function createSpyObj( + name: string, names: Array): SpyObj; + +function mock(spyName: string, methodNames: Array): SpyObj { + const spyObj = createSpyObj(spyName, methodNames); + for (const methodName of methodNames) { + spyObj[methodName].and.returnValue(1); + } + return spyObj; +} \ No newline at end of file diff --git a/tests/cases/compiler/thisIndexOnExistingReadonlyFieldIsNotNever.ts b/tests/cases/compiler/thisIndexOnExistingReadonlyFieldIsNotNever.ts new file mode 100644 index 00000000000..a271cbdbc9c --- /dev/null +++ b/tests/cases/compiler/thisIndexOnExistingReadonlyFieldIsNotNever.ts @@ -0,0 +1,22 @@ +// @strict: true +declare class Component { + readonly props: Readonly<{ children?: unknown }> & Readonly

; + state: Readonly; +} +interface CoachMarkAnchorProps { + anchorRef?: (anchor: C) => void; +} +type AnchorType

= Component

; + +class CoachMarkAnchorDecorator { + decorateComponent

(anchor: P) { + return class CoachMarkAnchor extends Component> & P, {}> { + private _onAnchorRef = (anchor: AnchorType

) => { + const anchorRef = this.props.anchorRef; + if (anchorRef) { + anchorRef(anchor); + } + } + }; + } +} diff --git a/tests/cases/compiler/varianceCallbacksAndIndexedAccesses.ts b/tests/cases/compiler/varianceCallbacksAndIndexedAccesses.ts new file mode 100644 index 00000000000..471829ffd81 --- /dev/null +++ b/tests/cases/compiler/varianceCallbacksAndIndexedAccesses.ts @@ -0,0 +1,32 @@ + + +type Source = { + (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; +} + +interface Action1 { + (arg: T): void; +} +interface MessageEventLike { + source: WindowLike; + origin: string; + data: T; +} +interface PostMessageObject { + postMessage(message: T, host: string): void; +} +interface WindowLike extends PostMessageObject { + addEventListener(type: "message", handler: Action1>): void; + addEventListener(type: string, handler: Action1): void; + removeEventListener(type: "message", handler: Action1>): void; + removeEventListener(type: string, handler: Action1): void; +} +type Target = { + (type: "message", handler: Action1>): void; + (type: string, handler: Action1): void; +}; + +function f1(s: Source, t: Target) { + t = s; +} \ No newline at end of file From b50c37de785a326752819ef85344097b38e5c81a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 27 Aug 2018 14:12:14 -0700 Subject: [PATCH 057/163] No assert for nameless typedefs (#26695) The assert is over-optimistic and should be removed until we can parse every possible thing that people might put in a JSDoc type position. Fixes #26693 --- src/compiler/utilities.ts | 12 ++++-------- .../noAssertForUnparseableTypedefs.errors.txt | 15 +++++++++++++++ .../noAssertForUnparseableTypedefs.symbols | 5 +++++ .../noAssertForUnparseableTypedefs.types | 5 +++++ .../jsdoc/noAssertForUnparseableTypedefs.ts | 7 +++++++ 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/noAssertForUnparseableTypedefs.errors.txt create mode 100644 tests/baselines/reference/noAssertForUnparseableTypedefs.symbols create mode 100644 tests/baselines/reference/noAssertForUnparseableTypedefs.types create mode 100644 tests/cases/conformance/jsdoc/noAssertForUnparseableTypedefs.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 33dfd2617c9..87cf26a1927 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4853,13 +4853,13 @@ namespace ts { if (isDeclaration(hostNode)) { return getDeclarationIdentifier(hostNode); } - // Covers remaining cases + // Covers remaining cases (returning undefined if none match). switch (hostNode.kind) { case SyntaxKind.VariableStatement: if (hostNode.declarationList && hostNode.declarationList.declarations[0]) { return getDeclarationIdentifier(hostNode.declarationList.declarations[0]); } - return undefined; + break; case SyntaxKind.ExpressionStatement: const expr = hostNode.expression; switch (expr.kind) { @@ -4871,9 +4871,7 @@ namespace ts { return arg; } } - return undefined; - case SyntaxKind.EndOfFileToken: - return undefined; + break; case SyntaxKind.ParenthesizedExpression: { return getDeclarationIdentifier(hostNode.expression); } @@ -4881,10 +4879,8 @@ namespace ts { if (isDeclaration(hostNode.statement) || isExpression(hostNode.statement)) { return getDeclarationIdentifier(hostNode.statement); } - return undefined; + break; } - default: - Debug.assertNever(hostNode, "Found typedef tag attached to node which it should not be!"); } } diff --git a/tests/baselines/reference/noAssertForUnparseableTypedefs.errors.txt b/tests/baselines/reference/noAssertForUnparseableTypedefs.errors.txt new file mode 100644 index 00000000000..4876d5276f7 --- /dev/null +++ b/tests/baselines/reference/noAssertForUnparseableTypedefs.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/jsdoc/bug26693.js(1,15): error TS2304: Cannot find name 'module'. +tests/cases/conformance/jsdoc/bug26693.js(1,21): error TS1005: '}' expected. +tests/cases/conformance/jsdoc/bug26693.js(2,22): error TS2307: Cannot find module 'nope'. + + +==== tests/cases/conformance/jsdoc/bug26693.js (3 errors) ==== + /** @typedef {module:locale} hi */ + ~~~~~~ +!!! error TS2304: Cannot find name 'module'. + ~ +!!! error TS1005: '}' expected. + import { nope } from 'nope'; + ~~~~~~ +!!! error TS2307: Cannot find module 'nope'. + \ No newline at end of file diff --git a/tests/baselines/reference/noAssertForUnparseableTypedefs.symbols b/tests/baselines/reference/noAssertForUnparseableTypedefs.symbols new file mode 100644 index 00000000000..fea0c07d003 --- /dev/null +++ b/tests/baselines/reference/noAssertForUnparseableTypedefs.symbols @@ -0,0 +1,5 @@ +=== tests/cases/conformance/jsdoc/bug26693.js === +/** @typedef {module:locale} hi */ +import { nope } from 'nope'; +>nope : Symbol(nope, Decl(bug26693.js, 1, 8)) + diff --git a/tests/baselines/reference/noAssertForUnparseableTypedefs.types b/tests/baselines/reference/noAssertForUnparseableTypedefs.types new file mode 100644 index 00000000000..3d10e4940b9 --- /dev/null +++ b/tests/baselines/reference/noAssertForUnparseableTypedefs.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/jsdoc/bug26693.js === +/** @typedef {module:locale} hi */ +import { nope } from 'nope'; +>nope : any + diff --git a/tests/cases/conformance/jsdoc/noAssertForUnparseableTypedefs.ts b/tests/cases/conformance/jsdoc/noAssertForUnparseableTypedefs.ts new file mode 100644 index 00000000000..416004c6514 --- /dev/null +++ b/tests/cases/conformance/jsdoc/noAssertForUnparseableTypedefs.ts @@ -0,0 +1,7 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: bug26693.js + +/** @typedef {module:locale} hi */ +import { nope } from 'nope'; From dfd6aa878cad344e44ea6bf7f65cafb2db1a5483 Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 27 Aug 2018 22:10:39 +0000 Subject: [PATCH 058/163] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 20256 ++++++++-------- 1 file changed, 10128 insertions(+), 10128 deletions(-) diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index e9e3bb6cf83..dc8079b6a53 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,10129 +1,10129 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - ou -. Por exemplo '{0}' ou '{1}'.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - Promessa global.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()' em vez disso.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + ou -. Por exemplo '{0}' ou '{1}'.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + Promessa global.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()' em vez disso.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From eeabd527ca0f4e00deb16bb3ca0fee1fb57b1d08 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 27 Aug 2018 15:50:26 -0700 Subject: [PATCH 059/163] Examine all constraints of indexed access types in relations --- src/compiler/checker.ts | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9c0f3cd643f..aad60d77f0f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6899,10 +6899,15 @@ namespace ts { } function getConstraintOfIndexedAccess(type: IndexedAccessType) { - const objectType = getBaseConstraintOfType(type.objectType) || type.objectType; - const indexType = getBaseConstraintOfType(type.indexType) || type.indexType; - const constraint = !isGenericObjectType(objectType) && !isGenericIndexType(indexType) ? getIndexedAccessType(objectType, indexType, /*accessNode*/ undefined, errorType) : undefined; - return constraint && constraint !== errorType ? constraint : undefined; + const objectType = getConstraintOfType(type.objectType) || type.objectType; + if (objectType !== type.objectType) { + const constraint = getIndexedAccessType(objectType, type.indexType, /*accessNode*/ undefined, errorType); + if (constraint && constraint !== errorType) { + return constraint; + } + } + const baseConstraint = getBaseConstraintOfType(type); + return baseConstraint && baseConstraint !== type ? baseConstraint : undefined; } function getDefaultConstraintOfConditionalType(type: ConditionalType) { @@ -7074,9 +7079,6 @@ namespace ts { if (t.flags & TypeFlags.Substitution) { return getBaseConstraint((t).substitute); } - if (isGenericMappedType(t)) { - return emptyObjectType; - } return t; } } @@ -11642,12 +11644,13 @@ namespace ts { } } else if (target.flags & TypeFlags.IndexedAccess) { - // A type S is related to a type T[K] if S is related to C, where C is the - // constraint of T[K] - const constraint = getConstraintForRelation(target); - if (constraint) { - if (result = isRelatedTo(source, constraint, reportErrors)) { - return result; + // A type S is related to a type T[K] if S is related to C, where C is the base constraint of T[K] + if (relation !== identityRelation) { + const constraint = getBaseConstraintOfType(target); + if (constraint && constraint !== target) { + if (result = isRelatedTo(source, constraint, reportErrors)) { + return result; + } } } } From 4cf5774c5e22ec5627e1f8fadca35e7d47a1b38d Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 27 Aug 2018 16:04:02 -0700 Subject: [PATCH 060/163] Add tsserver test for completions and avoid excess properties (#25622) --- src/server/protocol.ts | 2 +- src/services/codefixes/importFixes.ts | 7 +- .../unittests/tsserverProjectSystem.ts | 122 ++++++++++++++++++ .../reference/api/tsserverlibrary.d.ts | 2 +- 4 files changed, 130 insertions(+), 3 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index f8e94085c47..39a0045d97e 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1839,7 +1839,7 @@ namespace ts.server.protocol { * begin with prefix. */ export interface CompletionsRequest extends FileLocationRequest { - command: CommandTypes.Completions; + command: CommandTypes.Completions | CommandTypes.CompletionInfo; arguments: CompletionsRequestArgs; } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 030b9286741..3c5b1d06eaf 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -168,8 +168,13 @@ namespace ts.codefix { // We sort the best codefixes first, so taking `first` is best for completions. const moduleSpecifier = first(getNewImportInfos(program, sourceFile, position, exportInfos, host, preferences)).moduleSpecifier; const fix = first(getFixForImport(exportInfos, symbolName, position, program, sourceFile, host, preferences)); - return { moduleSpecifier, codeAction: codeActionForFix({ host, formatContext }, sourceFile, symbolName, fix, getQuotePreference(sourceFile, preferences)) }; + return { moduleSpecifier, codeAction: codeFixActionToCodeAction(codeActionForFix({ host, formatContext }, sourceFile, symbolName, fix, getQuotePreference(sourceFile, preferences))) }; } + + function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction { + return { description, changes, commands }; + } + function getAllReExportingModules(exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, sourceFile: SourceFile, checker: TypeChecker, allSourceFiles: ReadonlyArray): ReadonlyArray { const result: SymbolExportInfo[] = []; forEachExternalModule(checker, allSourceFiles, (moduleSymbol, moduleFile) => { diff --git a/src/testRunner/unittests/tsserverProjectSystem.ts b/src/testRunner/unittests/tsserverProjectSystem.ts index b99a2d9fe99..589668538c7 100644 --- a/src/testRunner/unittests/tsserverProjectSystem.ts +++ b/src/testRunner/unittests/tsserverProjectSystem.ts @@ -9210,6 +9210,128 @@ export function Test2() { }); }); + describe("tsserverProjectSystem completions", () => { + it("works", () => { + const aTs: File = { + path: "/a.ts", + content: "export const foo = 0;", + }; + const bTs: File = { + path: "/b.ts", + content: "foo", + }; + const tsconfig: File = { + path: "/tsconfig.json", + content: "{}", + }; + + const host = createServerHost([aTs, bTs, tsconfig]); + const session = createSession(host); + openFilesForSession([aTs, bTs], session); + + const requestLocation: protocol.FileLocationRequestArgs = { + file: bTs.path, + line: 1, + offset: 3, + }; + + const response = executeSessionRequest(session, protocol.CommandTypes.CompletionInfo, { + ...requestLocation, + includeExternalModuleExports: true, + prefix: "foo", + }); + const entry: protocol.CompletionEntry = { + hasAction: true, + insertText: undefined, + isRecommended: undefined, + kind: ScriptElementKind.constElement, + kindModifiers: ScriptElementKindModifier.exportedModifier, + name: "foo", + replacementSpan: undefined, + sortText: "0", + source: "/a", + }; + assert.deepEqual(response, { + isGlobalCompletion: true, + isMemberCompletion: false, + isNewIdentifierLocation: false, + entries: [entry], + }); + + const detailsRequestArgs: protocol.CompletionDetailsRequestArgs = { + ...requestLocation, + entryNames: [{ name: "foo", source: "/a" }], + }; + + const detailsResponse = executeSessionRequest(session, protocol.CommandTypes.CompletionDetails, detailsRequestArgs); + const detailsCommon: protocol.CompletionEntryDetails & CompletionEntryDetails = { + displayParts: [ + keywordPart(SyntaxKind.ConstKeyword), + spacePart(), + displayPart("foo", SymbolDisplayPartKind.localName), + punctuationPart(SyntaxKind.ColonToken), + spacePart(), + displayPart("0", SymbolDisplayPartKind.stringLiteral), + ], + documentation: emptyArray, + kind: ScriptElementKind.constElement, + kindModifiers: ScriptElementKindModifier.exportedModifier, + name: "foo", + source: [{ text: "./a", kind: "text" }], + tags: emptyArray, + }; + assert.deepEqual | undefined>(detailsResponse, [ + { + codeActions: [ + { + description: `Import 'foo' from module "./a"`, + changes: [ + { + fileName: "/b.ts", + textChanges: [ + { + start: { line: 1, offset: 1 }, + end: { line: 1, offset: 1 }, + newText: 'import { foo } from "./a";\n\n', + }, + ], + }, + ], + commands: undefined, + }, + ], + ...detailsCommon, + }, + ]); + + interface CompletionDetailsFullRequest extends protocol.FileLocationRequest { + readonly command: protocol.CommandTypes.CompletionDetailsFull; + readonly arguments: protocol.CompletionDetailsRequestArgs; + } + interface CompletionDetailsFullResponse extends protocol.Response { + readonly body?: ReadonlyArray; + } + const detailsFullResponse = executeSessionRequest(session, protocol.CommandTypes.CompletionDetailsFull, detailsRequestArgs); + assert.deepEqual | undefined>(detailsFullResponse, [ + { + codeActions: [ + { + description: `Import 'foo' from module "./a"`, + changes: [ + { + fileName: "/b.ts", + textChanges: [createTextChange(createTextSpan(0, 0), 'import { foo } from "./a";\n\n')], + }, + ], + commands: undefined, + } + ], + ...detailsCommon, + } + ]); + }); + }); + describe("tsserverProjectSystem project references", () => { const aTs: File = { path: "/a/a.ts", diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5e992f3847a..584557e8b0f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6948,7 +6948,7 @@ declare namespace ts.server.protocol { * begin with prefix. */ interface CompletionsRequest extends FileLocationRequest { - command: CommandTypes.Completions; + command: CommandTypes.Completions | CommandTypes.CompletionInfo; arguments: CompletionsRequestArgs; } /** From 9f83958dbe05dfaf2b3072e6cece68c7d5d7b1e9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 27 Aug 2018 16:06:17 -0700 Subject: [PATCH 061/163] Add tests --- .../types/keyof/keyofAndIndexedAccess.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index c76071f7d99..7748240f80d 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -651,3 +651,17 @@ function ff2(dd: DictDict, k1: V, k2: const d: Dict = dd[k1]; return d[k2]; } + +// Repro from #26409 + +const cf1 = (t: T, k: K) => +{ + const s: string = t[k]; + t.cool; +}; + +const cf2 = (t: T, k: K) => +{ + const s: string = t[k]; + t.cool; +}; From d369cecd101a0c7b8172fad2dec68337916d929d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 27 Aug 2018 16:06:26 -0700 Subject: [PATCH 062/163] Accept new baselines --- .../reference/keyofAndIndexedAccess.js | 27 ++++++++++ .../reference/keyofAndIndexedAccess.symbols | 51 +++++++++++++++++++ .../reference/keyofAndIndexedAccess.types | 41 +++++++++++++++ 3 files changed, 119 insertions(+) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index cc0498fcfe2..873fa2a035a 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -649,6 +649,20 @@ function ff2(dd: DictDict, k1: V, k2: const d: Dict = dd[k1]; return d[k2]; } + +// Repro from #26409 + +const cf1 = (t: T, k: K) => +{ + const s: string = t[k]; + t.cool; +}; + +const cf2 = (t: T, k: K) => +{ + const s: string = t[k]; + t.cool; +}; //// [keyofAndIndexedAccess.js] @@ -1078,6 +1092,15 @@ function ff2(dd, k1, k2) { var d = dd[k1]; return d[k2]; } +// Repro from #26409 +var cf1 = function (t, k) { + var s = t[k]; + t.cool; +}; +var cf2 = function (t, k) { + var s = t[k]; + t.cool; +}; //// [keyofAndIndexedAccess.d.ts] @@ -1413,3 +1436,7 @@ declare type DictDict = { }; declare function ff1(dd: DictDict, k1: V, k2: T): number; declare function ff2(dd: DictDict, k1: V, k2: T): number; +declare const cf1: (t: T, k: K) => void; +declare const cf2: (t: T, k: K) => void; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index c8bb9f14da7..15cc704c481 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -2319,3 +2319,54 @@ function ff2(dd: DictDict, k1: V, k2: >k2 : Symbol(k2, Decl(keyofAndIndexedAccess.ts, 646, 75)) } +// Repro from #26409 + +const cf1 = (t: T, k: K) => +>cf1 : Symbol(cf1, Decl(keyofAndIndexedAccess.ts, 653, 5)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 653, 13)) +>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 653, 26)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 653, 65)) +>cool : Symbol(cool, Decl(keyofAndIndexedAccess.ts, 653, 48)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 653, 65)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 653, 13)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 653, 85)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 653, 13)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 653, 90)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 653, 65)) +{ + const s: string = t[k]; +>s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 655, 9)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 653, 85)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 653, 90)) + + t.cool; +>t.cool : Symbol(cool, Decl(keyofAndIndexedAccess.ts, 653, 48)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 653, 85)) +>cool : Symbol(cool, Decl(keyofAndIndexedAccess.ts, 653, 48)) + +}; + +const cf2 = (t: T, k: K) => +>cf2 : Symbol(cf2, Decl(keyofAndIndexedAccess.ts, 659, 5)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 659, 13)) +>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 659, 26)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 659, 54)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 659, 54)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 659, 13)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 659, 74)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 659, 13)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 659, 79)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 659, 54)) +{ + const s: string = t[k]; +>s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 661, 9)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 659, 74)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 659, 79)) + + t.cool; +>t.cool : Symbol(cool) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 659, 74)) +>cool : Symbol(cool) + +}; + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 3434d003d54..58fd74f6601 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -2184,3 +2184,44 @@ function ff2(dd: DictDict, k1: V, k2: >k2 : T } +// Repro from #26409 + +const cf1 = (t: T, k: K) => +>cf1 : (t: T, k: K) => void +>(t: T, k: K) =>{ const s: string = t[k]; t.cool;} : (t: T, k: K) => void +>cool : string +>t : T +>k : K +{ + const s: string = t[k]; +>s : string +>t[k] : T[K] +>t : T +>k : K + + t.cool; +>t.cool : string +>t : T +>cool : string + +}; + +const cf2 = (t: T, k: K) => +>cf2 : (t: T, k: K) => void +>(t: T, k: K) =>{ const s: string = t[k]; t.cool;} : (t: T, k: K) => void +>t : T +>k : K +{ + const s: string = t[k]; +>s : string +>t[k] : T[K] +>t : T +>k : K + + t.cool; +>t.cool : string +>t : T +>cool : string + +}; + From a2e4a282e799fe724e86e06a18157e7aca14392e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 27 Aug 2018 16:52:35 -0700 Subject: [PATCH 063/163] Get [type] parameter types from @type tag (#26694) * Get [type] parameter types from @type tag Previously only the return type was used in cases like this: ```js /** @type {(param?: T) => T | undefined} */ function g(param) { return param; } ``` Now the type parameters from the type tag are used, and the compiler gets the type of the parameter by using the position in the signature of the type tag. Fixes #25618 * Fix split ifs according to PR comments --- src/compiler/checker.ts | 6 ++++++ src/compiler/utilities.ts | 15 ++++++++++++++- .../typeTagWithGenericSignature.symbols | 15 +++++++++++++++ .../reference/typeTagWithGenericSignature.types | 17 +++++++++++++++++ .../jsdoc/typeTagWithGenericSignature.ts | 13 +++++++++++++ 5 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/typeTagWithGenericSignature.symbols create mode 100644 tests/baselines/reference/typeTagWithGenericSignature.types create mode 100644 tests/cases/conformance/jsdoc/typeTagWithGenericSignature.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9c0f3cd643f..679cb79e0cf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4699,6 +4699,12 @@ namespace ts { return getReturnTypeOfSignature(getterSignature); } } + if (isInJavaScriptFile(declaration)) { + const typeTag = getJSDocType(func); + if (typeTag && isFunctionTypeNode(typeTag)) { + return getTypeAtPosition(getSignatureFromDeclaration(typeTag), func.parameters.indexOf(declaration)); + } + } // Use contextual parameter type if one is available const type = declaration.symbol.escapedName === InternalSymbolName.This ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration); if (type) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 87cf26a1927..6b905ad65ca 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5116,7 +5116,20 @@ namespace ts { Debug.assert(node.parent.kind === SyntaxKind.JSDocComment); return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined) as ReadonlyArray; } - return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : emptyArray); + if (node.typeParameters) { + return node.typeParameters; + } + if (isInJavaScriptFile(node)) { + const decls = getJSDocTypeParameterDeclarations(node); + if (decls.length) { + return decls; + } + const typeTag = getJSDocType(node); + if (typeTag && isFunctionTypeNode(typeTag) && typeTag.typeParameters) { + return typeTag.typeParameters; + } + } + return emptyArray; } export function getEffectiveConstraintOfTypeParameter(node: TypeParameterDeclaration): TypeNode | undefined { diff --git a/tests/baselines/reference/typeTagWithGenericSignature.symbols b/tests/baselines/reference/typeTagWithGenericSignature.symbols new file mode 100644 index 00000000000..c9a699d3b4a --- /dev/null +++ b/tests/baselines/reference/typeTagWithGenericSignature.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/jsdoc/bug25618.js === +/** @type {(param?: T) => T | undefined} */ +function typed(param) { +>typed : Symbol(typed, Decl(bug25618.js, 0, 0)) +>param : Symbol(param, Decl(bug25618.js, 1, 15)) + + return param; +>param : Symbol(param, Decl(bug25618.js, 1, 15)) +} + +var n = typed(1); +>n : Symbol(n, Decl(bug25618.js, 5, 3)) +>typed : Symbol(typed, Decl(bug25618.js, 0, 0)) + + diff --git a/tests/baselines/reference/typeTagWithGenericSignature.types b/tests/baselines/reference/typeTagWithGenericSignature.types new file mode 100644 index 00000000000..585fd49fbf4 --- /dev/null +++ b/tests/baselines/reference/typeTagWithGenericSignature.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/jsdoc/bug25618.js === +/** @type {(param?: T) => T | undefined} */ +function typed(param) { +>typed : (param: T | undefined) => T | undefined +>param : T | undefined + + return param; +>param : T | undefined +} + +var n = typed(1); +>n : number | undefined +>typed(1) : 1 | undefined +>typed : (param: T | undefined) => T | undefined +>1 : 1 + + diff --git a/tests/cases/conformance/jsdoc/typeTagWithGenericSignature.ts b/tests/cases/conformance/jsdoc/typeTagWithGenericSignature.ts new file mode 100644 index 00000000000..04ef3e5e1a0 --- /dev/null +++ b/tests/cases/conformance/jsdoc/typeTagWithGenericSignature.ts @@ -0,0 +1,13 @@ +// @checkJs: true +// @allowJs: true +// @noEmit: true +// @strict: true +// @Filename: bug25618.js + +/** @type {(param?: T) => T | undefined} */ +function typed(param) { + return param; +} + +var n = typed(1); + From 72239456667645cf5bd9a6fc06a057c42b25ff0d Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 27 Aug 2018 17:03:30 -0700 Subject: [PATCH 064/163] Use array helper in computeCommonSourceDirectory and remove two unnecessary tests (#26416) --- src/compiler/program.ts | 25 +++++++++---------------- src/compiler/utilities.ts | 2 -- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index abbc935cf65..670e2c200d8 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2319,27 +2319,20 @@ namespace ts { } function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string { - const fileNames: string[] = []; - for (const file of sourceFiles) { - if (!file.isDeclarationFile) { - fileNames.push(file.fileName); - } - } + const fileNames = mapDefined(sourceFiles, file => file.isDeclarationFile ? undefined : file.fileName); return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName); } - function checkSourceFilesBelongToPath(sourceFiles: SourceFile[], rootDirectory: string): boolean { + function checkSourceFilesBelongToPath(sourceFiles: ReadonlyArray, rootDirectory: string): boolean { let allFilesBelongToPath = true; - if (sourceFiles) { - const absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory)); + const absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory)); - for (const sourceFile of sourceFiles) { - if (!sourceFile.isDeclarationFile) { - const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory)); - if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, rootDirectory)); - allFilesBelongToPath = false; - } + for (const sourceFile of sourceFiles) { + if (!sourceFile.isDeclarationFile) { + const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory)); + if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, rootDirectory)); + allFilesBelongToPath = false; } } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6b905ad65ca..39a298329c7 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -7302,8 +7302,6 @@ namespace ts { if (pathComponents.length === 0) return ""; const root = pathComponents[0] && ensureTrailingDirectorySeparator(pathComponents[0]); - if (pathComponents.length === 1) return root; - return root + pathComponents.slice(1).join(directorySeparator); } From d7580755974df4fe3d64af54462b855d3f9f8f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Thu, 9 Aug 2018 16:40:11 +0800 Subject: [PATCH 065/163] add special check for parameter initializer lookup if targeting es2015+ --- src/compiler/checker.ts | 16 ++-- ...InitializersForwardReferencing1.errors.txt | 45 ++++++++++++ ...arameterInitializersForwardReferencing1.js | 61 ++++++++++++++++ ...terInitializersForwardReferencing1.symbols | 67 +++++++++++++++++ ...meterInitializersForwardReferencing1.types | 73 +++++++++++++++++++ ...ializersForwardReferencing1_es6.errors.txt | 36 +++++++++ ...eterInitializersForwardReferencing1_es6.js | 51 +++++++++++++ ...nitializersForwardReferencing1_es6.symbols | 67 +++++++++++++++++ ...rInitializersForwardReferencing1_es6.types | 73 +++++++++++++++++++ ...arameterInitializersForwardReferencing1.ts | 27 +++++++ ...eterInitializersForwardReferencing1_es6.ts | 29 ++++++++ 11 files changed, 540 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1.js create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1.symbols create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1.types create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols create mode 100644 tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types create mode 100644 tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts create mode 100644 tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 51eeb0fdb48..36c6d71f672 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1197,16 +1197,22 @@ namespace ts { : false; } if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) { - // parameters are visible only inside function body, parameter list and return type - // technically for parameter list case here we might mix parameters and variables declared in function, - // however it is detected separately when checking initializers of parameters - // to make sure that they reference no variables declared after them. - useResult = + // parameter initializer will lookup as normal variable scope when targeting es2015+ + if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && lastLocation.initializer === originalLocation && result.valueDeclaration !== lastLocation) { + useResult = false; + } + else { + // parameters are visible only inside function body, parameter list and return type + // technically for parameter list case here we might mix parameters and variables declared in function, + // however it is detected separately when checking initializers of parameters + // to make sure that they reference no variables declared after them. + useResult = lastLocation.kind === SyntaxKind.Parameter || ( lastLocation === (location).type && !!findAncestor(result.valueDeclaration, isParameter) ); + } } } else if (location.kind === SyntaxKind.ConditionalType) { diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt new file mode 100644 index 00000000000..9879ec320ca --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(3,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(8,27): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. + + +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts (5 errors) ==== + let foo: string = ""; + + function f1 (bar = foo) { // unexpected compiler error; works at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. + var foo: number = 2; + return bar; // returns 1 + } + + function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. + var foo: number = 2; + return bar(); // returns 1 + } + + function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. + return bar; + } + + function f4 (foo, bar = foo) { + return bar + } + + function f5 (a = a) { + ~ +!!! error TS2372: Parameter 'a' cannot be referenced in its initializer. + return a + } + + function f6 (async = async) { + ~~~~~ +!!! error TS2372: Parameter 'async' cannot be referenced in its initializer. + return async + } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.js b/tests/baselines/reference/parameterInitializersForwardReferencing1.js new file mode 100644 index 00000000000..43f303a94cd --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.js @@ -0,0 +1,61 @@ +//// [parameterInitializersForwardReferencing1.ts] +let foo: string = ""; + +function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar(); // returns 1 +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; +} + +function f4 (foo, bar = foo) { + return bar +} + +function f5 (a = a) { + return a +} + +function f6 (async = async) { + return async +} + +//// [parameterInitializersForwardReferencing1.js] +var foo = ""; +function f1(bar) { + if (bar === void 0) { bar = foo; } + var foo = 2; + return bar; // returns 1 +} +function f2(bar) { + if (bar === void 0) { bar = function (baz) { + if (baz === void 0) { baz = foo; } + return baz; + }; } + var foo = 2; + return bar(); // returns 1 +} +function f3(bar, foo) { + if (bar === void 0) { bar = foo; } + if (foo === void 0) { foo = 2; } + return bar; +} +function f4(foo, bar) { + if (bar === void 0) { bar = foo; } + return bar; +} +function f5(a) { + if (a === void 0) { a = a; } + return a; +} +function f6(async) { + if (async === void 0) { async = async; } + return async; +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols new file mode 100644 index 00000000000..6860e39fd8d --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols @@ -0,0 +1,67 @@ +=== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts === +let foo: string = ""; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 0, 3)) + +function f1 (bar = foo) { // unexpected compiler error; works at runtime +>f1 : Symbol(f1, Decl(parameterInitializersForwardReferencing1.ts, 0, 21)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 2, 13)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 3, 7)) + + var foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 3, 7)) + + return bar; // returns 1 +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 2, 13)) +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime +>f2 : Symbol(f2, Decl(parameterInitializersForwardReferencing1.ts, 5, 1)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 7, 13)) +>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1.ts, 7, 20)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 8, 7)) +>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1.ts, 7, 20)) + + var foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 8, 7)) + + return bar(); // returns 1 +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 7, 13)) +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime +>f3 : Symbol(f3, Decl(parameterInitializersForwardReferencing1.ts, 10, 1)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 12, 13)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 12, 23)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 12, 23)) + + return bar; +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 12, 13)) +} + +function f4 (foo, bar = foo) { +>f4 : Symbol(f4, Decl(parameterInitializersForwardReferencing1.ts, 14, 1)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 16, 13)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 16, 17)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 16, 13)) + + return bar +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 16, 17)) +} + +function f5 (a = a) { +>f5 : Symbol(f5, Decl(parameterInitializersForwardReferencing1.ts, 18, 1)) +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1.ts, 20, 13)) +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1.ts, 20, 13)) + + return a +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1.ts, 20, 13)) +} + +function f6 (async = async) { +>f6 : Symbol(f6, Decl(parameterInitializersForwardReferencing1.ts, 22, 1)) +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1.ts, 24, 13)) +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1.ts, 24, 13)) + + return async +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1.ts, 24, 13)) +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.types b/tests/baselines/reference/parameterInitializersForwardReferencing1.types new file mode 100644 index 00000000000..c33c227a37a --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.types @@ -0,0 +1,73 @@ +=== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts === +let foo: string = ""; +>foo : string +>"" : "" + +function f1 (bar = foo) { // unexpected compiler error; works at runtime +>f1 : (bar?: number) => number +>bar : number +>foo : number + + var foo: number = 2; +>foo : number +>2 : 2 + + return bar; // returns 1 +>bar : number +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime +>f2 : (bar?: (baz?: number) => number) => number +>bar : (baz?: number) => number +>(baz = foo) => baz : (baz?: number) => number +>baz : number +>foo : number +>baz : number + + var foo: number = 2; +>foo : number +>2 : 2 + + return bar(); // returns 1 +>bar() : number +>bar : (baz?: number) => number +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime +>f3 : (bar?: number, foo?: number) => number +>bar : number +>foo : number +>foo : number +>2 : 2 + + return bar; +>bar : number +} + +function f4 (foo, bar = foo) { +>f4 : (foo: any, bar?: any) => any +>foo : any +>bar : any +>foo : any + + return bar +>bar : any +} + +function f5 (a = a) { +>f5 : (a?: any) => any +>a : any +>a : any + + return a +>a : any +} + +function f6 (async = async) { +>f6 : (async?: any) => any +>async : any +>async : any + + return async +>async : any +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt new file mode 100644 index 00000000000..cffa83707e0 --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -0,0 +1,36 @@ +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. + + +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (2 errors) ==== + let foo: string = ""; + + function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 + } + + function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var fooo: number = 2; + return bar(); // returns 1 + } + + function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; + } + + function f4 (foo, bar = foo) { + return bar + } + + function f5 (a = a) { + ~ +!!! error TS2372: Parameter 'a' cannot be referenced in its initializer. + return a + } + + function f6 (async = async) { + ~~~~~ +!!! error TS2372: Parameter 'async' cannot be referenced in its initializer. + return async + } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js new file mode 100644 index 00000000000..add0837e312 --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js @@ -0,0 +1,51 @@ +//// [parameterInitializersForwardReferencing1_es6.ts] +let foo: string = ""; + +function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var fooo: number = 2; + return bar(); // returns 1 +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; +} + +function f4 (foo, bar = foo) { + return bar +} + +function f5 (a = a) { + return a +} + +function f6 (async = async) { + return async +} + +//// [parameterInitializersForwardReferencing1_es6.js] +let foo = ""; +function f1(bar = foo) { + var foo = 2; + return bar; // returns 1 +} +function f2(bar = (baz = foo) => baz) { + var fooo = 2; + return bar(); // returns 1 +} +function f3(bar = foo, foo = 2) { + return bar; +} +function f4(foo, bar = foo) { + return bar; +} +function f5(a = a) { + return a; +} +function f6(async = async) { + return async; +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols new file mode 100644 index 00000000000..c38a392c4d8 --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols @@ -0,0 +1,67 @@ +=== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts === +let foo: string = ""; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) + +function f1 (bar = foo) { // unexpected compiler error; works at runtime +>f1 : Symbol(f1, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 21)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 2, 13)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) + + var foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7)) + + return bar; // returns 1 +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 2, 13)) +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime +>f2 : Symbol(f2, Decl(parameterInitializersForwardReferencing1_es6.ts, 5, 1)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13)) +>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) + + var fooo: number = 2; +>fooo : Symbol(fooo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7)) + + return bar(); // returns 1 +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13)) +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime +>f3 : Symbol(f3, Decl(parameterInitializersForwardReferencing1_es6.ts, 10, 1)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 13)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 23)) + + return bar; +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 13)) +} + +function f4 (foo, bar = foo) { +>f4 : Symbol(f4, Decl(parameterInitializersForwardReferencing1_es6.ts, 14, 1)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 13)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 17)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) + + return bar +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 17)) +} + +function f5 (a = a) { +>f5 : Symbol(f5, Decl(parameterInitializersForwardReferencing1_es6.ts, 18, 1)) +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1_es6.ts, 20, 13)) +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1_es6.ts, 20, 13)) + + return a +>a : Symbol(a, Decl(parameterInitializersForwardReferencing1_es6.ts, 20, 13)) +} + +function f6 (async = async) { +>f6 : Symbol(f6, Decl(parameterInitializersForwardReferencing1_es6.ts, 22, 1)) +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1_es6.ts, 24, 13)) +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1_es6.ts, 24, 13)) + + return async +>async : Symbol(async, Decl(parameterInitializersForwardReferencing1_es6.ts, 24, 13)) +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types new file mode 100644 index 00000000000..bd17f482335 --- /dev/null +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types @@ -0,0 +1,73 @@ +=== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts === +let foo: string = ""; +>foo : string +>"" : "" + +function f1 (bar = foo) { // unexpected compiler error; works at runtime +>f1 : (bar?: string) => string +>bar : string +>foo : string + + var foo: number = 2; +>foo : number +>2 : 2 + + return bar; // returns 1 +>bar : string +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime +>f2 : (bar?: (baz?: string) => string) => string +>bar : (baz?: string) => string +>(baz = foo) => baz : (baz?: string) => string +>baz : string +>foo : string +>baz : string + + var fooo: number = 2; +>fooo : number +>2 : 2 + + return bar(); // returns 1 +>bar() : string +>bar : (baz?: string) => string +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime +>f3 : (bar?: string, foo?: number) => string +>bar : string +>foo : string +>foo : number +>2 : 2 + + return bar; +>bar : string +} + +function f4 (foo, bar = foo) { +>f4 : (foo: any, bar?: string) => string +>foo : any +>bar : string +>foo : string + + return bar +>bar : string +} + +function f5 (a = a) { +>f5 : (a?: any) => any +>a : any +>a : any + + return a +>a : any +} + +function f6 (async = async) { +>f6 : (async?: any) => any +>async : any +>async : any + + return async +>async : any +} diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts new file mode 100644 index 00000000000..8492a053856 --- /dev/null +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts @@ -0,0 +1,27 @@ +let foo: string = ""; + +function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar(); // returns 1 +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; +} + +function f4 (foo, bar = foo) { + return bar +} + +function f5 (a = a) { + return a +} + +function f6 (async = async) { + return async +} \ No newline at end of file diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts new file mode 100644 index 00000000000..dfd6b8d4e1a --- /dev/null +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts @@ -0,0 +1,29 @@ +// @target: es2015 + +let foo: string = ""; + +function f1 (bar = foo) { // unexpected compiler error; works at runtime + var foo: number = 2; + return bar; // returns 1 +} + +function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + var fooo: number = 2; + return bar(); // returns 1 +} + +function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + return bar; +} + +function f4 (foo, bar = foo) { + return bar +} + +function f5 (a = a) { + return a +} + +function f6 (async = async) { + return async +} \ No newline at end of file From 8869f39c25f8e9e7660ada38f0d33fcea714e49b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Tue, 28 Aug 2018 16:41:26 +0800 Subject: [PATCH 066/163] accept more case --- src/compiler/checker.ts | 6 +++--- ...eterInitializersForwardReferencing1.errors.txt | 13 +++++++++++-- .../parameterInitializersForwardReferencing1.js | 11 ++++++++++- ...rameterInitializersForwardReferencing1.symbols | 10 ++++++++++ ...parameterInitializersForwardReferencing1.types | 11 +++++++++++ ...InitializersForwardReferencing1_es6.errors.txt | 9 +++++++-- ...arameterInitializersForwardReferencing1_es6.js | 14 +++++++++++--- ...terInitializersForwardReferencing1_es6.symbols | 14 ++++++++++++-- ...meterInitializersForwardReferencing1_es6.types | 15 +++++++++++++-- .../parameterInitializersForwardReferencing1.ts | 6 +++++- ...arameterInitializersForwardReferencing1_es6.ts | 8 ++++++-- 11 files changed, 99 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 36c6d71f672..063044eda68 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1196,12 +1196,12 @@ namespace ts { // local types not visible outside the function body : false; } - if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) { + if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.Variable) { // parameter initializer will lookup as normal variable scope when targeting es2015+ - if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && lastLocation.initializer === originalLocation && result.valueDeclaration !== lastLocation) { + if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && result.valueDeclaration !== lastLocation) { useResult = false; } - else { + else if (result.flags & SymbolFlags.FunctionScopedVariable) { // parameters are visible only inside function body, parameter list and return type // technically for parameter list case here we might mix parameters and variables declared in function, // however it is detected separately when checking initializers of parameters diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt index 9879ec320ca..055a37838f1 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt @@ -3,9 +3,10 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(8, tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(29,15): error TS2448: Block-scoped variable 'foo' used before its declaration. -==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts (5 errors) ==== +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts (6 errors) ==== let foo: string = ""; function f1 (bar = foo) { // unexpected compiler error; works at runtime @@ -42,4 +43,12 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(25 ~~~~~ !!! error TS2372: Parameter 'async' cannot be referenced in its initializer. return async - } \ No newline at end of file + } + + function f7({[foo]: bar}: any[]) { + ~~~ +!!! error TS2448: Block-scoped variable 'foo' used before its declaration. +!!! related TS2728 tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts:30:9: 'foo' is declared here. + let foo: number = 2; + } + \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.js b/tests/baselines/reference/parameterInitializersForwardReferencing1.js index 43f303a94cd..ad68f64ca2c 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.js +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.js @@ -25,7 +25,12 @@ function f5 (a = a) { function f6 (async = async) { return async -} +} + +function f7({[foo]: bar}: any[]) { + let foo: number = 2; +} + //// [parameterInitializersForwardReferencing1.js] var foo = ""; @@ -59,3 +64,7 @@ function f6(async) { if (async === void 0) { async = async; } return async; } +function f7(_a) { + var _b = foo, bar = _a[_b]; + var foo = 2; +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols index 6860e39fd8d..f3ea0f1e7e8 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols @@ -65,3 +65,13 @@ function f6 (async = async) { return async >async : Symbol(async, Decl(parameterInitializersForwardReferencing1.ts, 24, 13)) } + +function f7({[foo]: bar}: any[]) { +>f7 : Symbol(f7, Decl(parameterInitializersForwardReferencing1.ts, 26, 1)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 29, 7)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 28, 13)) + + let foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 29, 7)) +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.types b/tests/baselines/reference/parameterInitializersForwardReferencing1.types index c33c227a37a..3a1d8d5864f 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.types @@ -71,3 +71,14 @@ function f6 (async = async) { return async >async : any } + +function f7({[foo]: bar}: any[]) { +>f7 : ({ [foo]: bar }: any[]) => void +>foo : number +>bar : any + + let foo: number = 2; +>foo : number +>2 : 2 +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt index cffa83707e0..e7708894b65 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -11,7 +11,7 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime - var fooo: number = 2; + var foo: number = 2; return bar(); // returns 1 } @@ -33,4 +33,9 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t ~~~~~ !!! error TS2372: Parameter 'async' cannot be referenced in its initializer. return async - } \ No newline at end of file + } + + function f7({[foo]: bar}: any[]) { + let foo: number = 2; + } + \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js index add0837e312..0c89b79b764 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js @@ -7,7 +7,7 @@ function f1 (bar = foo) { // unexpected compiler error; works at runtime } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime - var fooo: number = 2; + var foo: number = 2; return bar(); // returns 1 } @@ -25,7 +25,12 @@ function f5 (a = a) { function f6 (async = async) { return async -} +} + +function f7({[foo]: bar}: any[]) { + let foo: number = 2; +} + //// [parameterInitializersForwardReferencing1_es6.js] let foo = ""; @@ -34,7 +39,7 @@ function f1(bar = foo) { return bar; // returns 1 } function f2(bar = (baz = foo) => baz) { - var fooo = 2; + var foo = 2; return bar(); // returns 1 } function f3(bar = foo, foo = 2) { @@ -49,3 +54,6 @@ function f5(a = a) { function f6(async = async) { return async; } +function f7({ [foo]: bar }) { + let foo = 2; +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols index c38a392c4d8..f9366034aa6 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols @@ -21,8 +21,8 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) >baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) - var fooo: number = 2; ->fooo : Symbol(fooo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7)) + var foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7)) return bar(); // returns 1 >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13)) @@ -65,3 +65,13 @@ function f6 (async = async) { return async >async : Symbol(async, Decl(parameterInitializersForwardReferencing1_es6.ts, 24, 13)) } + +function f7({[foo]: bar}: any[]) { +>f7 : Symbol(f7, Decl(parameterInitializersForwardReferencing1_es6.ts, 26, 1)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 28, 13)) + + let foo: number = 2; +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 29, 7)) +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types index bd17f482335..16bd49f1cf7 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types @@ -24,8 +24,8 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at >foo : string >baz : string - var fooo: number = 2; ->fooo : number + var foo: number = 2; +>foo : number >2 : 2 return bar(); // returns 1 @@ -71,3 +71,14 @@ function f6 (async = async) { return async >async : any } + +function f7({[foo]: bar}: any[]) { +>f7 : ({ [foo]: bar }: any[]) => void +>foo : string +>bar : any + + let foo: number = 2; +>foo : number +>2 : 2 +} + diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts index 8492a053856..640900253bd 100644 --- a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts @@ -24,4 +24,8 @@ function f5 (a = a) { function f6 (async = async) { return async -} \ No newline at end of file +} + +function f7({[foo]: bar}: any[]) { + let foo: number = 2; +} diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts index dfd6b8d4e1a..55afbbf7c2f 100644 --- a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts @@ -8,7 +8,7 @@ function f1 (bar = foo) { // unexpected compiler error; works at runtime } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime - var fooo: number = 2; + var foo: number = 2; return bar(); // returns 1 } @@ -26,4 +26,8 @@ function f5 (a = a) { function f6 (async = async) { return async -} \ No newline at end of file +} + +function f7({[foo]: bar}: any[]) { + let foo: number = 2; +} From fb0cd6c0e03c03cfb4041036e21942e8250401ce Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 28 Aug 2018 16:10:36 +0000 Subject: [PATCH 067/163] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 20264 ++++++++-------- 1 file changed, 10132 insertions(+), 10132 deletions(-) diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 7dac9c42ec8..d2461ce0c42 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,10133 +1,10133 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - oder - erforderlich, z. B. "{0}" oder "{1}".]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - " sein.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()".]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + oder - erforderlich, z. B. "{0}" oder "{1}".]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + " sein.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()".]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 1b1ca9ebf00e062e1271f2c8e0290a80554e31ce Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 28 Aug 2018 09:41:46 -0700 Subject: [PATCH 068/163] Memoize collecting set of all imported packages (#26263) --- src/compiler/checker.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 51eeb0fdb48..01f3b5136f2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31,6 +31,18 @@ namespace ts { } export function createTypeChecker(host: TypeCheckerHost, produceDiagnostics: boolean): TypeChecker { + const getPackagesSet: () => Map = memoize(() => { + const set = createMap(); + host.getSourceFiles().forEach(sf => { + if (!sf.resolvedModules) return; + + forEachEntry(sf.resolvedModules, r => { + if (r && r.packageId) set.set(r.packageId.name, true); + }); + }); + return set; + }); + // Cancellation that controls whether or not we can cancel in the middle of type checking. // In general cancelling is *not* safe for the type checker. We might be in the middle of // computing something, and we will leave our internals in an inconsistent state. Callers @@ -2265,8 +2277,7 @@ namespace ts { resolvedFileName)); } function typesPackageExists(packageName: string): boolean { - return host.getSourceFiles().some(sf => !!sf.resolvedModules && !!forEachEntry(sf.resolvedModules, r => - r && r.packageId && r.packageId.name === getTypesPackageName(packageName))); + return getPackagesSet().has(getTypesPackageName(packageName)); } // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, From 1b5de9d16e0232506983c5ea6c0292f661299fec Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 28 Aug 2018 10:25:00 -0700 Subject: [PATCH 069/163] Uncomment tests fixed with #23631 (#26700) --- tests/cases/fourslash/genericFunctionReturnType.ts | 3 +-- tests/cases/fourslash/genericFunctionSignatureHelp3.ts | 9 +++------ tests/cases/fourslash/genericParameterHelp.ts | 3 --- .../fourslash/genericParameterHelpConstructorCalls.ts | 9 +++------ .../fourslash/genericParameterHelpTypeReferences.ts | 2 +- tests/cases/fourslash/staticGenericOverloads1.ts | 7 ++----- 6 files changed, 10 insertions(+), 23 deletions(-) diff --git a/tests/cases/fourslash/genericFunctionReturnType.ts b/tests/cases/fourslash/genericFunctionReturnType.ts index 9cb41a30ffb..35c566e2090 100644 --- a/tests/cases/fourslash/genericFunctionReturnType.ts +++ b/tests/cases/fourslash/genericFunctionReturnType.ts @@ -8,8 +8,7 @@ ////var /*2*/r = foo(/*1*/1, ""); ////var /*4*/r2 = r(/*3*/""); -// TODO: GH##23631 -// verify.signatureHelp({ marker: "1", text: "foo(x: number, y: string): (a: string) => number" }); +verify.signatureHelp({ marker: "1", text: "foo(x: number, y: string): (a: string) => number" }); verify.quickInfoAt("2", "var r: (a: string) => number"); diff --git a/tests/cases/fourslash/genericFunctionSignatureHelp3.ts b/tests/cases/fourslash/genericFunctionSignatureHelp3.ts index cc763f489cc..d2180219c2a 100644 --- a/tests/cases/fourslash/genericFunctionSignatureHelp3.ts +++ b/tests/cases/fourslash/genericFunctionSignatureHelp3.ts @@ -18,17 +18,14 @@ verify.signatureHelp( { marker: "1", text: "foo1(x: number, callback: (y1: {}) => number): void" }, - // TODO: GH#23631 - // { marker: "2", text: "foo2(x: number, callback: (y2: {}) => number): void" }, + { marker: "2", text: "foo2(x: number, callback: (y2: {}) => number): void" }, { marker: "3", text: "callback(y3: {}): number" }, - // TODO: GH#23631 - // { marker: "4", text: "foo4(x: number, callback: (y4: string) => number): void" }, + { marker: "4", text: "foo4(x: number, callback: (y4: string) => number): void" }, { marker: "5", text: "callback(y5: string): number" }, ); goTo.marker('6'); -// TODO: GH#23631 -// verify.signatureHelp({ text: "foo6(x: number, callback: (y6: {}) => number): void" }); +verify.signatureHelp({ text: "foo6(x: number, callback: (y6: {}) => number): void" }); edit.insert('string>(null,null);'); // need to make this line parse so we can get reasonable LS answers to later tests verify.signatureHelp({ marker: "7", text: "foo7(x: number, callback: (y7: {}) => number): void" }); diff --git a/tests/cases/fourslash/genericParameterHelp.ts b/tests/cases/fourslash/genericParameterHelp.ts index 320c159203c..698ace8a4d8 100644 --- a/tests/cases/fourslash/genericParameterHelp.ts +++ b/tests/cases/fourslash/genericParameterHelp.ts @@ -14,8 +14,6 @@ ////testFunction<, ,/*5*/>(null, null, null); verify.signatureHelp( - // TODO: GH#23631 - /* { marker: "1", text: "testFunction(a: T, b: U, c: M): M", @@ -24,7 +22,6 @@ verify.signatureHelp( parameterSpan: "T extends IFoo", }, { marker: "2", parameterName: "U", parameterSpan: "U" }, - */ { marker: "3", parameterName: "a", parameterSpan: "a: any" }, { marker: "4", parameterName: "M", parameterSpan: "M extends IFoo" }, { marker: "5", parameterName: "M", parameterSpan: "M extends IFoo" }, diff --git a/tests/cases/fourslash/genericParameterHelpConstructorCalls.ts b/tests/cases/fourslash/genericParameterHelpConstructorCalls.ts index 73ae1b91755..4c4ca62f99c 100644 --- a/tests/cases/fourslash/genericParameterHelpConstructorCalls.ts +++ b/tests/cases/fourslash/genericParameterHelpConstructorCalls.ts @@ -14,8 +14,6 @@ ////new testClass(null, null, null) verify.signatureHelp( - // TODO: GH#23631 - /* { marker: "constructor1", text: "testClass(a: T, b: U, c: M): testClass", @@ -27,8 +25,7 @@ verify.signatureHelp( parameterName: "U", parameterSpan: "U", }, - */ - { marker: "constructor3", parameterName: "T", parameterSpan: "T extends IFoo" }, - { marker: "constructor4", parameterName: "M", parameterSpan: "M extends IFoo" }, - { marker: "constructor5", parameterName: "U", parameterSpan: "U" }, + { marker: "constructor3", parameterName: "T", parameterSpan: "T extends IFoo" }, + { marker: "constructor4", parameterName: "M", parameterSpan: "M extends IFoo" }, + { marker: "constructor5", parameterName: "U", parameterSpan: "U" }, ); diff --git a/tests/cases/fourslash/genericParameterHelpTypeReferences.ts b/tests/cases/fourslash/genericParameterHelpTypeReferences.ts index 33d3d85d565..5a477d23e56 100644 --- a/tests/cases/fourslash/genericParameterHelpTypeReferences.ts +++ b/tests/cases/fourslash/genericParameterHelpTypeReferences.ts @@ -12,7 +12,7 @@ ////class Bar extends testClass; -// TODO: GH#23631 +// TODO: GH#26699 if (false) { verify.signatureHelp( diff --git a/tests/cases/fourslash/staticGenericOverloads1.ts b/tests/cases/fourslash/staticGenericOverloads1.ts index e67b9df8d2d..7b15e6e2a3e 100644 --- a/tests/cases/fourslash/staticGenericOverloads1.ts +++ b/tests/cases/fourslash/staticGenericOverloads1.ts @@ -13,11 +13,8 @@ verify.signatureHelp({ marker: "", overloadsCount: 2 }); edit.insert('a'); -verify.signatureHelp({ overloadsCount: 2 }); -// TODO: GH#23631 -// verify.signatureHelp({ text: "B(v: A): A" }); +verify.signatureHelp({ overloadsCount: 2, text: "B(v: A): A" }); edit.insert('); A.B('); verify.signatureHelp({ overloadsCount: 2, text: "B(v: A<{}>): A<{}>" }); edit.insert('a'); -// TODO: GH#23631 -// verify.signatureHelp({ text: "B(v: A): A" }); +verify.signatureHelp({ overloadsCount: 2, text: "B(v: A): A" }); From b183418124626b401ea4f7721cee455d6fd92d2f Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 28 Aug 2018 11:06:14 -0700 Subject: [PATCH 070/163] Fix bug: Don't go to *any* constructor signature for jsx element (#26715) --- src/services/goToDefinition.ts | 13 ++++++++++++- .../fourslash/goToDefinitionSignatureAlias.ts | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 973c040a769..02d590bb8b6 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -29,7 +29,7 @@ namespace ts.GoToDefinition { const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); // Don't go to the component constructor definition for a JSX element, just go to the component definition. - if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isConstructorDeclaration(calledDeclaration))) { + if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isConstructorLike(calledDeclaration))) { const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration); // For a function, if this is the original function definition, return just sigInfo. // If this is the original constructor definition, parent is the class. @@ -319,4 +319,15 @@ namespace ts.GoToDefinition { // Don't go to a function type, go to the value having that type. return tryCast(signature && signature.declaration, (d): d is SignatureDeclaration => isFunctionLike(d) && !isFunctionTypeNode(d)); } + + function isConstructorLike(node: Node): boolean { + switch (node.kind) { + case SyntaxKind.Constructor: + case SyntaxKind.ConstructorType: + case SyntaxKind.ConstructSignature: + return true; + default: + return false; + } + } } diff --git a/tests/cases/fourslash/goToDefinitionSignatureAlias.ts b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts index 909322582eb..4ace3635cc8 100644 --- a/tests/cases/fourslash/goToDefinitionSignatureAlias.ts +++ b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts @@ -21,9 +21,20 @@ ////o.[|/*useM*/m|](); ////class Component { /*componentCtr*/constructor(props: {}) {} } +////type ComponentClass = /*ComponentClass*/new () => Component; +////interface ComponentClass2 { /*ComponentClass2*/new(): Component; } +//// ////class /*MyComponent*/MyComponent extends Component {} -////<[|/*jsxMyComponent*/MyComponent|] /> +////<[|/*jsxMyComponent*/MyComponent|] />; ////new [|/*newMyComponent*/MyComponent|]({}); +//// +////declare const /*MyComponent2*/MyComponent2: ComponentClass; +////<[|/*jsxMyComponent2*/MyComponent2|] />; +////new [|/*newMyComponent2*/MyComponent2|](); +//// +////declare const /*MyComponent3*/MyComponent3: ComponentClass2; +////<[|/*jsxMyComponent3*/MyComponent3|] />; +////new [|/*newMyComponent3*/MyComponent3|](); verify.noErrors(); @@ -38,4 +49,10 @@ verify.goToDefinition({ jsxMyComponent: "MyComponent", newMyComponent: ["MyComponent", "componentCtr"], + + jsxMyComponent2: "MyComponent2", + newMyComponent2: ["MyComponent2", "ComponentClass"], + + jsxMyComponent3: "MyComponent3", + newMyComponent3: ["MyComponent3", "ComponentClass2"], }); From 868cf3e6de627aae3e811bc0bcc40839a9b7af5f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 28 Aug 2018 11:21:35 -0700 Subject: [PATCH 071/163] renames per PR feedback --- src/compiler/tsbuild.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 5fdab168951..f038136e6a4 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -39,7 +39,7 @@ namespace ts { invalidateProject(project: ResolvedConfigFileName, dependencyGraph: DependencyGraph | undefined): void; getNextInvalidatedProject(): ResolvedConfigFileName | undefined; - pendingInvalidatedProjects(): boolean; + hasPendingInvalidatedProjects(): boolean; missingRoots: Map; } @@ -396,20 +396,21 @@ namespace ts { unchangedOutputs: createFileMap(), invalidateProject, getNextInvalidatedProject, - pendingInvalidatedProjects, + hasPendingInvalidatedProjects, missingRoots }; - function invalidateProject(proj: ResolvedConfigFileName, dependancyGraph: DependencyGraph | undefined) { + function invalidateProject(proj: ResolvedConfigFileName, dependencyGraph: DependencyGraph | undefined) { if (!projectPendingBuild.hasKey(proj)) { addProjToQueue(proj); - if (dependancyGraph) { - queueBuildForDownstreamReferences(proj, dependancyGraph); + if (dependencyGraph) { + queueBuildForDownstreamReferences(proj, dependencyGraph); } } } function addProjToQueue(proj: ResolvedConfigFileName) { + Debug.assert(!projectPendingBuild.hasKey(proj)); projectPendingBuild.setValue(proj, true); invalidatedProjectQueue.push(proj); } @@ -426,18 +427,18 @@ namespace ts { } } - function pendingInvalidatedProjects() { + function hasPendingInvalidatedProjects() { return !!projectPendingBuild.getSize(); } // Mark all downstream projects of this one needing to be built "later" - function queueBuildForDownstreamReferences(root: ResolvedConfigFileName, dependancyGraph: DependencyGraph) { - const deps = dependancyGraph.dependencyMap.getReferencesTo(root); + function queueBuildForDownstreamReferences(root: ResolvedConfigFileName, dependencyGraph: DependencyGraph) { + const deps = dependencyGraph.dependencyMap.getReferencesTo(root); for (const ref of deps) { // Can skip circular references if (!projectPendingBuild.hasKey(ref)) { addProjToQueue(ref); - queueBuildForDownstreamReferences(ref, dependancyGraph); + queueBuildForDownstreamReferences(ref, dependencyGraph); } } } @@ -810,7 +811,7 @@ namespace ts { timerToBuildInvalidatedProject = undefined; const buildProject = context.getNextInvalidatedProject(); buildSomeProjects(p => p === buildProject); - if (context.pendingInvalidatedProjects()) { + if (context.hasPendingInvalidatedProjects()) { if (!timerToBuildInvalidatedProject) { scheduleBuildInvalidatedProject(); } From 3931b72118e82884f882b7941cb275f212f3afdd Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 28 Aug 2018 11:43:45 -0700 Subject: [PATCH 072/163] noUnusedLocals: Destructuring assignment is a write (#26365) * noUnusedLocals: Destructuring assignment is a write * Code review * Clarify test --- src/compiler/utilities.ts | 33 ++++++- .../noUnusedLocals_writeOnly.errors.txt | 13 ++- .../reference/noUnusedLocals_writeOnly.js | 25 +++++- .../noUnusedLocals_writeOnly.symbols | 51 +++++++++-- .../reference/noUnusedLocals_writeOnly.types | 87 ++++++++++++++++++- .../compiler/noUnusedLocals_writeOnly.ts | 12 ++- 6 files changed, 206 insertions(+), 15 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 39a298329c7..b808a1f2fd1 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2331,6 +2331,13 @@ namespace ts { return node; } + function skipParenthesesUp(node: Node): Node { + while (node.kind === SyntaxKind.ParenthesizedExpression) { + node = node.parent; + } + return node; + } + // a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped export function isDeleteTarget(node: Node): boolean { if (node.kind !== SyntaxKind.PropertyAccessExpression && node.kind !== SyntaxKind.ElementAccessExpression) { @@ -4206,6 +4213,8 @@ namespace ts { if (!parent) return AccessKind.Read; switch (parent.kind) { + case SyntaxKind.ParenthesizedExpression: + return accessKind(parent); case SyntaxKind.PostfixUnaryExpression: case SyntaxKind.PrefixUnaryExpression: const { operator } = parent as PrefixUnaryExpression | PostfixUnaryExpression; @@ -4217,13 +4226,35 @@ namespace ts { : AccessKind.Read; case SyntaxKind.PropertyAccessExpression: return (parent as PropertyAccessExpression).name !== node ? AccessKind.Read : accessKind(parent); + case SyntaxKind.PropertyAssignment: { + const parentAccess = accessKind(parent.parent); + // In `({ x: varname }) = { x: 1 }`, the left `x` is a read, the right `x` is a write. + return node === (parent as PropertyAssignment).name ? reverseAccessKind(parentAccess) : parentAccess; + } + case SyntaxKind.ShorthandPropertyAssignment: + // Assume it's the local variable being accessed, since we don't check public properties for --noUnusedLocals. + return node === (parent as ShorthandPropertyAssignment).objectAssignmentInitializer ? AccessKind.Read : accessKind(parent.parent); + case SyntaxKind.ArrayLiteralExpression: + return accessKind(parent); default: return AccessKind.Read; } function writeOrReadWrite(): AccessKind { // If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect. - return parent.parent && parent.parent.kind === SyntaxKind.ExpressionStatement ? AccessKind.Write : AccessKind.ReadWrite; + return parent.parent && skipParenthesesUp(parent.parent).kind === SyntaxKind.ExpressionStatement ? AccessKind.Write : AccessKind.ReadWrite; + } + } + function reverseAccessKind(a: AccessKind): AccessKind { + switch (a) { + case AccessKind.Read: + return AccessKind.Write; + case AccessKind.Write: + return AccessKind.Read; + case AccessKind.ReadWrite: + return AccessKind.ReadWrite; + default: + return Debug.assertNever(a); } } diff --git a/tests/baselines/reference/noUnusedLocals_writeOnly.errors.txt b/tests/baselines/reference/noUnusedLocals_writeOnly.errors.txt index 09ebea0f654..347e181d946 100644 --- a/tests/baselines/reference/noUnusedLocals_writeOnly.errors.txt +++ b/tests/baselines/reference/noUnusedLocals_writeOnly.errors.txt @@ -1,14 +1,22 @@ tests/cases/compiler/noUnusedLocals_writeOnly.ts(1,12): error TS6133: 'x' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_writeOnly.ts(10,9): error TS6133: 'z' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_writeOnly.ts(18,9): error TS6133: 'z' is declared but its value is never read. ==== tests/cases/compiler/noUnusedLocals_writeOnly.ts (2 errors) ==== - function f(x = 0) { + function f(x = 0, b = false) { ~ !!! error TS6133: 'x' is declared but its value is never read. + // None of these statements read from 'x', so it will be marked unused. x = 1; x++; x /= 2; + ([x] = [1]); + ({ x } = { x: 1 }); + ({ x: x } = { x: 1 }); + ({ a: [{ b: x }] } = { a: [{ b: 1 }] }); + ({ x = 2 } = { x: b ? 1 : undefined }); + let used = 1; + ({ x = used } = { x: b ? 1 : undefined }); let y = 0; // This is a write access to y, but not a write-*only* access. @@ -19,4 +27,5 @@ tests/cases/compiler/noUnusedLocals_writeOnly.ts(10,9): error TS6133: 'z' is dec !!! error TS6133: 'z' is declared but its value is never read. f(z = 1); // This effectively doesn't use `z`, values just pass through it. } + function f2(_: ReadonlyArray): void {} \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocals_writeOnly.js b/tests/baselines/reference/noUnusedLocals_writeOnly.js index bc007793042..55a927bfc2b 100644 --- a/tests/baselines/reference/noUnusedLocals_writeOnly.js +++ b/tests/baselines/reference/noUnusedLocals_writeOnly.js @@ -1,8 +1,16 @@ //// [noUnusedLocals_writeOnly.ts] -function f(x = 0) { +function f(x = 0, b = false) { + // None of these statements read from 'x', so it will be marked unused. x = 1; x++; x /= 2; + ([x] = [1]); + ({ x } = { x: 1 }); + ({ x: x } = { x: 1 }); + ({ a: [{ b: x }] } = { a: [{ b: 1 }] }); + ({ x = 2 } = { x: b ? 1 : undefined }); + let used = 1; + ({ x = used } = { x: b ? 1 : undefined }); let y = 0; // This is a write access to y, but not a write-*only* access. @@ -11,17 +19,30 @@ function f(x = 0) { let z = 0; f(z = 1); // This effectively doesn't use `z`, values just pass through it. } +function f2(_: ReadonlyArray): void {} //// [noUnusedLocals_writeOnly.js] -function f(x) { +"use strict"; +function f(x, b) { if (x === void 0) { x = 0; } + if (b === void 0) { b = false; } + var _a, _b; + // None of these statements read from 'x', so it will be marked unused. x = 1; x++; x /= 2; + (x = [1][0]); + (x = { x: 1 }.x); + (x = { x: 1 }.x); + (x = { a: [{ b: 1 }] }.a[0].b); + (_a = { x: b ? 1 : undefined }.x, x = _a === void 0 ? 2 : _a); + var used = 1; + (_b = { x: b ? 1 : undefined }.x, x = _b === void 0 ? used : _b); var y = 0; // This is a write access to y, but not a write-*only* access. f(y++); var z = 0; f(z = 1); // This effectively doesn't use `z`, values just pass through it. } +function f2(_) { } diff --git a/tests/baselines/reference/noUnusedLocals_writeOnly.symbols b/tests/baselines/reference/noUnusedLocals_writeOnly.symbols index afb13f9aa2c..a794291cadd 100644 --- a/tests/baselines/reference/noUnusedLocals_writeOnly.symbols +++ b/tests/baselines/reference/noUnusedLocals_writeOnly.symbols @@ -1,8 +1,10 @@ === tests/cases/compiler/noUnusedLocals_writeOnly.ts === -function f(x = 0) { +function f(x = 0, b = false) { >f : Symbol(f, Decl(noUnusedLocals_writeOnly.ts, 0, 0)) >x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 0, 11)) +>b : Symbol(b, Decl(noUnusedLocals_writeOnly.ts, 0, 17)) + // None of these statements read from 'x', so it will be marked unused. x = 1; >x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 0, 11)) @@ -12,19 +14,58 @@ function f(x = 0) { x /= 2; >x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 0, 11)) + ([x] = [1]); +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 0, 11)) + + ({ x } = { x: 1 }); +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 6, 6)) +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 6, 14)) + + ({ x: x } = { x: 1 }); +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 7, 6)) +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 0, 11)) +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 7, 17)) + + ({ a: [{ b: x }] } = { a: [{ b: 1 }] }); +>a : Symbol(a, Decl(noUnusedLocals_writeOnly.ts, 8, 6)) +>b : Symbol(b, Decl(noUnusedLocals_writeOnly.ts, 8, 12)) +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 0, 11)) +>a : Symbol(a, Decl(noUnusedLocals_writeOnly.ts, 8, 26)) +>b : Symbol(b, Decl(noUnusedLocals_writeOnly.ts, 8, 32)) + + ({ x = 2 } = { x: b ? 1 : undefined }); +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 9, 6)) +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 9, 18)) +>b : Symbol(b, Decl(noUnusedLocals_writeOnly.ts, 0, 17)) +>undefined : Symbol(undefined) + + let used = 1; +>used : Symbol(used, Decl(noUnusedLocals_writeOnly.ts, 10, 7)) + + ({ x = used } = { x: b ? 1 : undefined }); +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 11, 6)) +>used : Symbol(used, Decl(noUnusedLocals_writeOnly.ts, 10, 7)) +>x : Symbol(x, Decl(noUnusedLocals_writeOnly.ts, 11, 21)) +>b : Symbol(b, Decl(noUnusedLocals_writeOnly.ts, 0, 17)) +>undefined : Symbol(undefined) + let y = 0; ->y : Symbol(y, Decl(noUnusedLocals_writeOnly.ts, 5, 7)) +>y : Symbol(y, Decl(noUnusedLocals_writeOnly.ts, 13, 7)) // This is a write access to y, but not a write-*only* access. f(y++); >f : Symbol(f, Decl(noUnusedLocals_writeOnly.ts, 0, 0)) ->y : Symbol(y, Decl(noUnusedLocals_writeOnly.ts, 5, 7)) +>y : Symbol(y, Decl(noUnusedLocals_writeOnly.ts, 13, 7)) let z = 0; ->z : Symbol(z, Decl(noUnusedLocals_writeOnly.ts, 9, 7)) +>z : Symbol(z, Decl(noUnusedLocals_writeOnly.ts, 17, 7)) f(z = 1); // This effectively doesn't use `z`, values just pass through it. >f : Symbol(f, Decl(noUnusedLocals_writeOnly.ts, 0, 0)) ->z : Symbol(z, Decl(noUnusedLocals_writeOnly.ts, 9, 7)) +>z : Symbol(z, Decl(noUnusedLocals_writeOnly.ts, 17, 7)) } +function f2(_: ReadonlyArray): void {} +>f2 : Symbol(f2, Decl(noUnusedLocals_writeOnly.ts, 19, 1)) +>_ : Symbol(_, Decl(noUnusedLocals_writeOnly.ts, 20, 12)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --)) diff --git a/tests/baselines/reference/noUnusedLocals_writeOnly.types b/tests/baselines/reference/noUnusedLocals_writeOnly.types index 4b90d7b13e7..43a393a1edd 100644 --- a/tests/baselines/reference/noUnusedLocals_writeOnly.types +++ b/tests/baselines/reference/noUnusedLocals_writeOnly.types @@ -1,9 +1,12 @@ === tests/cases/compiler/noUnusedLocals_writeOnly.ts === -function f(x = 0) { ->f : (x?: number) => void +function f(x = 0, b = false) { +>f : (x?: number, b?: boolean) => void >x : number >0 : 0 +>b : boolean +>false : false + // None of these statements read from 'x', so it will be marked unused. x = 1; >x = 1 : 1 >x : number @@ -18,6 +21,79 @@ function f(x = 0) { >x : number >2 : 2 + ([x] = [1]); +>([x] = [1]) : [number] +>[x] = [1] : [number] +>[x] : [number] +>x : number +>[1] : [number] +>1 : 1 + + ({ x } = { x: 1 }); +>({ x } = { x: 1 }) : { x: number; } +>{ x } = { x: 1 } : { x: number; } +>{ x } : { x: number; } +>x : number +>{ x: 1 } : { x: number; } +>x : number +>1 : 1 + + ({ x: x } = { x: 1 }); +>({ x: x } = { x: 1 }) : { x: number; } +>{ x: x } = { x: 1 } : { x: number; } +>{ x: x } : { x: number; } +>x : number +>x : number +>{ x: 1 } : { x: number; } +>x : number +>1 : 1 + + ({ a: [{ b: x }] } = { a: [{ b: 1 }] }); +>({ a: [{ b: x }] } = { a: [{ b: 1 }] }) : { a: [{ b: number; }]; } +>{ a: [{ b: x }] } = { a: [{ b: 1 }] } : { a: [{ b: number; }]; } +>{ a: [{ b: x }] } : { a: [{ b: number; }]; } +>a : [{ b: number; }] +>[{ b: x }] : [{ b: number; }] +>{ b: x } : { b: number; } +>b : number +>x : number +>{ a: [{ b: 1 }] } : { a: [{ b: number; }]; } +>a : [{ b: number; }] +>[{ b: 1 }] : [{ b: number; }] +>{ b: 1 } : { b: number; } +>b : number +>1 : 1 + + ({ x = 2 } = { x: b ? 1 : undefined }); +>({ x = 2 } = { x: b ? 1 : undefined }) : { x?: number | undefined; } +>{ x = 2 } = { x: b ? 1 : undefined } : { x?: number | undefined; } +>{ x = 2 } : { x?: number; } +>x : number +>2 : 2 +>{ x: b ? 1 : undefined } : { x?: number | undefined; } +>x : number | undefined +>b ? 1 : undefined : 1 | undefined +>b : boolean +>1 : 1 +>undefined : undefined + + let used = 1; +>used : number +>1 : 1 + + ({ x = used } = { x: b ? 1 : undefined }); +>({ x = used } = { x: b ? 1 : undefined }) : { x?: number | undefined; } +>{ x = used } = { x: b ? 1 : undefined } : { x?: number | undefined; } +>{ x = used } : { x?: number; } +>x : number +>used : number +>{ x: b ? 1 : undefined } : { x?: number | undefined; } +>x : number | undefined +>b ? 1 : undefined : 1 | undefined +>b : boolean +>1 : 1 +>undefined : undefined + let y = 0; >y : number >0 : 0 @@ -25,7 +101,7 @@ function f(x = 0) { // This is a write access to y, but not a write-*only* access. f(y++); >f(y++) : void ->f : (x?: number) => void +>f : (x?: number, b?: boolean) => void >y++ : number >y : number @@ -35,9 +111,12 @@ function f(x = 0) { f(z = 1); // This effectively doesn't use `z`, values just pass through it. >f(z = 1) : void ->f : (x?: number) => void +>f : (x?: number, b?: boolean) => void >z = 1 : 1 >z : number >1 : 1 } +function f2(_: ReadonlyArray): void {} +>f2 : (_: ReadonlyArray) => void +>_ : ReadonlyArray diff --git a/tests/cases/compiler/noUnusedLocals_writeOnly.ts b/tests/cases/compiler/noUnusedLocals_writeOnly.ts index ca1df869915..8d2de0d517c 100644 --- a/tests/cases/compiler/noUnusedLocals_writeOnly.ts +++ b/tests/cases/compiler/noUnusedLocals_writeOnly.ts @@ -1,10 +1,19 @@ +// @strict: true // @noUnusedLocals: true // @noUnusedParameters: true -function f(x = 0) { +function f(x = 0, b = false) { + // None of these statements read from 'x', so it will be marked unused. x = 1; x++; x /= 2; + ([x] = [1]); + ({ x } = { x: 1 }); + ({ x: x } = { x: 1 }); + ({ a: [{ b: x }] } = { a: [{ b: 1 }] }); + ({ x = 2 } = { x: b ? 1 : undefined }); + let used = 1; + ({ x = used } = { x: b ? 1 : undefined }); let y = 0; // This is a write access to y, but not a write-*only* access. @@ -13,3 +22,4 @@ function f(x = 0) { let z = 0; f(z = 1); // This effectively doesn't use `z`, values just pass through it. } +function f2(_: ReadonlyArray): void {} From 96e61407c5e399f0dbe94c843f31c3313d98d780 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 28 Aug 2018 11:13:02 -0700 Subject: [PATCH 073/163] Add option --lazyConfiguredProjectsFromExternalProject to enable lazy load of configured projects referenced by external project Fixes #26696 --- src/server/editorServices.ts | 17 +- src/server/session.ts | 2 + .../unittests/tsserverProjectSystem.ts | 511 ++++++++++-------- src/tsserver/server.ts | 2 + .../reference/api/tsserverlibrary.d.ts | 3 + 5 files changed, 306 insertions(+), 229 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 117887d7611..c506c656de7 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -323,6 +323,7 @@ namespace ts.server { cancellationToken: HostCancellationToken; useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; + lazyConfiguredProjectsFromExternalProject?: boolean; typingsInstaller: ITypingsInstaller; eventHandler?: ProjectServiceEventHandler; suppressDiagnosticEvents?: boolean; @@ -440,6 +441,7 @@ namespace ts.server { public readonly cancellationToken: HostCancellationToken; public readonly useSingleInferredProject: boolean; public readonly useInferredProjectPerProjectRoot: boolean; + private readonly lazyConfiguredProjectsFromExternalProject?: boolean; public readonly typingsInstaller: ITypingsInstaller; private readonly globalCacheLocationDirectoryPath: Path | undefined; public readonly throttleWaitMilliseconds?: number; @@ -465,6 +467,7 @@ namespace ts.server { this.cancellationToken = opts.cancellationToken; this.useSingleInferredProject = opts.useSingleInferredProject; this.useInferredProjectPerProjectRoot = opts.useInferredProjectPerProjectRoot; + this.lazyConfiguredProjectsFromExternalProject = opts.lazyConfiguredProjectsFromExternalProject; this.typingsInstaller = opts.typingsInstaller || nullTypingsInstaller; this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds; this.eventHandler = opts.eventHandler; @@ -1561,6 +1564,13 @@ namespace ts.server { return project; } + /* @internal */ + private createLoadAndUpdateConfiguredProject(configFileName: NormalizedPath) { + const project = this.createAndLoadConfiguredProject(configFileName); + project.updateGraph(); + return project; + } + /** * Read the config file of the project, and update the project root file names. */ @@ -2192,8 +2202,7 @@ namespace ts.server { if (configFileName) { project = this.findConfiguredProjectByProjectName(configFileName); if (!project) { - project = this.createAndLoadConfiguredProject(configFileName); - project.updateGraph(); + project = this.createLoadAndUpdateConfiguredProject(configFileName); // Send the event only if the project got created as part of this open request and info is part of the project if (info.isOrphan()) { // Since the file isnt part of configured project, do not send config file info @@ -2633,7 +2642,9 @@ namespace ts.server { let project = this.findConfiguredProjectByProjectName(tsconfigFile); if (!project) { // errors are stored in the project, do not need to update the graph - project = this.createConfiguredProjectWithDelayLoad(tsconfigFile); + project = this.lazyConfiguredProjectsFromExternalProject ? + this.createConfiguredProjectWithDelayLoad(tsconfigFile) : + this.createLoadAndUpdateConfiguredProject(tsconfigFile); } if (project && !contains(exisingConfigFiles, tsconfigFile)) { // keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project diff --git a/src/server/session.ts b/src/server/session.ts index 8d2fbe9e190..69328b4c73b 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -465,6 +465,7 @@ namespace ts.server { cancellationToken: ServerCancellationToken; useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; + lazyConfiguredProjectsFromExternalProject?: boolean; typingsInstaller: ITypingsInstaller; byteLength: (buf: string, encoding?: string) => number; hrtime: (start?: number[]) => number[]; @@ -536,6 +537,7 @@ namespace ts.server { cancellationToken: this.cancellationToken, useSingleInferredProject: opts.useSingleInferredProject, useInferredProjectPerProjectRoot: opts.useInferredProjectPerProjectRoot, + lazyConfiguredProjectsFromExternalProject: opts.lazyConfiguredProjectsFromExternalProject, typingsInstaller: this.typingsInstaller, throttleWaitMilliseconds, eventHandler: this.eventHandler, diff --git a/src/testRunner/unittests/tsserverProjectSystem.ts b/src/testRunner/unittests/tsserverProjectSystem.ts index 589668538c7..7ef838fd6ff 100644 --- a/src/testRunner/unittests/tsserverProjectSystem.ts +++ b/src/testRunner/unittests/tsserverProjectSystem.ts @@ -642,37 +642,53 @@ namespace ts.projectSystem { checkWatchedDirectories(host, [combinePaths(getDirectoryPath(appFile.path), nodeModulesAtTypes)], /*recursive*/ true); }); - it("can handle tsconfig file name with difference casing", () => { - const f1 = { - path: "/a/b/app.ts", - content: "let x = 1" - }; - const config = { - path: "/a/b/tsconfig.json", - content: JSON.stringify({ - include: [] - }) - }; + describe("can handle tsconfig file name with difference casing", () => { + function verifyConfigFileCasing(lazyConfiguredProjectsFromExternalProject: boolean) { + const f1 = { + path: "/a/b/app.ts", + content: "let x = 1" + }; + const config = { + path: "/a/b/tsconfig.json", + content: JSON.stringify({ + include: [] + }) + }; - const host = createServerHost([f1, config], { useCaseSensitiveFileNames: false }); - const service = createProjectService(host); - const upperCaseConfigFilePath = combinePaths(getDirectoryPath(config.path).toUpperCase(), getBaseFileName(config.path)); - service.openExternalProject({ - projectFileName: "/a/b/project.csproj", - rootFiles: toExternalFiles([f1.path, upperCaseConfigFilePath]), - options: {} + const host = createServerHost([f1, config], { useCaseSensitiveFileNames: false }); + const service = createProjectService(host, /*parameters*/ undefined, { lazyConfiguredProjectsFromExternalProject }); + const upperCaseConfigFilePath = combinePaths(getDirectoryPath(config.path).toUpperCase(), getBaseFileName(config.path)); + service.openExternalProject({ + projectFileName: "/a/b/project.csproj", + rootFiles: toExternalFiles([f1.path, upperCaseConfigFilePath]), + options: {} + }); + service.checkNumberOfProjects({ configuredProjects: 1 }); + const project = service.configuredProjects.get(config.path)!; + if (lazyConfiguredProjectsFromExternalProject) { + assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.Full); // External project referenced configured project pending to be reloaded + checkProjectActualFiles(project, emptyArray); + } + else { + assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project pending to be reloaded + checkProjectActualFiles(project, [upperCaseConfigFilePath]); + } + + service.openClientFile(f1.path); + service.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 }); + + assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project is updated + checkProjectActualFiles(project, [upperCaseConfigFilePath]); + checkProjectActualFiles(service.inferredProjects[0], [f1.path]); + } + + it("when lazyConfiguredProjectsFromExternalProject not set", () => { + verifyConfigFileCasing(/*lazyConfiguredProjectsFromExternalProject*/ false); }); - service.checkNumberOfProjects({ configuredProjects: 1 }); - const project = service.configuredProjects.get(config.path)!; - assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.Full); // External project referenced configured project pending to be reloaded - checkProjectActualFiles(project, emptyArray); - service.openClientFile(f1.path); - service.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 }); - - assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project is updated - checkProjectActualFiles(project, [upperCaseConfigFilePath]); - checkProjectActualFiles(service.inferredProjects[0], [f1.path]); + it("when lazyConfiguredProjectsFromExternalProject is set", () => { + verifyConfigFileCasing(/*lazyConfiguredProjectsFromExternalProject*/ true); + }); }); it("create configured project without file list", () => { @@ -2950,45 +2966,55 @@ namespace ts.projectSystem { assert.equal(navbar[0].spans[0].length, f1.content.length); }); - it("deleting config file opened from the external project works", () => { - const site = { - path: "/user/someuser/project/js/site.js", - content: "" - }; - const configFile = { - path: "/user/someuser/project/tsconfig.json", - content: "{}" - }; - const projectFileName = "/user/someuser/project/WebApplication6.csproj"; - const host = createServerHost([libFile, site, configFile]); - const projectService = createProjectService(host); + describe("deleting config file opened from the external project works", () => { + function verifyDeletingConfigFile(lazyConfiguredProjectsFromExternalProject: boolean) { + const site = { + path: "/user/someuser/project/js/site.js", + content: "" + }; + const configFile = { + path: "/user/someuser/project/tsconfig.json", + content: "{}" + }; + const projectFileName = "/user/someuser/project/WebApplication6.csproj"; + const host = createServerHost([libFile, site, configFile]); + const projectService = createProjectService(host, /*parameters*/ undefined, { lazyConfiguredProjectsFromExternalProject }); - const externalProject: protocol.ExternalProject = { - projectFileName, - rootFiles: [toExternalFile(site.path), toExternalFile(configFile.path)], - options: { allowJs: false }, - typeAcquisition: { include: [] } - }; + const externalProject: protocol.ExternalProject = { + projectFileName, + rootFiles: [toExternalFile(site.path), toExternalFile(configFile.path)], + options: { allowJs: false }, + typeAcquisition: { include: [] } + }; - projectService.openExternalProjects([externalProject]); + projectService.openExternalProjects([externalProject]); - let knownProjects = projectService.synchronizeProjectList([]); - checkNumberOfProjects(projectService, { configuredProjects: 1, externalProjects: 0, inferredProjects: 0 }); + let knownProjects = projectService.synchronizeProjectList([]); + checkNumberOfProjects(projectService, { configuredProjects: 1, externalProjects: 0, inferredProjects: 0 }); - const configProject = configuredProjectAt(projectService, 0); - checkProjectActualFiles(configProject, []); // Since no files opened from this project, its not loaded + const configProject = configuredProjectAt(projectService, 0); + checkProjectActualFiles(configProject, lazyConfiguredProjectsFromExternalProject ? + emptyArray : // Since no files opened from this project, its not loaded + [libFile.path, configFile.path]); - host.reloadFS([libFile, site]); - host.checkTimeoutQueueLengthAndRun(1); + host.reloadFS([libFile, site]); + host.checkTimeoutQueueLengthAndRun(1); - knownProjects = projectService.synchronizeProjectList(map(knownProjects, proj => proj.info!)); // TODO: GH#18217 GH#20039 - checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 0, inferredProjects: 0 }); + knownProjects = projectService.synchronizeProjectList(map(knownProjects, proj => proj.info!)); // TODO: GH#18217 GH#20039 + checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 0, inferredProjects: 0 }); - externalProject.rootFiles.length = 1; - projectService.openExternalProjects([externalProject]); + externalProject.rootFiles.length = 1; + projectService.openExternalProjects([externalProject]); - checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 1, inferredProjects: 0 }); - checkProjectActualFiles(projectService.externalProjects[0], [site.path, libFile.path]); + checkNumberOfProjects(projectService, { configuredProjects: 0, externalProjects: 1, inferredProjects: 0 }); + checkProjectActualFiles(projectService.externalProjects[0], [site.path, libFile.path]); + } + it("when lazyConfiguredProjectsFromExternalProject not set", () => { + verifyDeletingConfigFile(/*lazyConfiguredProjectsFromExternalProject*/ false); + }); + it("when lazyConfiguredProjectsFromExternalProject is set", () => { + verifyDeletingConfigFile(/*lazyConfiguredProjectsFromExternalProject*/ true); + }); }); it("Getting errors from closed script info does not throw exception (because of getting project from orphan script info)", () => { @@ -3298,49 +3324,60 @@ namespace ts.projectSystem { }); - it("includes deferred files in the project context", () => { - const file1 = { - path: "/a.deferred", - content: "const a = 1;" - }; - // Deferred extensions should not affect JS files. - const file2 = { - path: "/b.js", - content: "const b = 1;" - }; - const tsconfig = { - path: "/tsconfig.json", - content: "" - }; + describe("includes deferred files in the project context", () => { + function verifyDeferredContext(lazyConfiguredProjectsFromExternalProject: boolean) { + const file1 = { + path: "/a.deferred", + content: "const a = 1;" + }; + // Deferred extensions should not affect JS files. + const file2 = { + path: "/b.js", + content: "const b = 1;" + }; + const tsconfig = { + path: "/tsconfig.json", + content: "" + }; - const host = createServerHost([file1, file2, tsconfig]); - const session = createSession(host); - const projectService = session.getProjectService(); + const host = createServerHost([file1, file2, tsconfig]); + const session = createSession(host, { lazyConfiguredProjectsFromExternalProject }); + const projectService = session.getProjectService(); - // Configure the deferred extension. - const extraFileExtensions = [{ extension: ".deferred", scriptKind: ScriptKind.Deferred, isMixedContent: true }]; - const configureHostRequest = makeSessionRequest(CommandNames.Configure, { extraFileExtensions }); - session.executeCommand(configureHostRequest); + // Configure the deferred extension. + const extraFileExtensions = [{ extension: ".deferred", scriptKind: ScriptKind.Deferred, isMixedContent: true }]; + const configureHostRequest = makeSessionRequest(CommandNames.Configure, { extraFileExtensions }); + session.executeCommand(configureHostRequest); - // Open external project - const projectName = "/proj1"; - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([file1.path, file2.path, tsconfig.path]), - options: {} + // Open external project + const projectName = "/proj1"; + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([file1.path, file2.path, tsconfig.path]), + options: {} + }); + + // Assert + checkNumberOfProjects(projectService, { configuredProjects: 1 }); + + const configuredProject = configuredProjectAt(projectService, 0); + if (lazyConfiguredProjectsFromExternalProject) { + // configured project is just created and not yet loaded + checkProjectActualFiles(configuredProject, emptyArray); + projectService.ensureInferredProjectsUpToDate_TestOnly(); + } + checkProjectActualFiles(configuredProject, [file1.path, tsconfig.path]); + + // Allow allowNonTsExtensions will be set to true for deferred extensions. + assert.isTrue(configuredProject.getCompilerOptions().allowNonTsExtensions); + } + + it("when lazyConfiguredProjectsFromExternalProject not set", () => { + verifyDeferredContext(/*lazyConfiguredProjectsFromExternalProject*/ false); + }); + it("when lazyConfiguredProjectsFromExternalProject is set", () => { + verifyDeferredContext(/*lazyConfiguredProjectsFromExternalProject*/ true); }); - - // Assert - checkNumberOfProjects(projectService, { configuredProjects: 1 }); - - const configuredProject = configuredProjectAt(projectService, 0); - // configured project is just created and not yet loaded - checkProjectActualFiles(configuredProject, emptyArray); - projectService.ensureInferredProjectsUpToDate_TestOnly(); - checkProjectActualFiles(configuredProject, [file1.path, tsconfig.path]); - - // Allow allowNonTsExtensions will be set to true for deferred extensions. - assert.isTrue(configuredProject.getCompilerOptions().allowNonTsExtensions); }); it("Orphan source files are handled correctly on watch trigger", () => { @@ -3943,143 +3980,165 @@ namespace ts.projectSystem { }); describe("tsserverProjectSystem external projects", () => { - it("correctly handling add/remove tsconfig - 1", () => { - const f1 = { - path: "/a/b/app.ts", - content: "let x = 1;" - }; - const f2 = { - path: "/a/b/lib.ts", - content: "" - }; - const tsconfig = { - path: "/a/b/tsconfig.json", - content: "" - }; - const host = createServerHost([f1, f2]); - const projectService = createProjectService(host); + describe("correctly handling add/remove tsconfig - 1", () => { + function verifyAddRemoveConfig(lazyConfiguredProjectsFromExternalProject: boolean) { + const f1 = { + path: "/a/b/app.ts", + content: "let x = 1;" + }; + const f2 = { + path: "/a/b/lib.ts", + content: "" + }; + const tsconfig = { + path: "/a/b/tsconfig.json", + content: "" + }; + const host = createServerHost([f1, f2]); + const projectService = createProjectService(host, /*parameters*/ undefined, { lazyConfiguredProjectsFromExternalProject }); - // open external project - const projectName = "/a/b/proj1"; - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, f2.path]), - options: {} + // open external project + const projectName = "/a/b/proj1"; + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([f1.path, f2.path]), + options: {} + }); + projectService.openClientFile(f1.path); + projectService.checkNumberOfProjects({ externalProjects: 1 }); + checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); + + // rename lib.ts to tsconfig.json + host.reloadFS([f1, tsconfig]); + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([f1.path, tsconfig.path]), + options: {} + }); + projectService.checkNumberOfProjects({ configuredProjects: 1 }); + if (lazyConfiguredProjectsFromExternalProject) { + checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed + projectService.ensureInferredProjectsUpToDate_TestOnly(); + } + checkProjectActualFiles(configuredProjectAt(projectService, 0), [f1.path, tsconfig.path]); + + // rename tsconfig.json back to lib.ts + host.reloadFS([f1, f2]); + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([f1.path, f2.path]), + options: {} + }); + + projectService.checkNumberOfProjects({ externalProjects: 1 }); + checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); + } + it("when lazyConfiguredProjectsFromExternalProject not set", () => { + verifyAddRemoveConfig(/*lazyConfiguredProjectsFromExternalProject*/ false); }); - projectService.openClientFile(f1.path); - projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); - - // rename lib.ts to tsconfig.json - host.reloadFS([f1, tsconfig]); - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, tsconfig.path]), - options: {} + it("when lazyConfiguredProjectsFromExternalProject is set", () => { + verifyAddRemoveConfig(/*lazyConfiguredProjectsFromExternalProject*/ true); }); - projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed - projectService.ensureInferredProjectsUpToDate_TestOnly(); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [f1.path, tsconfig.path]); - - // rename tsconfig.json back to lib.ts - host.reloadFS([f1, f2]); - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, f2.path]), - options: {} - }); - - projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [f1.path, f2.path]); }); + describe("correctly handling add/remove tsconfig - 2", () => { + function verifyAddRemoveConfig(lazyConfiguredProjectsFromExternalProject: boolean) { + const f1 = { + path: "/a/b/app.ts", + content: "let x = 1;" + }; + const cLib = { + path: "/a/b/c/lib.ts", + content: "" + }; + const cTsconfig = { + path: "/a/b/c/tsconfig.json", + content: "{}" + }; + const dLib = { + path: "/a/b/d/lib.ts", + content: "" + }; + const dTsconfig = { + path: "/a/b/d/tsconfig.json", + content: "{}" + }; + const host = createServerHost([f1, cLib, cTsconfig, dLib, dTsconfig]); + const projectService = createProjectService(host, /*parameters*/ undefined, { lazyConfiguredProjectsFromExternalProject }); - it("correctly handling add/remove tsconfig - 2", () => { - const f1 = { - path: "/a/b/app.ts", - content: "let x = 1;" - }; - const cLib = { - path: "/a/b/c/lib.ts", - content: "" - }; - const cTsconfig = { - path: "/a/b/c/tsconfig.json", - content: "{}" - }; - const dLib = { - path: "/a/b/d/lib.ts", - content: "" - }; - const dTsconfig = { - path: "/a/b/d/tsconfig.json", - content: "{}" - }; - const host = createServerHost([f1, cLib, cTsconfig, dLib, dTsconfig]); - const projectService = createProjectService(host); + // open external project + const projectName = "/a/b/proj1"; + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([f1.path]), + options: {} + }); - // open external project - const projectName = "/a/b/proj1"; - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([f1.path]), - options: {} + projectService.checkNumberOfProjects({ externalProjects: 1 }); + checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); + + // add two config file as root files + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([f1.path, cTsconfig.path, dTsconfig.path]), + options: {} + }); + projectService.checkNumberOfProjects({ configuredProjects: 2 }); + if (lazyConfiguredProjectsFromExternalProject) { + checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed + checkProjectActualFiles(configuredProjectAt(projectService, 1), emptyArray); // Configured project created but not loaded till actually needed + projectService.ensureInferredProjectsUpToDate_TestOnly(); + } + checkProjectActualFiles(configuredProjectAt(projectService, 0), [cLib.path, cTsconfig.path]); + checkProjectActualFiles(configuredProjectAt(projectService, 1), [dLib.path, dTsconfig.path]); + + // remove one config file + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([f1.path, dTsconfig.path]), + options: {} + }); + + projectService.checkNumberOfProjects({ configuredProjects: 1 }); + checkProjectActualFiles(configuredProjectAt(projectService, 0), [dLib.path, dTsconfig.path]); + + // remove second config file + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([f1.path]), + options: {} + }); + + projectService.checkNumberOfProjects({ externalProjects: 1 }); + checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); + + // open two config files + // add two config file as root files + projectService.openExternalProject({ + projectFileName: projectName, + rootFiles: toExternalFiles([f1.path, cTsconfig.path, dTsconfig.path]), + options: {} + }); + projectService.checkNumberOfProjects({ configuredProjects: 2 }); + if (lazyConfiguredProjectsFromExternalProject) { + checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed + checkProjectActualFiles(configuredProjectAt(projectService, 1), emptyArray); // Configured project created but not loaded till actually needed + projectService.ensureInferredProjectsUpToDate_TestOnly(); + } + checkProjectActualFiles(configuredProjectAt(projectService, 0), [cLib.path, cTsconfig.path]); + checkProjectActualFiles(configuredProjectAt(projectService, 1), [dLib.path, dTsconfig.path]); + + // close all projects - no projects should be opened + projectService.closeExternalProject(projectName); + projectService.checkNumberOfProjects({}); + } + + it("when lazyConfiguredProjectsFromExternalProject not set", () => { + verifyAddRemoveConfig(/*lazyConfiguredProjectsFromExternalProject*/ false); }); - - projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); - - // add two config file as root files - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, cTsconfig.path, dTsconfig.path]), - options: {} + it("when lazyConfiguredProjectsFromExternalProject is set", () => { + verifyAddRemoveConfig(/*lazyConfiguredProjectsFromExternalProject*/ true); }); - projectService.checkNumberOfProjects({ configuredProjects: 2 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed - checkProjectActualFiles(configuredProjectAt(projectService, 1), emptyArray); // Configured project created but not loaded till actually needed - projectService.ensureInferredProjectsUpToDate_TestOnly(); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [cLib.path, cTsconfig.path]); - checkProjectActualFiles(configuredProjectAt(projectService, 1), [dLib.path, dTsconfig.path]); - - // remove one config file - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, dTsconfig.path]), - options: {} - }); - - projectService.checkNumberOfProjects({ configuredProjects: 1 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [dLib.path, dTsconfig.path]); - - // remove second config file - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([f1.path]), - options: {} - }); - - projectService.checkNumberOfProjects({ externalProjects: 1 }); - checkProjectActualFiles(projectService.externalProjects[0], [f1.path]); - - // open two config files - // add two config file as root files - projectService.openExternalProject({ - projectFileName: projectName, - rootFiles: toExternalFiles([f1.path, cTsconfig.path, dTsconfig.path]), - options: {} - }); - projectService.checkNumberOfProjects({ configuredProjects: 2 }); - checkProjectActualFiles(configuredProjectAt(projectService, 0), emptyArray); // Configured project created but not loaded till actually needed - checkProjectActualFiles(configuredProjectAt(projectService, 1), emptyArray); // Configured project created but not loaded till actually needed - projectService.ensureInferredProjectsUpToDate_TestOnly(); - checkProjectActualFiles(configuredProjectAt(projectService, 0), [cLib.path, cTsconfig.path]); - checkProjectActualFiles(configuredProjectAt(projectService, 1), [dLib.path, dTsconfig.path]); - - // close all projects - no projects should be opened - projectService.closeExternalProject(projectName); - projectService.checkNumberOfProjects({}); }); it("correctly handles changes in lib section of config file", () => { diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index 3e5986e9408..6b8a146d8f3 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -499,6 +499,7 @@ namespace ts.server { cancellationToken, useSingleInferredProject, useInferredProjectPerProjectRoot, + lazyConfiguredProjectsFromExternalProject, typingsInstaller: typingsInstaller || nullTypingsInstaller, byteLength: Buffer.byteLength, hrtime: process.hrtime, @@ -937,6 +938,7 @@ namespace ts.server { const useSingleInferredProject = hasArgument("--useSingleInferredProject"); const useInferredProjectPerProjectRoot = hasArgument("--useInferredProjectPerProjectRoot"); + const lazyConfiguredProjectsFromExternalProject = hasArgument("--lazyConfiguredProjectsFromExternalProject"); const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition"); const suppressDiagnosticEvents = hasArgument("--suppressDiagnosticEvents"); const syntaxOnly = hasArgument("--syntaxOnly"); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 584557e8b0f..3194a2b79bb 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8325,6 +8325,7 @@ declare namespace ts.server { cancellationToken: HostCancellationToken; useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; + lazyConfiguredProjectsFromExternalProject?: boolean; typingsInstaller: ITypingsInstaller; eventHandler?: ProjectServiceEventHandler; suppressDiagnosticEvents?: boolean; @@ -8397,6 +8398,7 @@ declare namespace ts.server { readonly cancellationToken: HostCancellationToken; readonly useSingleInferredProject: boolean; readonly useInferredProjectPerProjectRoot: boolean; + private readonly lazyConfiguredProjectsFromExternalProject?; readonly typingsInstaller: ITypingsInstaller; private readonly globalCacheLocationDirectoryPath; readonly throttleWaitMilliseconds?: number; @@ -8598,6 +8600,7 @@ declare namespace ts.server { cancellationToken: ServerCancellationToken; useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; + lazyConfiguredProjectsFromExternalProject?: boolean; typingsInstaller: ITypingsInstaller; byteLength: (buf: string, encoding?: string) => number; hrtime: (start?: number[]) => number[]; From b94061c5871195642965c2df9fa341758572098f Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 28 Aug 2018 13:03:24 -0700 Subject: [PATCH 074/163] getEditsForFileRename: Avoid changing import specifier ending (#26177) * getEditsForFileRename: Avoid changing import specifier ending * Support .json and .jsx extensions * Restore typeRoots tests * Fix json test * When --jsx preserve is set, import ".tsx" file with ".jsx" extension * Support ending preference in UserPreferences --- src/compiler/checker.ts | 17 +- src/compiler/moduleSpecifiers.ts | 198 +++++++++--------- src/compiler/types.ts | 15 +- src/compiler/utilities.ts | 5 + src/services/getEditsForFileRename.ts | 9 +- src/services/types.ts | 8 - .../reference/api/tsserverlibrary.d.ts | 18 +- tests/baselines/reference/api/typescript.d.ts | 18 +- tests/cases/fourslash/fourslash.ts | 9 +- ...etEditsForFileRename_preservePathEnding.ts | 44 ++++ .../importNameCodeFixNewImportTypeRoots0.ts | 45 ++-- .../importNameCodeFixNewImportTypeRoots1.ts | 50 +++-- .../importNameCodeFix_endingPreference.ts | 26 +++ .../importNameCodeFix_jsExtension.ts | 16 +- .../importNameCodeFix_types_classic.ts | 18 +- 15 files changed, 309 insertions(+), 187 deletions(-) create mode 100644 tests/cases/fourslash/getEditsForFileRename_preservePathEnding.ts create mode 100644 tests/cases/fourslash/importNameCodeFix_endingPreference.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6106505df87..26e5a6b83be 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3926,13 +3926,22 @@ namespace ts { const links = getSymbolLinks(symbol); let specifier = links.specifierCache && links.specifierCache.get(contextFile.path); if (!specifier) { - specifier = moduleSpecifiers.getModuleSpecifierForDeclarationFile( + const isBundle = (compilerOptions.out || compilerOptions.outFile); + // For declaration bundles, we need to generate absolute paths relative to the common source dir for imports, + // just like how the declaration emitter does for the ambient module declarations - we can easily accomplish this + // using the `baseUrl` compiler option (which we would otherwise never use in declaration emit) and a non-relative + // specifier preference + const { moduleResolverHost } = context.tracker; + const specifierCompilerOptions = isBundle ? { ...compilerOptions, baseUrl: moduleResolverHost.getCommonSourceDirectory() } : compilerOptions; + specifier = first(first(moduleSpecifiers.getModuleSpecifiers( symbol, - compilerOptions, + specifierCompilerOptions, contextFile, - context.tracker.moduleResolverHost, + moduleResolverHost, + host.getSourceFiles(), + { importModuleSpecifierPreference: isBundle ? "non-relative" : "relative" }, host.redirectTargetsMap, - ); + ))); links.specifierCache = links.specifierCache || createMap(); links.specifierCache.set(contextFile.path, specifier); } diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 8c695e10be2..18b2ea76b01 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -1,8 +1,52 @@ // Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers. /* @internal */ namespace ts.moduleSpecifiers { - export interface ModuleSpecifierPreferences { - readonly importModuleSpecifierPreference?: "relative" | "non-relative"; + const enum RelativePreference { Relative, NonRelative, Auto } + // See UserPreferences#importPathEnding + const enum Ending { Minimal, Index, JsExtension } + + // Processed preferences + interface Preferences { + readonly relativePreference: RelativePreference; + readonly ending: Ending; + } + + function getPreferences({ importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences, compilerOptions: CompilerOptions, importingSourceFile: SourceFile): Preferences { + return { + relativePreference: importModuleSpecifierPreference === "relative" ? RelativePreference.Relative : importModuleSpecifierPreference === "non-relative" ? RelativePreference.NonRelative : RelativePreference.Auto, + ending: getEnding(), + }; + function getEnding(): Ending { + switch (importModuleSpecifierEnding) { + case "minimal": return Ending.Minimal; + case "index": return Ending.Index; + case "js": return Ending.JsExtension; + default: return usesJsExtensionOnImports(importingSourceFile) ? Ending.JsExtension + : getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs ? Ending.Index : Ending.Minimal; + } + } + } + + function getPreferencesForUpdate(compilerOptions: CompilerOptions, oldImportSpecifier: string): Preferences { + return { + relativePreference: isExternalModuleNameRelative(oldImportSpecifier) ? RelativePreference.Relative : RelativePreference.NonRelative, + ending: hasJavaScriptOrJsonFileExtension(oldImportSpecifier) ? Ending.JsExtension + : getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeJs || endsWith(oldImportSpecifier, "index") ? Ending.Index : Ending.Minimal, + }; + } + + export function updateModuleSpecifier( + compilerOptions: CompilerOptions, + importingSourceFileName: Path, + toFileName: string, + host: ModuleSpecifierResolutionHost, + files: ReadonlyArray, + redirectTargetsMap: RedirectTargetsMap, + oldImportSpecifier: string, + ): string | undefined { + const res = getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, files, redirectTargetsMap, getPreferencesForUpdate(compilerOptions, oldImportSpecifier)); + if (res === oldImportSpecifier) return undefined; + return res; } // Note: importingSourceFile is just for usesJsExtensionOnImports @@ -13,35 +57,25 @@ namespace ts.moduleSpecifiers { toFileName: string, host: ModuleSpecifierResolutionHost, files: ReadonlyArray, - preferences: ModuleSpecifierPreferences = {}, + preferences: UserPreferences = {}, redirectTargetsMap: RedirectTargetsMap, ): string { - const info = getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host); - const modulePaths = getAllModulePaths(files, importingSourceFileName, toFileName, info.getCanonicalFileName, host, redirectTargetsMap); - return firstDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions)) || - first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); + return getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, files, redirectTargetsMap, getPreferences(preferences, compilerOptions, importingSourceFile)); } - export function getModuleSpecifierForDeclarationFile( - moduleSymbol: Symbol, + function getModuleSpecifierWorker( compilerOptions: CompilerOptions, - importingSourceFile: SourceFile, + importingSourceFileName: Path, + toFileName: string, host: ModuleSpecifierResolutionHost, + files: ReadonlyArray, redirectTargetsMap: RedirectTargetsMap, + preferences: Preferences ): string { - const isBundle = (compilerOptions.out || compilerOptions.outFile); - if (isBundle && host.getCommonSourceDirectory) { - // For declaration bundles, we need to generate absolute paths relative to the common source dir for imports, - // just like how the declaration emitter does for the ambient module declarations - we can easily accomplish this - // using the `baseUrl` compiler option (which we would otherwise never use in declaration emit) and a non-relative - // specifier preference - compilerOptions = { - ...compilerOptions, - baseUrl: host.getCommonSourceDirectory(), - }; - } - const preferences: ModuleSpecifierPreferences = { importModuleSpecifierPreference: isBundle ? "non-relative" : "relative" }; - return first(first(getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, host.getSourceFiles ? host.getSourceFiles() : [importingSourceFile], preferences, redirectTargetsMap))); + const info = getInfo(importingSourceFileName, host); + const modulePaths = getAllModulePaths(files, importingSourceFileName, toFileName, info.getCanonicalFileName, host, redirectTargetsMap); + return firstDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions)) || + first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); } // For each symlink/original for a module, returns a list of ways to import that file. @@ -51,60 +85,39 @@ namespace ts.moduleSpecifiers { importingSourceFile: SourceFile, host: ModuleSpecifierResolutionHost, files: ReadonlyArray, - preferences: ModuleSpecifierPreferences, + userPreferences: UserPreferences, redirectTargetsMap: RedirectTargetsMap, ): ReadonlyArray> { const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); if (ambient) return [[ambient]]; - const info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.path, host); - if (!files) { - return Debug.fail("Files list must be present to resolve symlinks in specifier resolution"); - } + const info = getInfo(importingSourceFile.path, host); const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol)); const modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap); - const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions)); + const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile); + const global = mapDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions)); return global.length ? global.map(g => [g]) : modulePaths.map(moduleFileName => getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences)); } interface Info { - readonly moduleResolutionKind: ModuleResolutionKind; - readonly addJsExtension: boolean; readonly getCanonicalFileName: GetCanonicalFileName; readonly sourceDirectory: Path; } // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path - function getInfo(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Info { - const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); - const addJsExtension = usesJsExtensionOnImports(importingSourceFile); + function getInfo(importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Info { const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); const sourceDirectory = getDirectoryPath(importingSourceFileName); - return { moduleResolutionKind, addJsExtension, getCanonicalFileName, sourceDirectory }; + return { getCanonicalFileName, sourceDirectory }; } - function getGlobalModuleSpecifier( - moduleFileName: string, - { addJsExtension, getCanonicalFileName, sourceDirectory }: Info, - host: ModuleSpecifierResolutionHost, - compilerOptions: CompilerOptions, - ) { - return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) - || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory); - } - - function getLocalModuleSpecifiers( - moduleFileName: string, - { moduleResolutionKind, addJsExtension, getCanonicalFileName, sourceDirectory }: Info, - compilerOptions: CompilerOptions, - preferences: ModuleSpecifierPreferences, - ): ReadonlyArray { + function getLocalModuleSpecifiers(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): ReadonlyArray { const { baseUrl, paths, rootDirs } = compilerOptions; const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) || - removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); - if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { + removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions); + if (!baseUrl || relativePreference === RelativePreference.Relative) { return [relativePath]; } @@ -113,7 +126,7 @@ namespace ts.moduleSpecifiers { return [relativePath]; } - const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); + const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions); if (paths) { const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); if (fromPaths) { @@ -121,11 +134,11 @@ namespace ts.moduleSpecifiers { } } - if (preferences.importModuleSpecifierPreference === "non-relative") { + if (relativePreference === RelativePreference.NonRelative) { return [importRelativeToBaseUrl]; } - if (preferences.importModuleSpecifierPreference !== undefined) Debug.assertNever(preferences.importModuleSpecifierPreference); + if (relativePreference !== RelativePreference.Auto) Debug.assertNever(relativePreference); if (isPathRelativeToParent(relativeToBaseUrl)) { return [relativePath]; @@ -164,7 +177,7 @@ namespace ts.moduleSpecifiers { } function usesJsExtensionOnImports({ imports }: SourceFile): boolean { - return firstDefined(imports, ({ text }) => pathIsRelative(text) ? fileExtensionIs(text, Extension.Js) : undefined) || false; + return firstDefined(imports, ({ text }) => pathIsRelative(text) ? hasJavaScriptOrJsonFileExtension(text) : undefined) || false; } function stringsEqual(a: string, b: string, getCanonicalFileName: GetCanonicalFileName): boolean { @@ -283,37 +296,8 @@ namespace ts.moduleSpecifiers { return removeFileExtension(relativePath); } - function tryGetModuleNameFromTypeRoots( - options: CompilerOptions, - host: GetEffectiveTypeRootsHost, - getCanonicalFileName: (file: string) => string, - moduleFileName: string, - addJsExtension: boolean, - ): string | undefined { - const roots = getEffectiveTypeRoots(options, host); - return firstDefined(roots, unNormalizedTypeRoot => { - const typeRoot = toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); - if (startsWith(moduleFileName, typeRoot)) { - // For a type definition, we can strip `/index` even with classic resolution. - return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ModuleResolutionKind.NodeJs, addJsExtension); - } - }); - } - - function tryGetModuleNameAsNodeModule( - options: CompilerOptions, - moduleFileName: string, - host: ModuleSpecifierResolutionHost, - getCanonicalFileName: (file: string) => string, - sourceDirectory: Path, - ): string | undefined { - if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) { - // nothing to do here - return undefined; - } - + function tryGetModuleNameAsNodeModule(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, host: ModuleSpecifierResolutionHost, options: CompilerOptions): string | undefined { const parts: NodeModulePathParts = getNodeModulePathParts(moduleFileName)!; - if (!parts) { return undefined; } @@ -325,8 +309,12 @@ namespace ts.moduleSpecifiers { // Get a path that's relative to node_modules or the importing file's path // if node_modules folder is in this folder or any of its parent folders, no need to keep it. if (!startsWith(sourceDirectory, getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex)))) return undefined; + // If the module was found in @types, get the actual Node package name - return getPackageNameFromAtTypesDirectory(moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1)); + const nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1); + const packageName = getPackageNameFromAtTypesDirectory(nodeModulesDirectoryName); + // For classic resolution, only allow importing from node_modules/@types, not other node_modules + return getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName; function getDirectoryOrExtensionlessFileName(path: string): string { // If the file is the main module, it can be imported by the package name @@ -440,13 +428,35 @@ namespace ts.moduleSpecifiers { }); } - function removeExtensionAndIndexPostFix(fileName: string, moduleResolutionKind: ModuleResolutionKind, addJsExtension: boolean): string { + function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, options: CompilerOptions): string { const noExtension = removeFileExtension(fileName); - return addJsExtension - ? noExtension + ".js" - : moduleResolutionKind === ModuleResolutionKind.NodeJs - ? removeSuffix(noExtension, "/index") - : noExtension; + switch (ending) { + case Ending.Minimal: + return removeSuffix(noExtension, "/index"); + case Ending.Index: + return noExtension; + case Ending.JsExtension: + return noExtension + getJavaScriptExtensionForFile(fileName, options); + default: + return Debug.assertNever(ending); + } + } + + function getJavaScriptExtensionForFile(fileName: string, options: CompilerOptions): Extension { + const ext = extensionFromPath(fileName); + switch (ext) { + case Extension.Ts: + case Extension.Dts: + return Extension.Js; + case Extension.Tsx: + return options.jsx === JsxEmit.Preserve ? Extension.Jsx : Extension.Js; + case Extension.Js: + case Extension.Jsx: + case Extension.Json: + return ext; + default: + return Debug.assertNever(ext); + } } function getRelativePathIfInDirectory(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName): string | undefined { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d9d57cfcf17..8977d9be281 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5331,8 +5331,6 @@ namespace ts { useCaseSensitiveFileNames?(): boolean; fileExists?(path: string): boolean; readFile?(path: string): string | undefined; - getSourceFiles?(): ReadonlyArray; // Used for cached resolutions to find symlinks without traversing the fs (again) - getCommonSourceDirectory?(): string; } // Note: this used to be deprecated in our public API, but is still used internally @@ -5345,7 +5343,7 @@ namespace ts { reportInaccessibleThisError?(): void; reportPrivateInBaseOfClassExpression?(propertyName: string): void; reportInaccessibleUniqueSymbolError?(): void; - moduleResolverHost?: ModuleSpecifierResolutionHost; + moduleResolverHost?: EmitHost; trackReferencedAmbientModule?(decl: ModuleDeclaration, symbol: Symbol): void; trackExternalModuleSymbolOfImportTypeNode?(symbol: Symbol): void; } @@ -5595,4 +5593,15 @@ namespace ts { get(key: TKey): PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][]; forEach(action: (value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][], key: TKey) => void): void; } + + export interface UserPreferences { + readonly disableSuggestions?: boolean; + readonly quotePreference?: "double" | "single"; + readonly includeCompletionsForModuleExports?: boolean; + readonly includeCompletionsWithInsertText?: boolean; + readonly importModuleSpecifierPreference?: "relative" | "non-relative"; + /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ + readonly importModuleSpecifierEnding?: "minimal" | "index" | "js"; + readonly allowTextChangesInNewFiles?: boolean; + } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b808a1f2fd1..d04f921ec95 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -7936,6 +7936,7 @@ namespace ts { /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */ export const supportedTypescriptExtensionsForExtractExtension: ReadonlyArray = [Extension.Dts, Extension.Ts, Extension.Tsx]; export const supportedJavascriptExtensions: ReadonlyArray = [Extension.Js, Extension.Jsx]; + export const supportedJavaScriptAndJsonExtensions: ReadonlyArray = [Extension.Js, Extension.Jsx, Extension.Json]; const allSupportedExtensions: ReadonlyArray = [...supportedTypeScriptExtensions, ...supportedJavascriptExtensions]; export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray): ReadonlyArray { @@ -7961,6 +7962,10 @@ namespace ts { return some(supportedJavascriptExtensions, extension => fileExtensionIs(fileName, extension)); } + export function hasJavaScriptOrJsonFileExtension(fileName: string): boolean { + return supportedJavaScriptAndJsonExtensions.some(ext => fileExtensionIs(fileName, ext)); + } + export function hasTypeScriptFileExtension(fileName: string): boolean { return some(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension)); } diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index bd00ce5dd9e..4fe024787f3 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -6,7 +6,7 @@ namespace ts { newFileOrDirPath: string, host: LanguageServiceHost, formatContext: formatting.FormatContext, - preferences: UserPreferences, + _preferences: UserPreferences, sourceMapper: SourceMapper, ): ReadonlyArray { const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host); @@ -15,7 +15,7 @@ namespace ts { const newToOld = getPathUpdater(newFileOrDirPath, oldFileOrDirPath, getCanonicalFileName, sourceMapper); return textChanges.ChangeTracker.with({ host, formatContext }, changeTracker => { updateTsconfigFiles(program, changeTracker, oldToNew, newFileOrDirPath, host.getCurrentDirectory(), useCaseSensitiveFileNames); - updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName, preferences); + updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName); }); } @@ -122,7 +122,6 @@ namespace ts { newToOld: PathUpdater, host: LanguageServiceHost, getCanonicalFileName: GetCanonicalFileName, - preferences: UserPreferences, ): void { const allFiles = program.getSourceFiles(); for (const sourceFile of allFiles) { @@ -156,7 +155,7 @@ namespace ts { // Need an update if the imported file moved, or the importing file moved and was using a relative path. return toImport !== undefined && (toImport.updated || (importingSourceFileMoved && pathIsRelative(importLiteral.text))) - ? moduleSpecifiers.getModuleSpecifier(program.getCompilerOptions(), sourceFile, newImportFromPath, toImport.newFileName, host, allFiles, preferences, program.redirectTargetsMap) + ? moduleSpecifiers.updateModuleSpecifier(program.getCompilerOptions(), newImportFromPath, toImport.newFileName, host, allFiles, program.redirectTargetsMap, importLiteral.text) : undefined; }); } @@ -210,7 +209,7 @@ namespace ts { } function updateImportsWorker(sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker, updateRef: (refText: string) => string | undefined, updateImport: (importLiteral: StringLiteralLike) => string | undefined) { - for (const ref of sourceFile.referencedFiles) { + for (const ref of sourceFile.referencedFiles || emptyArray) { // TODO: GH#26162 const updated = updateRef(ref.fileName); if (updated !== undefined && updated !== sourceFile.text.slice(ref.pos, ref.end)) changeTracker.replaceRangeWithText(sourceFile, ref, updated); } diff --git a/src/services/types.ts b/src/services/types.ts index 51c98724c09..9bf0edf3150 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -233,14 +233,6 @@ namespace ts { installPackage?(options: InstallPackageOptions): Promise; } - export interface UserPreferences { - readonly disableSuggestions?: boolean; - readonly quotePreference?: "double" | "single"; - readonly includeCompletionsForModuleExports?: boolean; - readonly includeCompletionsWithInsertText?: boolean; - readonly importModuleSpecifierPreference?: "relative" | "non-relative"; - readonly allowTextChangesInNewFiles?: boolean; - } /* @internal */ export const emptyOptions = {}; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5c261c55a4c..e8cda88590b 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2990,6 +2990,16 @@ declare namespace ts { Parameters = 1296, IndexSignatureParameters = 4432 } + interface UserPreferences { + readonly disableSuggestions?: boolean; + readonly quotePreference?: "double" | "single"; + readonly includeCompletionsForModuleExports?: boolean; + readonly includeCompletionsWithInsertText?: boolean; + readonly importModuleSpecifierPreference?: "relative" | "non-relative"; + /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ + readonly importModuleSpecifierEnding?: "minimal" | "index" | "js"; + readonly allowTextChangesInNewFiles?: boolean; + } } declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any; declare function clearTimeout(handle: any): void; @@ -4636,14 +4646,6 @@ declare namespace ts { isKnownTypesPackageName?(name: string): boolean; installPackage?(options: InstallPackageOptions): Promise; } - interface UserPreferences { - readonly disableSuggestions?: boolean; - readonly quotePreference?: "double" | "single"; - readonly includeCompletionsForModuleExports?: boolean; - readonly includeCompletionsWithInsertText?: boolean; - readonly importModuleSpecifierPreference?: "relative" | "non-relative"; - readonly allowTextChangesInNewFiles?: boolean; - } interface LanguageService { cleanupSemanticCache(): void; getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index e92e3d6e1d5..c12d797bea8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2990,6 +2990,16 @@ declare namespace ts { Parameters = 1296, IndexSignatureParameters = 4432 } + interface UserPreferences { + readonly disableSuggestions?: boolean; + readonly quotePreference?: "double" | "single"; + readonly includeCompletionsForModuleExports?: boolean; + readonly includeCompletionsWithInsertText?: boolean; + readonly importModuleSpecifierPreference?: "relative" | "non-relative"; + /** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */ + readonly importModuleSpecifierEnding?: "minimal" | "index" | "js"; + readonly allowTextChangesInNewFiles?: boolean; + } } declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any; declare function clearTimeout(handle: any): void; @@ -4636,14 +4646,6 @@ declare namespace ts { isKnownTypesPackageName?(name: string): boolean; installPackage?(options: InstallPackageOptions): Promise; } - interface UserPreferences { - readonly disableSuggestions?: boolean; - readonly quotePreference?: "double" | "single"; - readonly includeCompletionsForModuleExports?: boolean; - readonly includeCompletionsWithInsertText?: boolean; - readonly importModuleSpecifierPreference?: "relative" | "non-relative"; - readonly allowTextChangesInNewFiles?: boolean; - } interface LanguageService { cleanupSemanticCache(): void; getSyntacticDiagnostics(fileName: string): DiagnosticWithLocation[]; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 8a91718dd7b..2d73be1a917 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -528,10 +528,11 @@ declare namespace FourSlashInterface { filesToSearch?: ReadonlyArray; } interface UserPreferences { - quotePreference?: "double" | "single"; - includeCompletionsForModuleExports?: boolean; - includeInsertTextCompletions?: boolean; - importModuleSpecifierPreference?: "relative" | "non-relative"; + readonly quotePreference?: "double" | "single"; + readonly includeCompletionsForModuleExports?: boolean; + readonly includeInsertTextCompletions?: boolean; + readonly importModuleSpecifierPreference?: "relative" | "non-relative"; + readonly importModuleSpecifierEnding?: "minimal" | "index" | "js"; } interface CompletionsAtOptions extends UserPreferences { triggerCharacter?: string; diff --git a/tests/cases/fourslash/getEditsForFileRename_preservePathEnding.ts b/tests/cases/fourslash/getEditsForFileRename_preservePathEnding.ts new file mode 100644 index 00000000000..54b3e0e0612 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_preservePathEnding.ts @@ -0,0 +1,44 @@ +/// + +// @allowJs: true +// @checkJs: true +// @strict: true +// @jsx: preserve +// @resolveJsonModule: true + +// @Filename: /index.js +////export const x = 0; + +// @Filename: /jsx.jsx +////export const y = 0; + +// @Filename: /j.jonah.json +////{ "j": 0 } + +// @Filename: /a.js +////import { x as x0 } from "."; +////import { x as x1 } from "./index"; +////import { x as x2 } from "./index.js"; +////import { y } from "./jsx.jsx"; +////import { j } from "./j.jonah.json"; + +verify.noErrors(); + +verify.getEditsForFileRename({ + oldPath: "/a.js", + newPath: "/b.js", + newFileContents: {}, // No change +}); + +verify.getEditsForFileRename({ + oldPath: "/b.js", + newPath: "/src/b.js", + newFileContents: { + "/b.js": +`import { x as x0 } from ".."; +import { x as x1 } from "../index"; +import { x as x2 } from "../index.js"; +import { y } from "../jsx.jsx"; +import { j } from "../j.jonah.json";`, + }, +}); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots0.ts b/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots0.ts index cb7ef465aff..ddc6d1790c7 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots0.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots0.ts @@ -1,22 +1,23 @@ -/// - -// @Filename: a/f1.ts -//// [|foo/*0*/();|] - -// @Filename: types/random/index.ts -//// export function foo() {}; - -// @Filename: tsconfig.json -//// { -//// "compilerOptions": { -//// "typeRoots": [ -//// "./types" -//// ] -//// } -//// } - -verify.importFixAtPosition([ -`import { foo } from "random"; - -foo();` -]); +/// + +// @Filename: a/f1.ts +//// [|foo/*0*/();|] + +// @Filename: types/random/index.ts +//// export function foo() {}; + +// @Filename: tsconfig.json +//// { +//// "compilerOptions": { +//// "typeRoots": [ +//// "./types" +//// ] +//// } +//// } + +// "typeRoots" does not affect module resolution. Importing from "random" would be a compile error. +verify.importFixAtPosition([ +`import { foo } from "../types/random"; + +foo();` +]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots1.ts b/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots1.ts index 1398a5d7866..9743d164a9c 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots1.ts @@ -1,23 +1,27 @@ -/// - -// @Filename: a/f1.ts -//// [|foo/*0*/();|] - -// @Filename: types/random/index.ts -//// export function foo() {}; - -// @Filename: tsconfig.json -//// { -//// "compilerOptions": { -//// "baseUrl": ".", -//// "typeRoots": [ -//// "./types" -//// ] -//// } -//// } - -verify.importFixAtPosition([ -`import { foo } from "random"; - -foo();` -]); +/// + +// @Filename: a/f1.ts +//// [|foo/*0*/();|] + +// @Filename: types/random/index.ts +//// export function foo() {}; + +// @Filename: tsconfig.json +//// { +//// "compilerOptions": { +//// "baseUrl": ".", +//// "typeRoots": [ +//// "./types" +//// ] +//// } +//// } + +// "typeRoots" does not affect module resolution. Importing from "random" would be a compile error. +verify.importFixAtPosition([ +`import { foo } from "types/random"; + +foo();`, +`import { foo } from "../types/random"; + +foo();` +]); diff --git a/tests/cases/fourslash/importNameCodeFix_endingPreference.ts b/tests/cases/fourslash/importNameCodeFix_endingPreference.ts new file mode 100644 index 00000000000..41a96e9cf06 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_endingPreference.ts @@ -0,0 +1,26 @@ +/// + +// @moduleResolution: node + +// @Filename: /foo/index.ts +////export const foo = 0; + +// @Filename: /a.ts +////foo; + +// @Filename: /b.ts +////foo; + +// @Filename: /c.ts +////foo; + +const tests: ReadonlyArray<[string, FourSlashInterface.UserPreferences["importModuleSpecifierEnding"], string]> = [ + ["/a.ts", "js", "./foo/index.js"], + ["/b.ts", "index", "./foo/index"], + ["/c.ts", "minimal", "./foo"], +]; + +for (const [fileName, importModuleSpecifierEnding, specifier] of tests) { + goTo.file(fileName); + verify.importFixAtPosition([`import { foo } from "${specifier}";\n\nfoo;`,], /*errorCode*/ undefined, { importModuleSpecifierEnding }); +} diff --git a/tests/cases/fourslash/importNameCodeFix_jsExtension.ts b/tests/cases/fourslash/importNameCodeFix_jsExtension.ts index e719f1aeee8..b47e67d82b2 100644 --- a/tests/cases/fourslash/importNameCodeFix_jsExtension.ts +++ b/tests/cases/fourslash/importNameCodeFix_jsExtension.ts @@ -2,6 +2,7 @@ // @moduleResolution: node // @noLib: true +// @jsx: preserve // @Filename: /a.ts ////export function a() {} @@ -9,17 +10,24 @@ // @Filename: /b.ts ////export function b() {} +// @Filename: /c.tsx +////export function c() {} + // @Filename: /c.ts ////import * as g from "global"; // Global imports skipped ////import { a } from "./a.js"; ////import { a as a2 } from "./a"; // Ignored, only the first relative import is considered -////b; +////b; c; goTo.file("/c.ts"); -verify.importFixAtPosition([ +verify.codeFixAll({ + fixId: "fixMissingImport", + fixAllDescription: "Add all missing imports", + newFileContent: `import * as g from "global"; // Global imports skipped import { a } from "./a.js"; import { a as a2 } from "./a"; // Ignored, only the first relative import is considered import { b } from "./b.js"; -b;`, -]); +import { c } from "./c.jsx"; +b; c;`, +}); diff --git a/tests/cases/fourslash/importNameCodeFix_types_classic.ts b/tests/cases/fourslash/importNameCodeFix_types_classic.ts index b9ba463fada..4d3bdda4d31 100644 --- a/tests/cases/fourslash/importNameCodeFix_types_classic.ts +++ b/tests/cases/fourslash/importNameCodeFix_types_classic.ts @@ -5,12 +5,22 @@ // @Filename: /node_modules/@types/foo/index.d.ts ////export const xyz: number; +// @Filename: /node_modules/bar/index.d.ts +////export const qrs: number; + // @Filename: /a.ts -////[|xyz|] +////xyz; +////qrs; goTo.file("/a.ts"); -verify.importFixAtPosition([ +verify.codeFixAll({ + fixId: "fixMissingImport", + fixAllDescription: "Add all missing imports", + newFileContent: `import { xyz } from "foo"; -xyz` -]); +import { qrs } from "./node_modules/bar/index"; + +xyz; +qrs;`, +}); From 552bd1c8a2cba709c5161e8bd667d60c591eccef Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 28 Aug 2018 13:04:11 -0700 Subject: [PATCH 075/163] Support import fix/completions for `export =` (#25708) --- src/compiler/checker.ts | 2 - src/compiler/types.ts | 4 ++ src/harness/fourslash.ts | 6 ++- src/services/codefixes/importFixes.ts | 49 +++++++++++------ src/services/completions.ts | 8 +++ .../completionsImport_default_anonymous.ts | 2 +- .../completionsImport_exportEquals.ts | 53 +++++++++++++++++++ ...mport_exportEqualsNamespace_noDuplicate.ts | 2 +- .../cases/fourslash/completionsImport_tsx.ts | 2 +- .../completionsUniqueSymbol_import.ts | 2 +- .../cases/fourslash/importNameCodeFix_all.ts | 2 +- .../importNameCodeFix_exportEquals.ts | 25 +++++++++ 12 files changed, 132 insertions(+), 25 deletions(-) create mode 100644 tests/cases/fourslash/completionsImport_exportEquals.ts create mode 100644 tests/cases/fourslash/importNameCodeFix_exportEquals.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 26e5a6b83be..41573a7a8f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2286,8 +2286,6 @@ namespace ts { return getPackagesSet().has(getTypesPackageName(packageName)); } - // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, - // and an external module with no 'export =' declaration resolves to the module itself. function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol; function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined; function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8977d9be281..e024885d6e8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3097,6 +3097,10 @@ namespace ts { */ /* @internal */ getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined; /* @internal */ getTypePredicateOfSignature(signature: Signature): TypePredicate; + /** + * An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, + * and an external module with no 'export =' declaration resolves to the module itself. + */ /* @internal */ resolveExternalModuleSymbol(symbol: Symbol): Symbol; /** @param node A location where we might consider accessing `this`. Not necessarily a ThisExpression. */ /* @internal */ tryGetThisTypeAt(node: Node): Type | undefined; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 5d1ac5c491f..214e1f295ab 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -908,8 +908,8 @@ namespace FourSlash { } private verifyCompletionEntry(actual: ts.CompletionEntry, expected: FourSlashInterface.ExpectedCompletionEntry) { - const { insertText, replacementSpan, hasAction, isRecommended, kind, text, documentation, sourceDisplay } = typeof expected === "string" - ? { insertText: undefined, replacementSpan: undefined, hasAction: undefined, isRecommended: undefined, kind: undefined, text: undefined, documentation: undefined, sourceDisplay: undefined } + const { insertText, replacementSpan, hasAction, isRecommended, kind, text, documentation, source, sourceDisplay } = typeof expected === "string" + ? { insertText: undefined, replacementSpan: undefined, hasAction: undefined, isRecommended: undefined, kind: undefined, text: undefined, documentation: undefined, source: undefined, sourceDisplay: undefined } : expected; if (actual.insertText !== insertText) { @@ -927,6 +927,7 @@ namespace FourSlash { assert.equal(actual.hasAction, hasAction); assert.equal(actual.isRecommended, isRecommended); + assert.equal(actual.source, source); if (text) { const actualDetails = this.getCompletionEntryDetails(actual.name, actual.source)!; @@ -4789,6 +4790,7 @@ namespace FourSlashInterface { export type ExpectedCompletionEntry = string | { readonly name: string, + readonly source?: string, readonly insertText?: string, readonly replacementSpan?: FourSlash.Range, readonly hasAction?: boolean, // If not specified, will assert that this is false. diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 3c5b1d06eaf..7ff5d30c954 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -163,7 +163,7 @@ namespace ts.codefix { position: number, preferences: UserPreferences, ): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } { - const exportInfos = getAllReExportingModules(exportedSymbol, moduleSymbol, symbolName, sourceFile, program.getTypeChecker(), program.getSourceFiles()); + const exportInfos = getAllReExportingModules(exportedSymbol, moduleSymbol, symbolName, sourceFile, program.getCompilerOptions(), program.getTypeChecker(), program.getSourceFiles()); Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol)); // We sort the best codefixes first, so taking `first` is best for completions. const moduleSpecifier = first(getNewImportInfos(program, sourceFile, position, exportInfos, host, preferences)).moduleSpecifier; @@ -175,7 +175,7 @@ namespace ts.codefix { return { description, changes, commands }; } - function getAllReExportingModules(exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, sourceFile: SourceFile, checker: TypeChecker, allSourceFiles: ReadonlyArray): ReadonlyArray { + function getAllReExportingModules(exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, sourceFile: SourceFile, compilerOptions: CompilerOptions, checker: TypeChecker, allSourceFiles: ReadonlyArray): ReadonlyArray { const result: SymbolExportInfo[] = []; forEachExternalModule(checker, allSourceFiles, (moduleSymbol, moduleFile) => { // Don't import from a re-export when looking "up" like to `./index` or `../index`. @@ -183,10 +183,14 @@ namespace ts.codefix { return; } + const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions); + if (defaultInfo && defaultInfo.name === symbolName && skipAlias(defaultInfo.symbol, checker) === exportedSymbol) { + result.push({ moduleSymbol, importKind: defaultInfo.kind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(defaultInfo.symbol) }); + } + for (const exported of checker.getExportsOfModule(moduleSymbol)) { - if ((exported.escapedName === InternalSymbolName.Default || exported.name === symbolName) && skipAlias(exported, checker) === exportedSymbol) { - const isDefaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol) === exported; - result.push({ moduleSymbol, importKind: isDefaultExport ? ImportKind.Default : ImportKind.Named, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exported) }); + if (exported.name === symbolName && skipAlias(exported, checker) === exportedSymbol) { + result.push({ moduleSymbol, importKind: ImportKind.Named, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exported) }); } } }); @@ -400,13 +404,9 @@ namespace ts.codefix { forEachExternalModuleToImportFrom(checker, sourceFile, program.getSourceFiles(), moduleSymbol => { cancellationToken.throwIfCancellationRequested(); - // check the default export - const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol); - if (defaultExport) { - const info = getDefaultExportInfo(defaultExport, moduleSymbol, program); - if (info && info.name === symbolName && symbolHasMeaning(info.symbolForMeaning, currentTokenMeaning)) { - addSymbol(moduleSymbol, defaultExport, ImportKind.Default); - } + const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, program.getCompilerOptions()); + if (defaultInfo && defaultInfo.name === symbolName && symbolHasMeaning(defaultInfo.symbolForMeaning, currentTokenMeaning)) { + addSymbol(moduleSymbol, defaultInfo.symbol, defaultInfo.kind); } // check exports with the same name @@ -418,7 +418,24 @@ namespace ts.codefix { return originalSymbolToExportInfos; } - function getDefaultExportInfo(defaultExport: Symbol, moduleSymbol: Symbol, program: Program): { readonly symbolForMeaning: Symbol, readonly name: string } | undefined { + function getDefaultLikeExportInfo( + moduleSymbol: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions, + ): { readonly symbol: Symbol, readonly symbolForMeaning: Symbol, readonly name: string, readonly kind: ImportKind.Default | ImportKind.Equals } | undefined { + const exported = getDefaultLikeExportWorker(moduleSymbol, checker); + if (!exported) return undefined; + const { symbol, kind } = exported; + const info = getDefaultExportInfoWorker(symbol, moduleSymbol, checker, compilerOptions); + return info && { symbol, symbolForMeaning: info.symbolForMeaning, name: info.name, kind }; + } + + function getDefaultLikeExportWorker(moduleSymbol: Symbol, checker: TypeChecker): { readonly symbol: Symbol, readonly kind: ImportKind.Default | ImportKind.Equals } | undefined { + const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol); + if (defaultExport) return { symbol: defaultExport, kind: ImportKind.Default }; + const exportEquals = checker.resolveExternalModuleSymbol(moduleSymbol); + return exportEquals === moduleSymbol ? undefined : { symbol: exportEquals, kind: ImportKind.Equals }; + } + + function getDefaultExportInfoWorker(defaultExport: Symbol, moduleSymbol: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions): { readonly symbolForMeaning: Symbol, readonly name: string } | undefined { const localSymbol = getLocalSymbolForExportDefault(defaultExport); if (localSymbol) return { symbolForMeaning: localSymbol, name: localSymbol.name }; @@ -426,11 +443,11 @@ namespace ts.codefix { if (name !== undefined) return { symbolForMeaning: defaultExport, name }; if (defaultExport.flags & SymbolFlags.Alias) { - const aliased = program.getTypeChecker().getImmediateAliasedSymbol(defaultExport); - return aliased && getDefaultExportInfo(aliased, Debug.assertDefined(aliased.parent), program); + const aliased = checker.getImmediateAliasedSymbol(defaultExport); + return aliased && getDefaultExportInfoWorker(aliased, Debug.assertDefined(aliased.parent), checker, compilerOptions); } else { - return { symbolForMeaning: defaultExport, name: moduleSymbolToValidIdentifier(moduleSymbol, program.getCompilerOptions().target!) }; + return { symbolForMeaning: defaultExport, name: moduleSymbolToValidIdentifier(moduleSymbol, compilerOptions.target!) }; } } diff --git a/src/services/completions.ts b/src/services/completions.ts index 40986543318..7f82c9e7483 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1378,6 +1378,14 @@ namespace ts.Completions { return; } + if (resolvedModuleSymbol !== moduleSymbol && + // Don't add another completion for `export =` of a symbol that's already global. + // So in `declare namespace foo {} declare module "foo" { export = foo; }`, there will just be the global completion for `foo`. + resolvedModuleSymbol.declarations.some(d => !!d.getSourceFile().externalModuleIndicator)) { + symbols.push(resolvedModuleSymbol); + symbolToOriginInfoMap[getSymbolId(resolvedModuleSymbol)] = { kind: SymbolOriginInfoKind.Export, moduleSymbol, isDefaultExport: false }; + } + for (let symbol of typeChecker.getExportsOfModule(moduleSymbol)) { // Don't add a completion for a re-export, only for the original. // The actual import fix might end up coming from a re-export -- we don't compute that until getting completion details. diff --git a/tests/cases/fourslash/completionsImport_default_anonymous.ts b/tests/cases/fourslash/completionsImport_default_anonymous.ts index c406259dd6c..82e5f07b064 100644 --- a/tests/cases/fourslash/completionsImport_default_anonymous.ts +++ b/tests/cases/fourslash/completionsImport_default_anonymous.ts @@ -11,7 +11,7 @@ ////fooB/*1*/ goTo.marker("0"); -const preferences = { includeCompletionsForModuleExports: true }; +const preferences: FourSlashInterface.UserPreferences = { includeCompletionsForModuleExports: true }; verify.completions( { marker: "0", excludes: { name: "default", source: "/src/foo-bar" }, preferences }, { marker: "1", includes: { name: "fooBar", source: "/src/foo-bar", sourceDisplay: "./foo-bar", text: "(property) default: 0", kind: "property", hasAction: true }, preferences } diff --git a/tests/cases/fourslash/completionsImport_exportEquals.ts b/tests/cases/fourslash/completionsImport_exportEquals.ts new file mode 100644 index 00000000000..37e78e09f38 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_exportEquals.ts @@ -0,0 +1,53 @@ +/// + +// @module: commonjs + +// @Filename: /a.d.ts +////declare function a(): void; +////declare namespace a { +//// export interface b {} +////} +////export = a; + +// @Filename: /b.ts +////a/*0*/; +////let x: b/*1*/; + +const preferences: FourSlashInterface.UserPreferences = { includeCompletionsForModuleExports: true }; +verify.completions( + { + marker: "0", + includes: { name: "a", source: "/a", hasAction: true, }, + preferences, + }, + { + marker: "1", + includes: { name: "b", source: "/a", hasAction: true }, + preferences, + } +); + +// Import { b } first, or it will just add a qualified name from 'a' (which isn't what we're trying to test) +verify.applyCodeActionFromCompletion("1", { + name: "b", + source: "/a", + description: `Import 'b' from module "./a"`, + newFileContent: +`import { b } from "./a"; + +a; +let x: b;`, +}); + +verify.applyCodeActionFromCompletion("0", { + name: "a", + source: "/a", + description: `Import 'a' from module "./a"`, + newFileContent: +`import { b } from "./a"; +import a = require("./a"); + +a; +let x: b;`, +}); + diff --git a/tests/cases/fourslash/completionsImport_exportEqualsNamespace_noDuplicate.ts b/tests/cases/fourslash/completionsImport_exportEqualsNamespace_noDuplicate.ts index ede97c2d810..8a687f5a191 100644 --- a/tests/cases/fourslash/completionsImport_exportEqualsNamespace_noDuplicate.ts +++ b/tests/cases/fourslash/completionsImport_exportEqualsNamespace_noDuplicate.ts @@ -18,7 +18,7 @@ verify.completions({ marker: "", // Tester will assert that it is only included once - includes: [{ name: "foo", hasAction: true }], + includes: [{ name: "foo", source: "a", hasAction: true }], preferences: { includeCompletionsForModuleExports: true, } diff --git a/tests/cases/fourslash/completionsImport_tsx.ts b/tests/cases/fourslash/completionsImport_tsx.ts index f2f8752082b..9fb4d239223 100644 --- a/tests/cases/fourslash/completionsImport_tsx.ts +++ b/tests/cases/fourslash/completionsImport_tsx.ts @@ -12,7 +12,7 @@ verify.completions({ marker: "", - includes: { name: "Foo", source: "/a.tsx", hasAction: true }, + includes: { name: "Foo", source: "/a", hasAction: true }, excludes: "Bar", preferences: { includeCompletionsForModuleExports: true, diff --git a/tests/cases/fourslash/completionsUniqueSymbol_import.ts b/tests/cases/fourslash/completionsUniqueSymbol_import.ts index df3034e56fe..7f98f8c1dd7 100644 --- a/tests/cases/fourslash/completionsUniqueSymbol_import.ts +++ b/tests/cases/fourslash/completionsUniqueSymbol_import.ts @@ -24,7 +24,7 @@ verify.completions({ marker: "", exact: [ "n", - { name: "publicSym", insertText: "[publicSym]", replacementSpan: test.ranges()[0], hasAction: true }, + { name: "publicSym", source: "/a", insertText: "[publicSym]", replacementSpan: test.ranges()[0], hasAction: true }, ], preferences: { includeInsertTextCompletions: true, diff --git a/tests/cases/fourslash/importNameCodeFix_all.ts b/tests/cases/fourslash/importNameCodeFix_all.ts index 4aa22413d5a..d5bb525900a 100644 --- a/tests/cases/fourslash/importNameCodeFix_all.ts +++ b/tests/cases/fourslash/importNameCodeFix_all.ts @@ -37,11 +37,11 @@ verify.codeFixAll({ fixId: "fixMissingImport", fixAllDescription: "Add all missing imports", newFileContent: -// TODO: GH#25135 (should import 'e') `import bd, * as b from "./b"; import cd, { c0 } from "./c"; import dd, { d0, d1 } from "./d"; import ad, { a0 } from "./a"; +import e = require("./e"); ad; ad; a0; a0; bd; bd; b.b0; b.b0; diff --git a/tests/cases/fourslash/importNameCodeFix_exportEquals.ts b/tests/cases/fourslash/importNameCodeFix_exportEquals.ts new file mode 100644 index 00000000000..4ab87df7e76 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_exportEquals.ts @@ -0,0 +1,25 @@ +/// + +// @Filename: /a.d.ts +////declare function a(): void; +////declare namespace a { +//// export interface b {} +////} +////export = a; + +// @Filename: /b.ts +////a; +////let x: b; + +goTo.file("/b.ts"); +verify.codeFixAll({ + fixId: "fixMissingImport", + fixAllDescription: "Add all missing imports", + newFileContent: +`import { b } from "./a"; + +import a = require("./a"); + +a; +let x: b;`, +}); From 9106fdbc47f4b1e7ddb6458f62c2e00c775591d0 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 28 Aug 2018 14:21:09 -0700 Subject: [PATCH 076/163] Support signature help for type parameters of a type (#26702) --- src/compiler/checker.ts | 4 +- src/compiler/types.ts | 2 + src/services/signatureHelp.ts | 76 +++++++++++++++---- .../genericParameterHelpTypeReferences.ts | 50 +++++++----- 4 files changed, 99 insertions(+), 33 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 41573a7a8f6..cb3fc5614fb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -370,7 +370,9 @@ namespace ts { finally { cancellationToken = undefined; } - } + }, + + getLocalTypeParametersOfClassOrInterfaceOrTypeAlias, }; function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, isForSignatureHelp: boolean): Signature | undefined { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e024885d6e8..10076014d96 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3118,6 +3118,8 @@ namespace ts { * and the operation is cancelled, then it should be discarded, otherwise it is safe to keep. */ runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) => T): T; + + /* @internal */ getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): ReadonlyArray | undefined; } /* @internal */ diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index d1705b51048..5211b244e21 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -2,7 +2,7 @@ namespace ts.SignatureHelp { const enum InvocationKind { Call, TypeArgs, Contextual } interface CallInvocation { readonly kind: InvocationKind.Call; readonly node: CallLikeExpression; } - interface TypeArgsInvocation { readonly kind: InvocationKind.TypeArgs; readonly called: Expression; } + interface TypeArgsInvocation { readonly kind: InvocationKind.TypeArgs; readonly called: Identifier; } interface ContextualInvocation { readonly kind: InvocationKind.Contextual; readonly signature: Signature; @@ -44,7 +44,7 @@ namespace ts.SignatureHelp { cancellationToken.throwIfCancellationRequested(); // Extra syntactic and semantic filtering of signature help - const candidateInfo = getCandidateInfo(argumentInfo, typeChecker, sourceFile, startingToken, onlyUseSyntacticOwners); + const candidateInfo = getCandidateOrTypeInfo(argumentInfo, typeChecker, sourceFile, startingToken, onlyUseSyntacticOwners); cancellationToken.throwIfCancellationRequested(); if (!candidateInfo) { @@ -53,11 +53,24 @@ namespace ts.SignatureHelp { return isSourceFileJavaScript(sourceFile) ? createJavaScriptSignatureHelpItems(argumentInfo, program, cancellationToken) : undefined; } - return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker)); + return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => + candidateInfo.kind === CandidateOrTypeKind.Candidate + ? createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker) + : createTypeHelpItems(candidateInfo.symbol, argumentInfo, sourceFile, typeChecker)); } - interface CandidateInfo { readonly candidates: ReadonlyArray; readonly resolvedSignature: Signature; } - function getCandidateInfo({ invocation, argumentCount }: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): CandidateInfo | undefined { + const enum CandidateOrTypeKind { Candidate, Type } + interface CandidateInfo { + readonly kind: CandidateOrTypeKind.Candidate; + readonly candidates: ReadonlyArray; + readonly resolvedSignature: Signature; + } + interface TypeInfo { + readonly kind: CandidateOrTypeKind.Type; + readonly symbol: Symbol; + } + + function getCandidateOrTypeInfo({ invocation, argumentCount }: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean): CandidateInfo | TypeInfo | undefined { switch (invocation.kind) { case InvocationKind.Call: { if (onlyUseSyntacticOwners && !isSyntacticOwner(startingToken, invocation.node, sourceFile)) { @@ -65,17 +78,21 @@ namespace ts.SignatureHelp { } const candidates: Signature[] = []; const resolvedSignature = checker.getResolvedSignatureForSignatureHelp(invocation.node, candidates, argumentCount)!; // TODO: GH#18217 - return candidates.length === 0 ? undefined : { candidates, resolvedSignature }; + return candidates.length === 0 ? undefined : { kind: CandidateOrTypeKind.Candidate, candidates, resolvedSignature }; } case InvocationKind.TypeArgs: { - if (onlyUseSyntacticOwners && !lessThanFollowsCalledExpression(startingToken, sourceFile, invocation.called)) { + const { called } = invocation; + if (onlyUseSyntacticOwners && !containsPrecedingToken(startingToken, sourceFile, isIdentifier(called) ? called.parent : called)) { return undefined; } - const candidates = getPossibleGenericSignatures(invocation.called, argumentCount, checker); - return candidates.length === 0 ? undefined : { candidates, resolvedSignature: first(candidates) }; + const candidates = getPossibleGenericSignatures(called, argumentCount, checker); + if (candidates.length !== 0) return { kind: CandidateOrTypeKind.Candidate, candidates, resolvedSignature: first(candidates) }; + + const symbol = checker.getSymbolAtLocation(called); + return symbol && { kind: CandidateOrTypeKind.Type, symbol }; } case InvocationKind.Contextual: - return { candidates: [invocation.signature], resolvedSignature: invocation.signature }; + return { kind: CandidateOrTypeKind.Candidate, candidates: [invocation.signature], resolvedSignature: invocation.signature }; default: return Debug.assertNever(invocation); } @@ -92,7 +109,7 @@ namespace ts.SignatureHelp { return !!containingList && contains(invocationChildren, containingList); } case SyntaxKind.LessThanToken: - return lessThanFollowsCalledExpression(startingToken, sourceFile, node.expression); + return containsPrecedingToken(startingToken, sourceFile, node.expression); default: return false; } @@ -114,12 +131,12 @@ namespace ts.SignatureHelp { })); } - function lessThanFollowsCalledExpression(startingToken: Node, sourceFile: SourceFile, calledExpression: Expression) { + function containsPrecedingToken(startingToken: Node, sourceFile: SourceFile, container: Node) { const precedingToken = Debug.assertDefined( findPrecedingToken(startingToken.getFullStart(), sourceFile, startingToken.parent, /*excludeJsdoc*/ true) ); - return rangeContainsRange(calledExpression, precedingToken); + return rangeContainsRange(container, precedingToken); } export interface ArgumentInfoForCompletions { @@ -457,6 +474,10 @@ namespace ts.SignatureHelp { return invocation.kind === InvocationKind.Call ? getInvokedExpression(invocation.node) : invocation.called; } + function getEnclosingDeclarationFromInvocation(invocation: Invocation): Node { + return invocation.kind === InvocationKind.Call ? invocation.node : invocation.kind === InvocationKind.TypeArgs ? invocation.called : invocation.node; + } + const signatureHelpNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope; function createSignatureHelpItems( candidates: ReadonlyArray, @@ -465,7 +486,7 @@ namespace ts.SignatureHelp { sourceFile: SourceFile, typeChecker: TypeChecker, ): SignatureHelpItems { - const enclosingDeclaration = invocation.kind === InvocationKind.Call ? invocation.node : invocation.kind === InvocationKind.TypeArgs ? invocation.called : invocation.node; + const enclosingDeclaration = getEnclosingDeclarationFromInvocation(invocation); const callTargetSymbol = invocation.kind === InvocationKind.Contextual ? invocation.symbol : typeChecker.getSymbolAtLocation(getExpressionFromInvocation(invocation)); const callTargetDisplayParts = callTargetSymbol ? symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined) : emptyArray; const items = candidates.map(candidateSignature => getSignatureHelpItem(candidateSignature, callTargetDisplayParts, isTypeParameterList, typeChecker, enclosingDeclaration, sourceFile)); @@ -480,11 +501,36 @@ namespace ts.SignatureHelp { return { items, applicableSpan, selectedItemIndex, argumentIndex, argumentCount }; } + function createTypeHelpItems( + symbol: Symbol, + { argumentCount, argumentsSpan: applicableSpan, invocation, argumentIndex }: ArgumentListInfo, + sourceFile: SourceFile, + checker: TypeChecker + ): SignatureHelpItems | undefined { + const typeParameters = checker.getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); + if (!typeParameters) return undefined; + const items = [getTypeHelpItem(symbol, typeParameters, checker, getEnclosingDeclarationFromInvocation(invocation), sourceFile)]; + return { items, applicableSpan, selectedItemIndex: 0, argumentIndex, argumentCount }; + } + + function getTypeHelpItem(symbol: Symbol, typeParameters: ReadonlyArray, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem { + const typeSymbolDisplay = symbolToDisplayParts(checker, symbol); + + const printer = createPrinter({ removeComments: true }); + const parameters = typeParameters.map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer)); + + const documentation = symbol.getDocumentationComment(checker); + const tags = symbol.getJsDocTags(); + const prefixDisplayParts = [...typeSymbolDisplay, punctuationPart(SyntaxKind.LessThanToken)]; + return { isVariadic: false, prefixDisplayParts, suffixDisplayParts: [punctuationPart(SyntaxKind.GreaterThanToken)], separatorDisplayParts, parameters, documentation, tags }; + } + + const separatorDisplayParts: SymbolDisplayPart[] = [punctuationPart(SyntaxKind.CommaToken), spacePart()]; + function getSignatureHelpItem(candidateSignature: Signature, callTargetDisplayParts: ReadonlyArray, isTypeParameterList: boolean, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem { const { isVariadic, parameters, prefix, suffix } = (isTypeParameterList ? itemInfoForTypeParameters : itemInfoForParameters)(candidateSignature, checker, enclosingDeclaration, sourceFile); const prefixDisplayParts = [...callTargetDisplayParts, ...prefix]; const suffixDisplayParts = [...suffix, ...returnTypeToDisplayParts(candidateSignature, enclosingDeclaration, checker)]; - const separatorDisplayParts = [punctuationPart(SyntaxKind.CommaToken), spacePart()]; const documentation = candidateSignature.getDocumentationComment(checker); const tags = candidateSignature.getJsDocTags(); return { isVariadic, prefixDisplayParts, suffixDisplayParts, separatorDisplayParts, parameters, documentation, tags }; diff --git a/tests/cases/fourslash/genericParameterHelpTypeReferences.ts b/tests/cases/fourslash/genericParameterHelpTypeReferences.ts index 5a477d23e56..a5dee833248 100644 --- a/tests/cases/fourslash/genericParameterHelpTypeReferences.ts +++ b/tests/cases/fourslash/genericParameterHelpTypeReferences.ts @@ -11,21 +11,37 @@ ////var x : testClass extends testClass; +//// +////interface I {} +////let i: I; +//// +////type Ty = T; +////let t: Ty; -// TODO: GH#26699 - -if (false) { - verify.signatureHelp( - { - marker: ["type1", "type2", "type3"], - text: "testClass", - parameterName: "T", - parameterSpan: "T extends IFoo", - }, - { - marker: "type4", - parameterName: "M", - parameterSpan: "M extends IFoo", - } - ); -} +verify.signatureHelp( + { + marker: ["type1", "type2", "type3"], + text: "testClass", + parameterName: "T", + parameterSpan: "T extends IFoo", + triggerReason: { kind: "characterTyped", triggerCharacter: "<" }, + }, + { + marker: "type4", + parameterName: "M", + parameterSpan: "M extends IFoo", + triggerReason: { kind: "characterTyped", triggerCharacter: "," }, + }, + { + marker: "interface", + text: "I", + parameterName: "T", + parameterSpan: "T", + }, + { + marker: "typeAlias", + text: "Ty", + parameterName: "T", + parameterSpan: "T", + }, +); From fc90b8f98b6dbf3a4fbae22a4c310382700fc099 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 28 Aug 2018 14:08:59 -0700 Subject: [PATCH 077/163] lazyConfiguredProjectsFromExternalProject as userpreference instead of command line option --- src/server/editorServices.ts | 17 ++++-- src/server/project.ts | 5 ++ src/server/protocol.ts | 1 + src/server/session.ts | 2 - src/services/types.ts | 1 + .../unittests/tsserverProjectSystem.ts | 61 +++++++++++++++++-- src/tsserver/server.ts | 2 - 7 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index c506c656de7..d941ce2f3f4 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -323,7 +323,6 @@ namespace ts.server { cancellationToken: HostCancellationToken; useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; - lazyConfiguredProjectsFromExternalProject?: boolean; typingsInstaller: ITypingsInstaller; eventHandler?: ProjectServiceEventHandler; suppressDiagnosticEvents?: boolean; @@ -441,7 +440,6 @@ namespace ts.server { public readonly cancellationToken: HostCancellationToken; public readonly useSingleInferredProject: boolean; public readonly useInferredProjectPerProjectRoot: boolean; - private readonly lazyConfiguredProjectsFromExternalProject?: boolean; public readonly typingsInstaller: ITypingsInstaller; private readonly globalCacheLocationDirectoryPath: Path | undefined; public readonly throttleWaitMilliseconds?: number; @@ -467,7 +465,6 @@ namespace ts.server { this.cancellationToken = opts.cancellationToken; this.useSingleInferredProject = opts.useSingleInferredProject; this.useInferredProjectPerProjectRoot = opts.useInferredProjectPerProjectRoot; - this.lazyConfiguredProjectsFromExternalProject = opts.lazyConfiguredProjectsFromExternalProject; this.typingsInstaller = opts.typingsInstaller || nullTypingsInstaller; this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds; this.eventHandler = opts.eventHandler; @@ -1989,7 +1986,19 @@ namespace ts.server { this.logger.info("Format host information updated"); } if (args.preferences) { + const { lazyConfiguredProjectsFromExternalProject } = this.hostConfiguration.preferences; this.hostConfiguration.preferences = { ...this.hostConfiguration.preferences, ...args.preferences }; + if (lazyConfiguredProjectsFromExternalProject && !this.hostConfiguration.preferences.lazyConfiguredProjectsFromExternalProject) { + // Load configured projects for external projects that are pending reload + this.configuredProjects.forEach(project => { + if (project.hasExternalProjectRef() && + project.pendingReload === ConfigFileProgramReloadLevel.Full && + !this.pendingProjectUpdates.has(project.getProjectName())) { + this.loadConfiguredProject(project); + project.updateGraph(); + } + }); + } } if (args.extraFileExtensions) { this.hostConfiguration.extraFileExtensions = args.extraFileExtensions; @@ -2642,7 +2651,7 @@ namespace ts.server { let project = this.findConfiguredProjectByProjectName(tsconfigFile); if (!project) { // errors are stored in the project, do not need to update the graph - project = this.lazyConfiguredProjectsFromExternalProject ? + project = this.getHostPreferences().lazyConfiguredProjectsFromExternalProject ? this.createConfiguredProjectWithDelayLoad(tsconfigFile) : this.createLoadAndUpdateConfiguredProject(tsconfigFile); } diff --git a/src/server/project.ts b/src/server/project.ts index ff2c504a54a..9589108c93d 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1520,6 +1520,11 @@ namespace ts.server { ) || false; } + /*@internal*/ + hasExternalProjectRef() { + return !!this.externalProjectRefCount; + } + getEffectiveTypeRoots() { return getEffectiveTypeRoots(this.getCompilationSettings(), this.directoryStructureHost) || []; } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 39a0045d97e..441c1316c99 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2823,6 +2823,7 @@ namespace ts.server.protocol { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; + readonly lazyConfiguredProjectsFromExternalProject?: boolean; } export interface CompilerOptions { diff --git a/src/server/session.ts b/src/server/session.ts index 69328b4c73b..8d2fbe9e190 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -465,7 +465,6 @@ namespace ts.server { cancellationToken: ServerCancellationToken; useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; - lazyConfiguredProjectsFromExternalProject?: boolean; typingsInstaller: ITypingsInstaller; byteLength: (buf: string, encoding?: string) => number; hrtime: (start?: number[]) => number[]; @@ -537,7 +536,6 @@ namespace ts.server { cancellationToken: this.cancellationToken, useSingleInferredProject: opts.useSingleInferredProject, useInferredProjectPerProjectRoot: opts.useInferredProjectPerProjectRoot, - lazyConfiguredProjectsFromExternalProject: opts.lazyConfiguredProjectsFromExternalProject, typingsInstaller: this.typingsInstaller, throttleWaitMilliseconds, eventHandler: this.eventHandler, diff --git a/src/services/types.ts b/src/services/types.ts index 51c98724c09..73a70c786b7 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -240,6 +240,7 @@ namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; + readonly lazyConfiguredProjectsFromExternalProject?: boolean; } /* @internal */ export const emptyOptions = {}; diff --git a/src/testRunner/unittests/tsserverProjectSystem.ts b/src/testRunner/unittests/tsserverProjectSystem.ts index 7ef838fd6ff..cb608d26dc6 100644 --- a/src/testRunner/unittests/tsserverProjectSystem.ts +++ b/src/testRunner/unittests/tsserverProjectSystem.ts @@ -656,7 +656,8 @@ namespace ts.projectSystem { }; const host = createServerHost([f1, config], { useCaseSensitiveFileNames: false }); - const service = createProjectService(host, /*parameters*/ undefined, { lazyConfiguredProjectsFromExternalProject }); + const service = createProjectService(host); + service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); const upperCaseConfigFilePath = combinePaths(getDirectoryPath(config.path).toUpperCase(), getBaseFileName(config.path)); service.openExternalProject({ projectFileName: "/a/b/project.csproj", @@ -670,7 +671,7 @@ namespace ts.projectSystem { checkProjectActualFiles(project, emptyArray); } else { - assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project pending to be reloaded + assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded checkProjectActualFiles(project, [upperCaseConfigFilePath]); } @@ -2978,7 +2979,8 @@ namespace ts.projectSystem { }; const projectFileName = "/user/someuser/project/WebApplication6.csproj"; const host = createServerHost([libFile, site, configFile]); - const projectService = createProjectService(host, /*parameters*/ undefined, { lazyConfiguredProjectsFromExternalProject }); + const projectService = createProjectService(host); + projectService.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); const externalProject: protocol.ExternalProject = { projectFileName, @@ -3341,8 +3343,12 @@ namespace ts.projectSystem { }; const host = createServerHost([file1, file2, tsconfig]); - const session = createSession(host, { lazyConfiguredProjectsFromExternalProject }); + const session = createSession(host); const projectService = session.getProjectService(); + session.executeCommandSeq({ + command: protocol.CommandTypes.Configure, + arguments: { preferences: { lazyConfiguredProjectsFromExternalProject } } + }); // Configure the deferred extension. const extraFileExtensions = [{ extension: ".deferred", scriptKind: ScriptKind.Deferred, isMixedContent: true }]; @@ -3995,7 +4001,8 @@ namespace ts.projectSystem { content: "" }; const host = createServerHost([f1, f2]); - const projectService = createProjectService(host, /*parameters*/ undefined, { lazyConfiguredProjectsFromExternalProject }); + const projectService = createProjectService(host); + projectService.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); // open external project const projectName = "/a/b/proj1"; @@ -4064,7 +4071,8 @@ namespace ts.projectSystem { content: "{}" }; const host = createServerHost([f1, cLib, cTsconfig, dLib, dTsconfig]); - const projectService = createProjectService(host, /*parameters*/ undefined, { lazyConfiguredProjectsFromExternalProject }); + const projectService = createProjectService(host); + projectService.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject } }); // open external project const projectName = "/a/b/proj1"; @@ -4233,6 +4241,47 @@ namespace ts.projectSystem { assert.isTrue(project.hasOpenRef()); // f assert.isFalse(project.isClosed()); }); + + it("handles loads existing configured projects of external projects when lazyConfiguredProjectsFromExternalProject is disabled", () => { + const f1 = { + path: "/a/b/app.ts", + content: "let x = 1" + }; + const config = { + path: "/a/b/tsconfig.json", + content: JSON.stringify({}) + }; + const projectFileName = "/a/b/project.csproj"; + const host = createServerHost([f1, config]); + const service = createProjectService(host); + service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject: true } }); + service.openExternalProject({ + projectFileName, + rootFiles: toExternalFiles([f1.path, config.path]), + options: {} + }); + service.checkNumberOfProjects({ configuredProjects: 1 }); + const project = service.configuredProjects.get(config.path)!; + assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.Full); // External project referenced configured project pending to be reloaded + checkProjectActualFiles(project, emptyArray); + + service.setHostConfiguration({ preferences: { lazyConfiguredProjectsFromExternalProject: false } }); + assert.equal(project.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded + checkProjectActualFiles(project, [config.path, f1.path]); + + service.closeExternalProject(projectFileName); + service.checkNumberOfProjects({}); + + service.openExternalProject({ + projectFileName, + rootFiles: toExternalFiles([f1.path, config.path]), + options: {} + }); + service.checkNumberOfProjects({ configuredProjects: 1 }); + const project2 = service.configuredProjects.get(config.path)!; + assert.equal(project2.pendingReload, ConfigFileProgramReloadLevel.None); // External project referenced configured project loaded + checkProjectActualFiles(project2, [config.path, f1.path]); + }); }); describe("tsserverProjectSystem prefer typings to js", () => { diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index 6b8a146d8f3..3e5986e9408 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -499,7 +499,6 @@ namespace ts.server { cancellationToken, useSingleInferredProject, useInferredProjectPerProjectRoot, - lazyConfiguredProjectsFromExternalProject, typingsInstaller: typingsInstaller || nullTypingsInstaller, byteLength: Buffer.byteLength, hrtime: process.hrtime, @@ -938,7 +937,6 @@ namespace ts.server { const useSingleInferredProject = hasArgument("--useSingleInferredProject"); const useInferredProjectPerProjectRoot = hasArgument("--useInferredProjectPerProjectRoot"); - const lazyConfiguredProjectsFromExternalProject = hasArgument("--lazyConfiguredProjectsFromExternalProject"); const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition"); const suppressDiagnosticEvents = hasArgument("--suppressDiagnosticEvents"); const syntaxOnly = hasArgument("--syntaxOnly"); From 03bb5d170ec721897de059514dfa03d0a9da6c60 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 28 Aug 2018 15:47:17 -0700 Subject: [PATCH 078/163] Use protocol.UserPreferences in server to store UserPreferences --- src/server/editorServices.ts | 18 +++++++++--------- src/server/scriptInfo.ts | 6 +++--- src/server/session.ts | 6 +++--- .../reference/api/tsserverlibrary.d.ts | 15 +++++---------- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 63e8ac0a937..292c8d77fc6 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1,9 +1,3 @@ -namespace ts { - export interface UserPreferences { - readonly lazyConfiguredProjectsFromExternalProject?: boolean; - } -} - namespace ts.server { export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; /*@internal*/ @@ -224,9 +218,15 @@ namespace ts.server { } } + /*@internal*/ + export function convertUserPreferences(preferences: protocol.UserPreferences): UserPreferences { + const { lazyConfiguredProjectsFromExternalProject, ...userPreferences } = preferences; + return userPreferences; + } + export interface HostConfiguration { formatCodeOptions: FormatCodeSettings; - preferences: UserPreferences; + preferences: protocol.UserPreferences; hostInfo: string; extraFileExtensions?: FileExtensionInfo[]; } @@ -808,7 +808,7 @@ namespace ts.server { return info && info.getFormatCodeSettings() || this.hostConfiguration.formatCodeOptions; } - getPreferences(file: NormalizedPath): UserPreferences { + getPreferences(file: NormalizedPath): protocol.UserPreferences { const info = this.getScriptInfoForNormalizedPath(file); return info && info.getPreferences() || this.hostConfiguration.preferences; } @@ -817,7 +817,7 @@ namespace ts.server { return this.hostConfiguration.formatCodeOptions; } - getHostPreferences(): UserPreferences { + getHostPreferences(): protocol.UserPreferences { return this.hostConfiguration.preferences; } diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index c6992e91b88..085dd6d0eef 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -234,7 +234,7 @@ namespace ts.server { */ readonly containingProjects: Project[] = []; private formatSettings: FormatCodeSettings | undefined; - private preferences: UserPreferences | undefined; + private preferences: protocol.UserPreferences | undefined; /* @internal */ fileWatcher: FileWatcher | undefined; @@ -333,7 +333,7 @@ namespace ts.server { } getFormatCodeSettings(): FormatCodeSettings | undefined { return this.formatSettings; } - getPreferences(): UserPreferences | undefined { return this.preferences; } + getPreferences(): protocol.UserPreferences | undefined { return this.preferences; } attachToProject(project: Project): boolean { const isNew = !this.isAttached(project); @@ -432,7 +432,7 @@ namespace ts.server { } } - setOptions(formatSettings: FormatCodeSettings, preferences: UserPreferences | undefined): void { + setOptions(formatSettings: FormatCodeSettings, preferences: protocol.UserPreferences | undefined): void { if (formatSettings) { if (!this.formatSettings) { this.formatSettings = getDefaultFormatCodeSettings(this.host); diff --git a/src/server/session.ts b/src/server/session.ts index 8d2fbe9e190..6c3413601d0 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1423,7 +1423,7 @@ namespace ts.server { const position = this.getPosition(args, scriptInfo); const completions = project.getLanguageService().getCompletionsAtPosition(file, position, { - ...this.getPreferences(file), + ...convertUserPreferences(this.getPreferences(file)), triggerCharacter: args.triggerCharacter, includeExternalModuleExports: args.includeExternalModuleExports, includeInsertTextCompletions: args.includeInsertTextCompletions @@ -2352,7 +2352,7 @@ namespace ts.server { return this.projectService.getFormatCodeOptions(file); } - private getPreferences(file: NormalizedPath): UserPreferences { + private getPreferences(file: NormalizedPath): protocol.UserPreferences { return this.projectService.getPreferences(file); } @@ -2360,7 +2360,7 @@ namespace ts.server { return this.projectService.getHostFormatCodeOptions(); } - private getHostPreferences(): UserPreferences { + private getHostPreferences(): protocol.UserPreferences { return this.projectService.getHostPreferences(); } } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5ef55512f97..186f3eeff1c 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7929,14 +7929,14 @@ declare namespace ts.server { getSnapshot(): IScriptSnapshot; private ensureRealPath; getFormatCodeSettings(): FormatCodeSettings | undefined; - getPreferences(): UserPreferences | undefined; + getPreferences(): protocol.UserPreferences | undefined; attachToProject(project: Project): boolean; isAttached(project: Project): boolean; detachFromProject(project: Project): void; detachAllProjects(): void; getDefaultProject(): Project; registerFileUpdate(): void; - setOptions(formatSettings: FormatCodeSettings, preferences: UserPreferences | undefined): void; + setOptions(formatSettings: FormatCodeSettings, preferences: protocol.UserPreferences | undefined): void; getLatestVersion(): string; saveTo(fileName: string): void; reloadFromFile(tempFileName?: NormalizedPath): boolean; @@ -8201,11 +8201,6 @@ declare namespace ts.server { setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void; } } -declare namespace ts { - interface UserPreferences { - readonly lazyConfiguredProjectsFromExternalProject?: boolean; - } -} declare namespace ts.server { const maxProgramSizeForNonTsFiles: number; const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground"; @@ -8319,7 +8314,7 @@ declare namespace ts.server { function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX; interface HostConfiguration { formatCodeOptions: FormatCodeSettings; - preferences: UserPreferences; + preferences: protocol.UserPreferences; hostInfo: string; extraFileExtensions?: FileExtensionInfo[]; } @@ -8438,9 +8433,9 @@ declare namespace ts.server { */ private ensureProjectStructuresUptoDate; getFormatCodeOptions(file: NormalizedPath): FormatCodeSettings; - getPreferences(file: NormalizedPath): UserPreferences; + getPreferences(file: NormalizedPath): protocol.UserPreferences; getHostFormatCodeOptions(): FormatCodeSettings; - getHostPreferences(): UserPreferences; + getHostPreferences(): protocol.UserPreferences; private onSourceFileChanged; private handleDeletedFile; private onConfigChangedForConfiguredProject; From 723e64ba3bbeaa9bb4abd347689c9153bc0c091e Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 28 Aug 2018 15:36:09 -0700 Subject: [PATCH 079/163] Add js source maps to list of outputs when doing --build Fixes #26619 --- src/compiler/tsbuild.ts | 13 ++++++++++--- src/testRunner/unittests/tsbuild.ts | 4 ++-- tests/projects/sample1/core/tsconfig.json | 3 ++- tests/projects/sample1/logic/tsconfig.json | 1 + 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index f038136e6a4..e52c743bb36 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -317,12 +317,16 @@ namespace ts { } const outputs: string[] = []; - outputs.push(getOutputJavaScriptFileName(inputFileName, configFile)); + const js = getOutputJavaScriptFileName(inputFileName, configFile); + outputs.push(js); + if (configFile.options.sourceMap) { + outputs.push(`${js}.map`); + } if (getEmitDeclarations(configFile.options) && !fileExtensionIs(inputFileName, Extension.Json)) { const dts = getOutputDeclarationFileName(inputFileName, configFile); outputs.push(dts); if (configFile.options.declarationMap) { - outputs.push(dts + ".map"); + outputs.push(`${dts}.map`); } } return outputs; @@ -334,11 +338,14 @@ namespace ts { } const outputs: string[] = []; outputs.push(project.options.outFile); + if (project.options.sourceMap) { + outputs.push(`${project.options.outFile}.map`); + } if (getEmitDeclarations(project.options)) { const dts = changeExtension(project.options.outFile, Extension.Dts); outputs.push(dts); if (project.options.declarationMap) { - outputs.push(dts + ".map"); + outputs.push(`${dts}.map`); } } return outputs; diff --git a/src/testRunner/unittests/tsbuild.ts b/src/testRunner/unittests/tsbuild.ts index b7d708446c1..ea99ee92457 100644 --- a/src/testRunner/unittests/tsbuild.ts +++ b/src/testRunner/unittests/tsbuild.ts @@ -5,8 +5,8 @@ namespace ts { const projFs = loadProjectFromDisk("tests/projects/sample1"); const allExpectedOutputs = ["/src/tests/index.js", - "/src/core/index.js", "/src/core/index.d.ts", - "/src/logic/index.js", "/src/logic/index.d.ts"]; + "/src/core/index.js", "/src/core/index.d.ts", "/src/core/index.d.ts.map", + "/src/logic/index.js", "/src/logic/index.js.map", "/src/logic/index.d.ts"]; describe("tsbuild - sanity check of clean build of 'sample1' project", () => { it("can build the sample project 'sample1' without error", () => { diff --git a/tests/projects/sample1/core/tsconfig.json b/tests/projects/sample1/core/tsconfig.json index b8332f5c476..24b64bc7b2c 100644 --- a/tests/projects/sample1/core/tsconfig.json +++ b/tests/projects/sample1/core/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "composite": true, - "declaration": true + "declaration": true, + "declarationMap": true } } \ No newline at end of file diff --git a/tests/projects/sample1/logic/tsconfig.json b/tests/projects/sample1/logic/tsconfig.json index 43c78ea4e96..939e6f5659b 100644 --- a/tests/projects/sample1/logic/tsconfig.json +++ b/tests/projects/sample1/logic/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "composite": true, "declaration": true, + "sourceMap": true, "forceConsistentCasingInFileNames": true }, "references": [ From cff04e6050143696203f233407fce93f5086e89e Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 28 Aug 2018 16:43:14 -0700 Subject: [PATCH 080/163] Ensure JsonSourceFile has all the non-optional properties of SourceFile (#26162) * Ensure JsonSourceFile has all the non-optional properties of SourceFile * Set properties in parseSourceFile --- src/compiler/moduleSpecifiers.ts | 1 + src/compiler/parser.ts | 7 +++++-- src/compiler/types.ts | 10 ++++++++-- src/compiler/utilities.ts | 2 +- .../getEditsForFileRename_resolveJsonModule.ts | 17 +++++++++++++++++ 5 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/getEditsForFileRename_resolveJsonModule.ts diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 18b2ea76b01..b34471a107a 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -429,6 +429,7 @@ namespace ts.moduleSpecifiers { } function removeExtensionAndIndexPostFix(fileName: string, ending: Ending, options: CompilerOptions): string { + if (fileExtensionIs(fileName, Extension.Json)) return fileName; const noExtension = removeFileExtension(fileName); switch (ending) { case Ending.Minimal: diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 096c3f16354..e9eb953d22a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -515,7 +515,7 @@ namespace ts { performance.mark("beforeParse"); let result: SourceFile; if (languageVersion === ScriptTarget.JSON) { - result = Parser.parseJsonText(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes); + result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, ScriptKind.JSON); } else { result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind); @@ -689,8 +689,12 @@ namespace ts { if (scriptKind === ScriptKind.JSON) { const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); convertToObjectWorker(result, result.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); + result.referencedFiles = emptyArray; result.typeReferenceDirectives = emptyArray; + result.libReferenceDirectives = emptyArray; result.amdDependencies = emptyArray; + result.hasNoDefaultLib = false; + result.pragmas = emptyMap; return result; } @@ -7754,7 +7758,6 @@ namespace ts { } } - /*@internal*/ type PragmaDiagnosticReporter = (pos: number, length: number, message: DiagnosticMessage) => void; /*@internal*/ diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 10076014d96..54e19154376 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2632,7 +2632,7 @@ namespace ts { /* @internal */ ambientModuleNames: ReadonlyArray; /* @internal */ checkJsDirective?: CheckJsDirective; /* @internal */ version: string; - /* @internal */ pragmas: PragmaMap; + /* @internal */ pragmas: ReadonlyPragmaMap; /* @internal */ localJsxNamespace?: __String; /* @internal */ localJsxFactory?: EntityName; @@ -5588,13 +5588,19 @@ namespace ts { /* @internal */ export type PragmaPsuedoMapEntry = {[K in keyof PragmaPsuedoMap]: {name: K, args: PragmaPsuedoMap[K]}}[keyof PragmaPsuedoMap]; + /* @internal */ + export interface ReadonlyPragmaMap extends ReadonlyMap { + get(key: TKey): PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][]; + forEach(action: (value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][], key: TKey) => void): void; + } + /** * A strongly-typed es6 map of pragma entries, the values of which are either a single argument * value (if only one was found), or an array of multiple argument values if the pragma is present * in multiple places */ /* @internal */ - export interface PragmaMap extends Map { + export interface PragmaMap extends Map, ReadonlyPragmaMap { set(key: TKey, value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][]): this; get(key: TKey): PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][]; forEach(action: (value: PragmaPsuedoMap[TKey] | PragmaPsuedoMap[TKey][], key: TKey) => void): void; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index d04f921ec95..0e92bad7f55 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -16,7 +16,7 @@ namespace ts { namespace ts { export const emptyArray: never[] = [] as never[]; export const resolvingEmptyArray: never[] = [] as never[]; - export const emptyMap: ReadonlyMap = createMap(); + export const emptyMap = createMap() as ReadonlyMap & ReadonlyPragmaMap; export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap = emptyMap as ReadonlyUnderscoreEscapedMap; export const externalHelpersModuleNameText = "tslib"; diff --git a/tests/cases/fourslash/getEditsForFileRename_resolveJsonModule.ts b/tests/cases/fourslash/getEditsForFileRename_resolveJsonModule.ts new file mode 100644 index 00000000000..3aa86c6aad0 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_resolveJsonModule.ts @@ -0,0 +1,17 @@ +/// + +// @resolveJsonModule: true + +// @Filename: /a.ts +////import text from "./message.json"; + +// @Filename: /message.json +////{} + +verify.getEditsForFileRename({ + oldPath: "/a.ts", + newPath: "/src/a.ts", + newFileContents: { + "/a.ts": 'import text from "../message.json";', + }, +}); From 30f611b0558c3c594e25d0280d91567e26c61ecb Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 28 Aug 2018 19:57:39 -0700 Subject: [PATCH 081/163] Add survey event (#26455) * Start adding survey event * Add surveyReady event * Remove old notes * Move event, simplify type, add test 1. Move the survey event to sendProjectTelemetry so that it happens on open instead of on editing tsconfig. 2. Remove URL from the survey type; VS code should control this information. 3. Add test based on large files event test. I'm not sure it's in the right place, though. * Fix tests and update API baseline * Split survey sending from telemetry Based on tests requested during review. * Add additional assertion --- src/server/editorServices.ts | 33 ++++- src/server/project.ts | 2 + src/server/protocol.ts | 12 ++ src/server/session.ts | 4 + .../unittests/tsserverProjectSystem.ts | 117 +++++++++++++++++- .../reference/api/tsserverlibrary.d.ts | 20 ++- 6 files changed, 185 insertions(+), 3 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 292c8d77fc6..b4382410717 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -5,6 +5,7 @@ namespace ts.server { // tslint:disable variable-name export const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground"; + export const SurveyReady = "surveyReady"; export const LargeFileReferencedEvent = "largeFileReferenced"; export const ConfigFileDiagEvent = "configFileDiag"; export const ProjectLanguageServiceStateEvent = "projectLanguageServiceState"; @@ -17,6 +18,11 @@ namespace ts.server { data: { openFiles: string[]; }; } + export interface SurveyReady { + eventName: typeof SurveyReady; + data: { surveyId: string; }; + } + export interface LargeFileReferencedEvent { eventName: typeof LargeFileReferencedEvent; data: { file: string; fileSize: number; maxFileSize: number; }; @@ -98,7 +104,7 @@ namespace ts.server { readonly checkJs: boolean; } - export type ProjectServiceEvent = LargeFileReferencedEvent | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent; + export type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent; export type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void; @@ -462,6 +468,9 @@ namespace ts.server { /** Tracks projects that we have already sent telemetry for. */ private readonly seenProjects = createMap(); + /** Tracks projects that we have already sent survey events for. */ + private readonly seenSurveyProjects = createMap(); + /*@internal*/ readonly watchFactory: WatchFactory; @@ -663,6 +672,14 @@ namespace ts.server { this.eventHandler(event); } + /* @internal */ + sendSurveyReadyEvent(surveyId: string) { + if (!this.eventHandler) { + return; + } + this.eventHandler({ eventName: SurveyReady, data: { surveyId } }); + } + /* @internal */ sendLargeFileReferencedEvent(file: string, fileSize: number) { if (!this.eventHandler) { @@ -1477,6 +1494,20 @@ namespace ts.server { return project; } + /*@internal*/ + sendSurveyReady(project: ExternalProject | ConfiguredProject): void { + if (this.seenSurveyProjects.has(project.projectName)) { + return; + } + + if (project.getCompilerOptions().checkJs !== undefined) { + const name = "checkJs"; + this.logger.info(`Survey ${name} is ready`); + this.sendSurveyReadyEvent(name); + this.seenSurveyProjects.set(project.projectName, true); + } + } + /*@internal*/ sendProjectTelemetry(project: ExternalProject | ConfiguredProject): void { if (this.seenProjects.has(project.projectName)) { diff --git a/src/server/project.ts b/src/server/project.ts index 9589108c93d..f20530c88a9 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1366,6 +1366,7 @@ namespace ts.server { result = super.updateGraph(); } this.projectService.sendProjectTelemetry(this); + this.projectService.sendSurveyReady(this); return result; } @@ -1570,6 +1571,7 @@ namespace ts.server { updateGraph() { const result = super.updateGraph(); this.projectService.sendProjectTelemetry(this); + this.projectService.sendSurveyReady(this); return result; } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 441c1316c99..5c6d9bed337 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2436,6 +2436,18 @@ namespace ts.server.protocol { openFiles: string[]; } + export type SurveyReadyEventName = "surveyReady"; + + export interface SurveyReadyEvent extends Event { + event: SurveyReadyEventName; + body: SurveyReadyEventBody; + } + + export interface SurveyReadyEventBody { + /** Name of the survey. This is an internal machine- and programmer-friendly name */ + surveyId: string; + } + export type LargeFileReferencedEventName = "largeFileReferenced"; export interface LargeFileReferencedEvent extends Event { event: LargeFileReferencedEventName; diff --git a/src/server/session.ts b/src/server/session.ts index 6c3413601d0..d923942cd5c 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -572,6 +572,10 @@ namespace ts.server { diagnostics: bakedDiags }, "configFileDiag"); break; + case SurveyReady: + const { surveyId } = event.data; + this.event({ surveyId }, "surveyReady"); + break; case ProjectLanguageServiceStateEvent: { const eventName: protocol.ProjectLanguageServiceStateEventName = "projectLanguageServiceState"; this.event({ diff --git a/src/testRunner/unittests/tsserverProjectSystem.ts b/src/testRunner/unittests/tsserverProjectSystem.ts index be144246ed6..a1e0c0932b2 100644 --- a/src/testRunner/unittests/tsserverProjectSystem.ts +++ b/src/testRunner/unittests/tsserverProjectSystem.ts @@ -2863,7 +2863,7 @@ namespace ts.projectSystem { const session = createSession(host, { canUseEvents: true, eventHandler: e => { - if (e.eventName === server.ConfigFileDiagEvent || e.eventName === server.ProjectsUpdatedInBackgroundEvent || e.eventName === server.ProjectInfoTelemetryEvent || e.eventName === server.OpenFileInfoTelemetryEvent || e.eventName === server.LargeFileReferencedEvent) { + if (e.eventName === server.ConfigFileDiagEvent || e.eventName === server.ProjectsUpdatedInBackgroundEvent || e.eventName === server.ProjectInfoTelemetryEvent || e.eventName === server.OpenFileInfoTelemetryEvent || e.eventName === server.LargeFileReferencedEvent || e.eventName === server.SurveyReady) { return; } assert.equal(e.eventName, server.ProjectLanguageServiceStateEvent); @@ -3539,6 +3539,121 @@ namespace ts.projectSystem { } }); + function createSessionWithEventHandler(host: TestServerHost) { + const surveyEvents: server.SurveyReady[] = []; + const session = createSession(host, { + eventHandler: e => { + if (e.eventName === server.SurveyReady) { + surveyEvents.push(e); + } + } + }); + + return { session, verifySurveyReadyEvent }; + + function verifySurveyReadyEvent(numberOfEvents: number) { + assert.equal(surveyEvents.length, numberOfEvents); + const expectedEvents = numberOfEvents === 0 ? [] : [{ + eventName: server.SurveyReady, + data: { surveyId: "checkJs" } + }]; + assert.deepEqual(surveyEvents, expectedEvents); + } + } + + it("doesn't log an event when checkJs isn't set", () => { + const projectRoot = "/user/username/projects/project"; + const file: File = { + path: `${projectRoot}/src/file.ts`, + content: "export var y = 10;" + }; + const tsconfig: File = { + path: `${projectRoot}/tsconfig.json`, + content: JSON.stringify({ compilerOptions: { } }), + }; + const host = createServerHost([file, tsconfig]); + const { session, verifySurveyReadyEvent } = createSessionWithEventHandler(host); + const service = session.getProjectService(); + openFilesForSession([file], session); + checkNumberOfProjects(service, { configuredProjects: 1 }); + const project = service.configuredProjects.get(tsconfig.path)!; + checkProjectActualFiles(project, [file.path, tsconfig.path]); + + verifySurveyReadyEvent(0); + }); + + it("logs an event when checkJs is set", () => { + const projectRoot = "/user/username/projects/project"; + const file: File = { + path: `${projectRoot}/src/file.ts`, + content: "export var y = 10;" + }; + const tsconfig: File = { + path: `${projectRoot}/tsconfig.json`, + content: JSON.stringify({ compilerOptions: { checkJs: true } }), + }; + const host = createServerHost([file, tsconfig]); + const { session, verifySurveyReadyEvent } = createSessionWithEventHandler(host); + openFilesForSession([file], session); + + verifySurveyReadyEvent(1); + }); + + it("logs an event when checkJs is set, only the first time", () => { + const projectRoot = "/user/username/projects/project"; + const file: File = { + path: `${projectRoot}/src/file.ts`, + content: "export var y = 10;" + }; + const rando: File = { + path: `/rando/calrissian.ts`, + content: "export function f() { }" + }; + const tsconfig: File = { + path: `${projectRoot}/tsconfig.json`, + content: JSON.stringify({ compilerOptions: { checkJs: true } }), + }; + const host = createServerHost([file, tsconfig]); + const { session, verifySurveyReadyEvent } = createSessionWithEventHandler(host); + openFilesForSession([file], session); + + verifySurveyReadyEvent(1); + + closeFilesForSession([file], session); + openFilesForSession([rando], session); + openFilesForSession([file], session); + + verifySurveyReadyEvent(1); + }); + + it("logs an event when checkJs is set after closing and reopening", () => { + const projectRoot = "/user/username/projects/project"; + const file: File = { + path: `${projectRoot}/src/file.ts`, + content: "export var y = 10;" + }; + const rando: File = { + path: `/rando/calrissian.ts`, + content: "export function f() { }" + }; + const tsconfig: File = { + path: `${projectRoot}/tsconfig.json`, + content: JSON.stringify({ }), + }; + const host = createServerHost([file, tsconfig]); + const { session, verifySurveyReadyEvent } = createSessionWithEventHandler(host); + openFilesForSession([file], session); + + verifySurveyReadyEvent(0); + + closeFilesForSession([file], session); + openFilesForSession([rando], session); + host.writeFile(tsconfig.path, JSON.stringify({ compilerOptions: { checkJs: true } })); + openFilesForSession([file], session); + + verifySurveyReadyEvent(1); + }); + describe("CompileOnSaveAffectedFileListRequest with and without projectFileName in request", () => { const projectRoot = "/user/username/projects/myproject"; const core: File = { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 186f3eeff1c..911fd328f3b 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7462,6 +7462,15 @@ declare namespace ts.server.protocol { */ openFiles: string[]; } + type SurveyReadyEventName = "surveyReady"; + interface SurveyReadyEvent extends Event { + event: SurveyReadyEventName; + body: SurveyReadyEventBody; + } + interface SurveyReadyEventBody { + /** Name of the survey. This is an internal machine- and programmer-friendly name */ + surveyId: string; + } type LargeFileReferencedEventName = "largeFileReferenced"; interface LargeFileReferencedEvent extends Event { event: LargeFileReferencedEventName; @@ -8204,6 +8213,7 @@ declare namespace ts.server { declare namespace ts.server { const maxProgramSizeForNonTsFiles: number; const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground"; + const SurveyReady = "surveyReady"; const LargeFileReferencedEvent = "largeFileReferenced"; const ConfigFileDiagEvent = "configFileDiag"; const ProjectLanguageServiceStateEvent = "projectLanguageServiceState"; @@ -8215,6 +8225,12 @@ declare namespace ts.server { openFiles: string[]; }; } + interface SurveyReady { + eventName: typeof SurveyReady; + data: { + surveyId: string; + }; + } interface LargeFileReferencedEvent { eventName: typeof LargeFileReferencedEvent; data: { @@ -8293,7 +8309,7 @@ declare namespace ts.server { interface OpenFileInfo { readonly checkJs: boolean; } - type ProjectServiceEvent = LargeFileReferencedEvent | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent; + type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent; type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void; interface SafeList { [name: string]: { @@ -8412,6 +8428,8 @@ declare namespace ts.server { readonly syntaxOnly?: boolean; /** Tracks projects that we have already sent telemetry for. */ private readonly seenProjects; + /** Tracks projects that we have already sent survey events for. */ + private readonly seenSurveyProjects; constructor(opts: ProjectServiceOptions); toPath(fileName: string): Path; private loadTypesMap; From 0d3adffd1a87bec80e36feda4caad3638ff28b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Wed, 29 Aug 2018 18:42:02 +0800 Subject: [PATCH 082/163] accept baseline --- ...ctAndSimpleParameterList_es2016.errors.txt | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt index 4887cb4f07a..4f92ac06b2b 100644 --- a/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt +++ b/tests/baselines/reference/functionWithUseStrictAndSimpleParameterList_es2016.errors.txt @@ -1,33 +1,33 @@ -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(1,12): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(2,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(15,15): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(16,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(19,16): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(19,23): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(20,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(23,23): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(24,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(27,31): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(28,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(31,30): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(32,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,24): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,32): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(36,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(39,23): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(39,31): error TS1345: This parameter is not allowed with 'use strict' directive. -tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(41,5): error TS1346: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(1,12): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(2,5): error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(15,15): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(16,5): error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(19,16): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(19,23): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(20,5): error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(23,23): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(24,5): error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(27,31): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(28,5): error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(31,30): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(32,5): error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,24): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(35,32): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(36,5): error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(39,23): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(39,31): error TS1346: This parameter is not allowed with 'use strict' directive. +tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts(41,5): error TS1347: 'use strict' directive cannot be used with non-simple parameter list. ==== tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts (19 errors) ==== function a(a = 10) { ~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:2:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:2:5: 'use strict' directive used here. "use strict"; ~~~~~~~~~~~~~ -!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:1:12: Non-simple parameter declared here. +!!! error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:1:12: Non-simple parameter declared here. } export var foo = 10; @@ -42,84 +42,84 @@ tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es function rest(...args: any[]) { ~~~~~~~~~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:16:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:16:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:15:15: Non-simple parameter declared here. +!!! error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:15:15: Non-simple parameter declared here. } function rest1(a = 1, ...args) { ~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:20:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:20:5: 'use strict' directive used here. ~~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:20:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:20:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:19:16: Non-simple parameter declared here. +!!! error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:19:16: Non-simple parameter declared here. !!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:19:23: and here. } function paramDefault(param = 1) { ~~~~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:24:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:24:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:23:23: Non-simple parameter declared here. +!!! error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:23:23: Non-simple parameter declared here. } function objectBindingPattern({foo}: any) { ~~~~~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:28:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:28:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:27:31: Non-simple parameter declared here. +!!! error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:27:31: Non-simple parameter declared here. } function arrayBindingPattern([foo]: any[]) { ~~~~~~~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:32:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:32:5: 'use strict' directive used here. 'use strict'; ~~~~~~~~~~~~~ -!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:31:30: Non-simple parameter declared here. +!!! error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:31:30: Non-simple parameter declared here. } function manyParameter(a = 10, b = 20) { ~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:36:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:36:5: 'use strict' directive used here. ~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:36:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:36:5: 'use strict' directive used here. "use strict"; ~~~~~~~~~~~~~ -!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:24: Non-simple parameter declared here. +!!! error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:24: Non-simple parameter declared here. !!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:35:32: and here. } function manyPrologue(a = 10, b = 20) { ~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:41:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:41:5: 'use strict' directive used here. ~~~~~~ -!!! error TS1345: This parameter is not allowed with 'use strict' directive. -!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:41:5: 'use strict' directive used here. +!!! error TS1346: This parameter is not allowed with 'use strict' directive. +!!! related TS1349 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:41:5: 'use strict' directive used here. "foo"; "use strict"; ~~~~~~~~~~~~~ -!!! error TS1346: 'use strict' directive cannot be used with non-simple parameter list. -!!! related TS1347 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:39:23: Non-simple parameter declared here. +!!! error TS1347: 'use strict' directive cannot be used with non-simple parameter list. +!!! related TS1348 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:39:23: Non-simple parameter declared here. !!! related TS6204 tests/cases/conformance/functions/functionWithUseStrictAndSimpleParameterList_es2016.ts:39:31: and here. } From 9f4ae5f5eaa48c4ee52caaaae4193a0ad519b5bc Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 29 Aug 2018 06:57:21 -0700 Subject: [PATCH 083/163] Fix typo --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 39e1ab5e526..0de2aa1c32a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10725,7 +10725,7 @@ namespace ts { const sourceRestType = getNonArrayRestType(source); const targetRestType = getNonArrayRestType(target); if (sourceRestType && targetRestType && sourceCount !== targetCount) { - // We're not able to relate misaliged complex rest parameters + // We're not able to relate misaligned complex rest parameters return Ternary.False; } From f67d7e01cfa82f16d868a548357041f5d50629cf Mon Sep 17 00:00:00 2001 From: Wenlu Wang Date: Wed, 29 Aug 2018 21:58:55 +0800 Subject: [PATCH 084/163] add test case and fix regression (#26726) --- src/compiler/checker.ts | 4 ++-- ...ameterInitializersForwardReferencing1.errors.txt | 4 ++++ .../parameterInitializersForwardReferencing1.js | 13 +++++++++++++ ...parameterInitializersForwardReferencing1.symbols | 9 +++++++++ .../parameterInitializersForwardReferencing1.types | 10 ++++++++++ ...erInitializersForwardReferencing1_es6.errors.txt | 4 ++++ .../parameterInitializersForwardReferencing1_es6.js | 10 ++++++++++ ...meterInitializersForwardReferencing1_es6.symbols | 9 +++++++++ ...rameterInitializersForwardReferencing1_es6.types | 10 ++++++++++ .../parameterInitializersForwardReferencing1.ts | 4 ++++ .../parameterInitializersForwardReferencing1_es6.ts | 4 ++++ 11 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cb3fc5614fb..f9b6af65f9d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1211,8 +1211,8 @@ namespace ts { : false; } if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.Variable) { - // parameter initializer will lookup as normal variable scope when targeting es2015+ - if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && result.valueDeclaration !== lastLocation) { + // expression inside parameter will lookup as normal variable scope when targeting es2015+ + if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && !isParameterPropertyDeclaration(lastLocation) && result.valueDeclaration !== lastLocation) { useResult = false; } else if (result.flags & SymbolFlags.FunctionScopedVariable) { diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt index 055a37838f1..94f4175f5e5 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt @@ -51,4 +51,8 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(29 !!! related TS2728 tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts:30:9: 'foo' is declared here. let foo: number = 2; } + + class Foo { + constructor(public x = 12, public y = x) {} + } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.js b/tests/baselines/reference/parameterInitializersForwardReferencing1.js index ad68f64ca2c..bb3a4c87e69 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.js +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.js @@ -30,6 +30,10 @@ function f6 (async = async) { function f7({[foo]: bar}: any[]) { let foo: number = 2; } + +class Foo { + constructor(public x = 12, public y = x) {} +} //// [parameterInitializersForwardReferencing1.js] @@ -68,3 +72,12 @@ function f7(_a) { var _b = foo, bar = _a[_b]; var foo = 2; } +var Foo = /** @class */ (function () { + function Foo(x, y) { + if (x === void 0) { x = 12; } + if (y === void 0) { y = x; } + this.x = x; + this.y = y; + } + return Foo; +}()); diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols index f3ea0f1e7e8..10f94a2bd64 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols @@ -75,3 +75,12 @@ function f7({[foo]: bar}: any[]) { >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1.ts, 29, 7)) } +class Foo { +>Foo : Symbol(Foo, Decl(parameterInitializersForwardReferencing1.ts, 30, 1)) + + constructor(public x = 12, public y = x) {} +>x : Symbol(Foo.x, Decl(parameterInitializersForwardReferencing1.ts, 33, 16)) +>y : Symbol(Foo.y, Decl(parameterInitializersForwardReferencing1.ts, 33, 30)) +>x : Symbol(x, Decl(parameterInitializersForwardReferencing1.ts, 33, 16)) +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.types b/tests/baselines/reference/parameterInitializersForwardReferencing1.types index 3a1d8d5864f..d6eee6a9c30 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.types @@ -82,3 +82,13 @@ function f7({[foo]: bar}: any[]) { >2 : 2 } +class Foo { +>Foo : Foo + + constructor(public x = 12, public y = x) {} +>x : number +>12 : 12 +>y : number +>x : number +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt index e7708894b65..d84519e406e 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -38,4 +38,8 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t function f7({[foo]: bar}: any[]) { let foo: number = 2; } + + class Foo { + constructor(public x = 12, public y = x) {} + } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js index 0c89b79b764..a5b00cfeb44 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js @@ -30,6 +30,10 @@ function f6 (async = async) { function f7({[foo]: bar}: any[]) { let foo: number = 2; } + +class Foo { + constructor(public x = 12, public y = x) {} +} //// [parameterInitializersForwardReferencing1_es6.js] @@ -57,3 +61,9 @@ function f6(async = async) { function f7({ [foo]: bar }) { let foo = 2; } +class Foo { + constructor(x = 12, y = x) { + this.x = x; + this.y = y; + } +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols index f9366034aa6..3d678a021ba 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols @@ -75,3 +75,12 @@ function f7({[foo]: bar}: any[]) { >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 29, 7)) } +class Foo { +>Foo : Symbol(Foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 30, 1)) + + constructor(public x = 12, public y = x) {} +>x : Symbol(Foo.x, Decl(parameterInitializersForwardReferencing1_es6.ts, 33, 16)) +>y : Symbol(Foo.y, Decl(parameterInitializersForwardReferencing1_es6.ts, 33, 30)) +>x : Symbol(x, Decl(parameterInitializersForwardReferencing1_es6.ts, 33, 16)) +} + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types index 16bd49f1cf7..ca8ae55557e 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types @@ -82,3 +82,13 @@ function f7({[foo]: bar}: any[]) { >2 : 2 } +class Foo { +>Foo : Foo + + constructor(public x = 12, public y = x) {} +>x : number +>12 : 12 +>y : number +>x : number +} + diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts index 640900253bd..cf667840f20 100644 --- a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts @@ -29,3 +29,7 @@ function f6 (async = async) { function f7({[foo]: bar}: any[]) { let foo: number = 2; } + +class Foo { + constructor(public x = 12, public y = x) {} +} diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts index 55afbbf7c2f..5643ea2cc0a 100644 --- a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts @@ -31,3 +31,7 @@ function f6 (async = async) { function f7({[foo]: bar}: any[]) { let foo: number = 2; } + +class Foo { + constructor(public x = 12, public y = x) {} +} From 983b0b4f95f3cf2532c82d78f55b8a1785dc74fd Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 29 Aug 2018 16:10:32 +0000 Subject: [PATCH 085/163] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 20276 ++++++++-------- 1 file changed, 10138 insertions(+), 10138 deletions(-) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index 58e6309512a..1a288195844 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,10139 +1,10139 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - 或 <语言>-<区域> 形式。例如“{0}”或“{1}”。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - 类型。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()"。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + 或 <语言>-<区域> 形式。例如“{0}”或“{1}”。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + 类型。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()"。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 0feeb487832189f75ba90392747dd7bdea6b7db7 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 29 Aug 2018 10:53:32 -0700 Subject: [PATCH 086/163] Make generator function name a completion list blocker (#26640) * Make generator function name a completion list blocker * Improvements for class/object members * Separate KeywordCompletionFilter.None and .All --- src/services/completions.ts | 41 +++++++++---------- .../completionsGeneratorFunctions.ts | 22 ++++++++++ 2 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 tests/cases/fourslash/completionsGeneratorFunctions.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index 7f82c9e7483..a82c4e02882 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -23,7 +23,8 @@ namespace ts.Completions { type SymbolOriginInfoMap = (SymbolOriginInfo | undefined)[]; const enum KeywordCompletionFilters { - None, + None, // No keywords + All, // Every possible keyword (TODO: This is never appropriate) ClassElementKeywords, // Keywords inside class body InterfaceElementKeywords, // Keywords inside interface body ConstructorParameterKeywords, // Keywords at constructor parameter @@ -143,21 +144,13 @@ namespace ts.Completions { getCompletionEntriesFromSymbols(symbols, entries, location, sourceFile, typeChecker, compilerOptions.target!, log, completionKind, preferences, propertyAccessToConvert, isJsxInitializer, recommendedCompletion, symbolToOriginInfoMap); } - // TODO add filter for keyword based on type/value/namespace and also location - - // Add all keywords if - // - this is not a member completion list (all the keywords) - // - other filters are enabled in required scenario so add those keywords - const isMemberCompletion = isMemberCompletionKind(completionKind); - if (keywordFilters !== KeywordCompletionFilters.None || !isMemberCompletion) { - addRange(entries, getKeywordCompletions(keywordFilters)); - } + addRange(entries, getKeywordCompletions(keywordFilters)); for (const literal of literals) { entries.push(createCompletionEntryForLiteral(literal)); } - return { isGlobalCompletion: isInSnippetScope, isMemberCompletion, isNewIdentifierLocation, entries }; + return { isGlobalCompletion: isInSnippetScope, isMemberCompletion: isMemberCompletionKind(completionKind), isNewIdentifierLocation, entries }; } function isUncheckedFile(sourceFile: SourceFile, compilerOptions: CompilerOptions): boolean { @@ -1014,6 +1007,7 @@ namespace ts.Completions { tryGetGlobalSymbols(); symbols = tagSymbols.concat(symbols); completionKind = CompletionKind.MemberLike; + keywordFilters = KeywordCompletionFilters.None; } else if (isStartingCloseTag) { const tagName = (contextToken.parent.parent).openingElement.tagName; @@ -1022,6 +1016,7 @@ namespace ts.Completions { symbols = [tagSymbol]; } completionKind = CompletionKind.MemberLike; + keywordFilters = KeywordCompletionFilters.None; } else { // For JavaScript or TypeScript, if we're not after a dot, then just try to get the @@ -1191,9 +1186,7 @@ namespace ts.Completions { } function getGlobalCompletions(): void { - if (tryGetFunctionLikeBodyCompletionContainer(contextToken)) { - keywordFilters = KeywordCompletionFilters.FunctionLikeBodyKeywords; - } + keywordFilters = tryGetFunctionLikeBodyCompletionContainer(contextToken) ? KeywordCompletionFilters.FunctionLikeBodyKeywords : KeywordCompletionFilters.All; // Get all entities in the current scope. completionKind = CompletionKind.Global; @@ -1648,7 +1641,8 @@ namespace ts.Completions { completionKind = CompletionKind.MemberLike; // Declaring new property/method/accessor isNewIdentifierLocation = true; - keywordFilters = isClassLike(decl) ? KeywordCompletionFilters.ClassElementKeywords : KeywordCompletionFilters.InterfaceElementKeywords; + keywordFilters = contextToken.kind === SyntaxKind.AsteriskToken ? KeywordCompletionFilters.None : + isClassLike(decl) ? KeywordCompletionFilters.ClassElementKeywords : KeywordCompletionFilters.InterfaceElementKeywords; // If you're in an interface you don't want to repeat things from super-interface. So just stop here. if (!isClassLike(decl)) return GlobalsSearch.Success; @@ -1686,14 +1680,16 @@ namespace ts.Completions { */ function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | ObjectBindingPattern | undefined { if (contextToken) { + const { parent } = contextToken; switch (contextToken.kind) { case SyntaxKind.OpenBraceToken: // const x = { | case SyntaxKind.CommaToken: // const x = { a: 0, | - const parent = contextToken.parent; if (isObjectLiteralExpression(parent) || isObjectBindingPattern(parent)) { return parent; } break; + case SyntaxKind.AsteriskToken: + return isMethodDeclaration(parent) ? tryCast(parent.parent, isObjectLiteralExpression) : undefined; } } @@ -1870,10 +1866,8 @@ namespace ts.Completions { case SyntaxKind.GetKeyword: case SyntaxKind.SetKeyword: - if (isFromObjectTypeDeclaration(contextToken)) { - return false; - } - // falls through + return !isFromObjectTypeDeclaration(contextToken); + case SyntaxKind.ClassKeyword: case SyntaxKind.EnumKeyword: case SyntaxKind.InterfaceKeyword: @@ -1885,6 +1879,9 @@ namespace ts.Completions { case SyntaxKind.YieldKeyword: case SyntaxKind.TypeKeyword: // type htm| return true; + + case SyntaxKind.AsteriskToken: + return isFunctionLike(contextToken.parent) && !isMethodDeclaration(contextToken.parent); } // If the previous token is keyword correspoding to class member completion keyword @@ -2124,6 +2121,8 @@ namespace ts.Completions { const kind = stringToToken(entry.name)!; switch (keywordFilter) { case KeywordCompletionFilters.None: + return false; + case KeywordCompletionFilters.All: return kind === SyntaxKind.AsyncKeyword || !isContextualKeyword(kind) && !isClassMemberCompletionKeyword(kind) || kind === SyntaxKind.DeclareKeyword || kind === SyntaxKind.ModuleKeyword || isTypeKeyword(kind) && kind !== SyntaxKind.UndefinedKeyword; case KeywordCompletionFilters.ClassElementKeywords: @@ -2236,7 +2235,7 @@ namespace ts.Completions { default: if (!isFromObjectTypeDeclaration(contextToken)) return undefined; const isValidKeyword = isClassLike(contextToken.parent.parent) ? isClassMemberCompletionKeyword : isInterfaceOrTypeLiteralCompletionKeyword; - return (isValidKeyword(contextToken.kind) || isIdentifier(contextToken) && isValidKeyword(stringToToken(contextToken.text)!)) // TODO: GH#18217 + return (isValidKeyword(contextToken.kind) || contextToken.kind === SyntaxKind.AsteriskToken || isIdentifier(contextToken) && isValidKeyword(stringToToken(contextToken.text)!)) // TODO: GH#18217 ? contextToken.parent.parent as ObjectTypeDeclaration : undefined; } } diff --git a/tests/cases/fourslash/completionsGeneratorFunctions.ts b/tests/cases/fourslash/completionsGeneratorFunctions.ts new file mode 100644 index 00000000000..1aea1eb6e4d --- /dev/null +++ b/tests/cases/fourslash/completionsGeneratorFunctions.ts @@ -0,0 +1,22 @@ +/// + +////function /*a*/ ; +////function* /*b*/ ; +////interface I { +//// abstract baseMethod(): Iterable; +////} +////class C implements I { +//// */*c*/ ; +//// public */*d*/ +////} +////const o: I = { +//// */*e*/ +////}; +////1 * /*f*/ + +verify.completions( + { marker: ["a", "b"], exact: undefined, isNewIdentifierLocation: true }, + { marker: ["c", "d"], exact: ["baseMethod"], isNewIdentifierLocation: true }, + { marker: "e", exact: ["baseMethod"] }, + { marker: "f", includes: ["Number"] }, +); From 02630273a279f5febe621261e44ab2fc13e85c8e Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 29 Aug 2018 11:37:31 -0700 Subject: [PATCH 087/163] codeFixInferFromUsage: Assume that using `x[0]` means that `x` is an array (#26739) * codeFixInferFromUsage: Assume that using `x[0]` means that `x` is an array * Remove unnecessary '||' with non-falsy LHS If only there were some kind of type-checker for JavaScript that could detect this sort of thing --- src/services/codefixes/inferFromUsage.ts | 20 ++++++++++--------- ...deFixInferFromUsageNumberIndexSignature.ts | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index f7b5edc5ca7..17b3469f0bf 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -534,17 +534,19 @@ namespace ts.codefix { else if (usageContext.properties && hasCallContext(usageContext.properties.get("push" as __String))) { return checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push" as __String)!.callContexts!, /*isRestParameter*/ false, checker)!); } - else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.numberIndexContext || usageContext.stringIndexContext) { + else if (usageContext.numberIndexContext) { + return checker.createArrayType(recur(usageContext.numberIndexContext)); + } + else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.stringIndexContext) { const members = createUnderscoreEscapedMap(); const callSignatures: Signature[] = []; const constructSignatures: Signature[] = []; let stringIndexInfo: IndexInfo | undefined; - let numberIndexInfo: IndexInfo | undefined; if (usageContext.properties) { usageContext.properties.forEach((context, name) => { const symbol = checker.createSymbol(SymbolFlags.Property, name); - symbol.type = getTypeFromUsageContext(context, checker) || checker.getAnyType(); + symbol.type = recur(context); members.set(name, symbol); }); } @@ -561,19 +563,19 @@ namespace ts.codefix { } } - if (usageContext.numberIndexContext) { - numberIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.numberIndexContext, checker) || checker.getAnyType(), /*isReadonly*/ false); - } - if (usageContext.stringIndexContext) { - stringIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.stringIndexContext, checker) || checker.getAnyType(), /*isReadonly*/ false); + stringIndexInfo = checker.createIndexInfo(recur(usageContext.stringIndexContext), /*isReadonly*/ false); } - return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); // TODO: GH#18217 + return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined); // TODO: GH#18217 } else { return undefined; } + + function recur(innerContext: UsageContext): Type { + return getTypeFromUsageContext(innerContext, checker) || checker.getAnyType(); + } } function getParameterTypeFromCallContexts(parameterIndex: number, callContexts: CallContext[], isRestParameter: boolean, checker: TypeChecker) { diff --git a/tests/cases/fourslash/codeFixInferFromUsageNumberIndexSignature.ts b/tests/cases/fourslash/codeFixInferFromUsageNumberIndexSignature.ts index cf031bd017f..2587cc79dcc 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageNumberIndexSignature.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageNumberIndexSignature.ts @@ -5,4 +5,4 @@ //// return a[0] + 1; ////} -verify.rangeAfterCodeFix("a: { [x: number]: number; }",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); +verify.rangeAfterCodeFix("a: number[]",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); From 068840d471590f4b15cc2b4ae7afe3a8233e4147 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 29 Aug 2018 11:58:38 -0700 Subject: [PATCH 088/163] Add shortname for watch option --- src/tsc/tsc.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index 1685dfc3449..3e0b9a631f8 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -208,6 +208,7 @@ namespace ts { }, { name: "watch", + shortName:"w", category: Diagnostics.Command_line_Options, description: Diagnostics.Watch_input_files, type: "boolean" From d6ff1a7241dab125fc1258d3f59416641ccf8ff8 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 29 Aug 2018 12:23:52 -0700 Subject: [PATCH 089/163] Move parsing of build options to commandLineParsing so it can be tested and it lines with other commandline parsing --- src/compiler/commandLineParser.ts | 124 ++++++++++++++--- .../unittests/commandLineParsing.ts | 116 ++++++++++++++++ src/tsc/tsc.ts | 125 +++--------------- 3 files changed, 241 insertions(+), 124 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index f1dd4093956..e4c4edcb4db 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -62,9 +62,7 @@ namespace ts { /* @internal */ export const libMap = createMapFromEntries(libEntries); - /* @internal */ - export const optionDeclarations: CommandLineOption[] = [ - // CommandLine only options + const commonOptionsWithBuild: CommandLineOption[] = [ { name: "help", shortName: "h", @@ -78,6 +76,27 @@ namespace ts { shortName: "?", type: "boolean" }, + { + name: "preserveWatchOutput", + type: "boolean", + showInSimplifiedHelpView: false, + category: Diagnostics.Command_line_Options, + description: Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen, + }, + { + name: "watch", + shortName: "w", + type: "boolean", + showInSimplifiedHelpView: true, + category: Diagnostics.Command_line_Options, + description: Diagnostics.Watch_input_files, + }, + ]; + + /* @internal */ + export const optionDeclarations: CommandLineOption[] = [ + // CommandLine only options + ...commonOptionsWithBuild, { name: "all", type: "boolean", @@ -125,21 +144,6 @@ namespace ts { category: Diagnostics.Command_line_Options, description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, - { - name: "preserveWatchOutput", - type: "boolean", - showInSimplifiedHelpView: false, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen, - }, - { - name: "watch", - shortName: "w", - type: "boolean", - showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Watch_input_files, - }, // Basic { @@ -754,6 +758,38 @@ namespace ts { } ]; + /* @internal */ + export const buildOpts: CommandLineOption[] = [ + ...commonOptionsWithBuild, + { + name: "verbose", + shortName: "v", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Enable_verbose_logging, + type: "boolean" + }, + { + name: "dry", + shortName: "d", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, + type: "boolean" + }, + { + name: "force", + shortName: "f", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, + type: "boolean" + }, + { + name: "clean", + category: Diagnostics.Command_line_Options, + description: Diagnostics.Delete_the_outputs_of_all_projects, + type: "boolean" + } + ]; + /* @internal */ export const typeAcquisitionDeclarations: CommandLineOption[] = [ { @@ -997,6 +1033,58 @@ namespace ts { return optionNameMap.get(optionName); } + /*@internal*/ + export interface ParsedBuildCommand { + buildOptions: BuildOptions; + projects: string[]; + errors: ReadonlyArray; + } + + /*@internal*/ + export function parseBuildCommand(args: string[]): ParsedBuildCommand { + let buildOptionNameMap: OptionNameMap | undefined; + const returnBuildOptionNameMap = () => (buildOptionNameMap || (buildOptionNameMap = createOptionNameMap(buildOpts))); + + const buildOptions: BuildOptions = {}; + const projects: string[] = []; + let errors: Diagnostic[] | undefined; + for (const arg of args) { + if (arg.charCodeAt(0) === CharacterCodes.minus) { + const opt = getOptionDeclarationFromName(returnBuildOptionNameMap, arg.slice(arg.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true); + if (opt) { + buildOptions[opt.name as keyof BuildOptions] = true; + } + else { + (errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Unknown_build_option_0, arg)); + } + } + else { + // Not a flag, parse as filename + projects.push(arg); + } + } + + if (projects.length === 0) { + // tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ." + projects.push("."); + } + + // Nonsensical combinations + if (buildOptions.clean && buildOptions.force) { + (errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force")); + } + if (buildOptions.clean && buildOptions.verbose) { + (errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose")); + } + if (buildOptions.clean && buildOptions.watch) { + (errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch")); + } + if (buildOptions.watch && buildOptions.dry) { + (errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry")); + } + + return { buildOptions, projects, errors: errors || emptyArray }; + } function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string { const diagnostic = createCompilerDiagnostic.apply(undefined, arguments); diff --git a/src/testRunner/unittests/commandLineParsing.ts b/src/testRunner/unittests/commandLineParsing.ts index 7145b9e5ec4..7ac9504f1f8 100644 --- a/src/testRunner/unittests/commandLineParsing.ts +++ b/src/testRunner/unittests/commandLineParsing.ts @@ -366,4 +366,120 @@ namespace ts { }); }); }); + + describe("parseBuildOptions", () => { + function assertParseResult(commandLine: string[], expectedParsedBuildCommand: ParsedBuildCommand) { + const parsed = parseBuildCommand(commandLine); + const parsedBuildOptions = JSON.stringify(parsed.buildOptions); + const expectedBuildOptions = JSON.stringify(expectedParsedBuildCommand.buildOptions); + assert.equal(parsedBuildOptions, expectedBuildOptions); + + const parsedErrors = parsed.errors; + const expectedErrors = expectedParsedBuildCommand.errors; + assert.isTrue(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`); + for (let i = 0; i < parsedErrors.length; i++) { + const parsedError = parsedErrors[i]; + const expectedError = expectedErrors[i]; + assert.equal(parsedError.code, expectedError.code); + assert.equal(parsedError.category, expectedError.category); + assert.equal(parsedError.messageText, expectedError.messageText); + } + + const parsedProjects = parsed.projects; + const expectedProjects = expectedParsedBuildCommand.projects; + assert.deepEqual(parsedProjects, expectedProjects, `Expected projects: [${JSON.stringify(expectedProjects)}]. Actual projects: [${JSON.stringify(parsedProjects)}].`); + } + it("parse build without any options ", () => { + // --lib es6 0.ts + assertParseResult([], + { + errors: [], + projects: ["."], + buildOptions: {} + }); + }); + + it("Parse multiple options", () => { + // --lib es5,es2015.symbol.wellknown 0.ts + assertParseResult(["--verbose", "--force", "tests"], + { + errors: [], + projects: ["tests"], + buildOptions: { verbose: true, force: true } + }); + }); + + it("Parse option with invalid option ", () => { + // --lib es5,invalidOption 0.ts + assertParseResult(["--verbose", "--invalidOption"], + { + errors: [{ + messageText: "Unknown build option '--invalidOption'.", + category: Diagnostics.Unknown_build_option_0.category, + code: Diagnostics.Unknown_build_option_0.code, + file: undefined, + start: undefined, + length: undefined, + }], + projects: ["."], + buildOptions: { verbose: true } + }); + }); + + it("Parse multiple flags with input projects at the end", () => { + // --lib es5,es2015.symbol.wellknown --target es5 0.ts + assertParseResult(["--force", "--verbose", "src", "tests"], + { + errors: [], + projects: ["src", "tests"], + buildOptions: { force: true, verbose: true } + }); + }); + + it("Parse multiple flags with input projects in the middle", () => { + // --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown + assertParseResult(["--force", "src", "tests", "--verbose"], + { + errors: [], + projects: ["src", "tests"], + buildOptions: { force: true, verbose: true } + }); + }); + + it("Parse multiple flags with input projects in the beginning", () => { + // --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown + assertParseResult(["src", "tests", "--force", "--verbose"], + { + errors: [], + projects: ["src", "tests"], + buildOptions: { force: true, verbose: true } + }); + }); + + describe("Combining options that make no sense together", () => { + function verifyInvalidCombination(flag1: keyof BuildOptions, flag2: keyof BuildOptions) { + it(`--${flag1} and --${flag2} together is invalid`, () => { + // --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown + assertParseResult([`--${flag1}`, `--${flag2}`], + { + errors: [{ + messageText: `Options '${flag1}' and '${flag2}' cannot be combined.`, + category: Diagnostics.Options_0_and_1_cannot_be_combined.category, + code: Diagnostics.Options_0_and_1_cannot_be_combined.code, + file: undefined, + start: undefined, + length: undefined, + }], + projects: ["."], + buildOptions: { [flag1]: true, [flag2]: true } + }); + }); + } + + verifyInvalidCombination("clean", "force"); + verifyInvalidCombination("clean", "verbose"); + verifyInvalidCombination("clean", "watch"); + verifyInvalidCombination("watch", "dry"); + }); + }); } diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index 3e0b9a631f8..d3966071265 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -165,80 +165,10 @@ namespace ts { } function performBuild(args: string[]): number | undefined { - const buildOpts: CommandLineOption[] = [ - { - name: "help", - shortName: "h", - type: "boolean", - showInSimplifiedHelpView: true, - category: Diagnostics.Command_line_Options, - description: Diagnostics.Print_this_message, - }, - { - name: "help", - shortName: "?", - type: "boolean" - }, - { - name: "verbose", - shortName: "v", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Enable_verbose_logging, - type: "boolean" - }, - { - name: "dry", - shortName: "d", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, - type: "boolean" - }, - { - name: "force", - shortName: "f", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, - type: "boolean" - }, - { - name: "clean", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Delete_the_outputs_of_all_projects, - type: "boolean" - }, - { - name: "watch", - shortName:"w", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Watch_input_files, - type: "boolean" - }, - { - name: "preserveWatchOutput", - type: "boolean", - category: Diagnostics.Command_line_Options, - description: Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen, - }, - ]; - let buildOptionNameMap: OptionNameMap | undefined; - const returnBuildOptionNameMap = () => (buildOptionNameMap || (buildOptionNameMap = createOptionNameMap(buildOpts))); - - const buildOptions: BuildOptions = {}; - const projects: string[] = []; - for (const arg of args) { - if (arg.charCodeAt(0) === CharacterCodes.minus) { - const opt = getOptionDeclarationFromName(returnBuildOptionNameMap, arg.slice(arg.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true); - if (opt) { - buildOptions[opt.name as keyof BuildOptions] = true; - } - else { - reportDiagnostic(createCompilerDiagnostic(Diagnostics.Unknown_build_option_0, arg)); - } - } - else { - // Not a flag, parse as filename - addProject(arg); - } + const { buildOptions, projects: buildProjects, errors } = parseBuildCommand(args); + if (errors.length > 0) { + errors.forEach(reportDiagnostic); + return ExitStatus.DiagnosticsPresent_OutputsSkipped; } if (buildOptions.help) { @@ -249,6 +179,21 @@ namespace ts { // Update to pretty if host supports it updateReportDiagnostic(); + const projects = mapDefined(buildProjects, project => { + const fileName = resolvePath(sys.getCurrentDirectory(), project); + const refPath = resolveProjectReferencePath(sys, { path: fileName }); + if (!sys.fileExists(refPath)) { + reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, fileName)); + return undefined; + } + return refPath; + }); + + if (projects.length === 0) { + printVersion(); + printHelp(buildOpts, "--build "); + return ExitStatus.Success; + } if (!sys.getModifiedTime || !sys.setModifiedTime || (buildOptions.clean && !sys.deleteFile)) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--build")); @@ -258,29 +203,6 @@ namespace ts { reportWatchModeWithoutSysSupport(); } - // Nonsensical combinations - if (buildOptions.clean && buildOptions.force) { - reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force")); - return ExitStatus.DiagnosticsPresent_OutputsSkipped; - } - if (buildOptions.clean && buildOptions.verbose) { - reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose")); - return ExitStatus.DiagnosticsPresent_OutputsSkipped; - } - if (buildOptions.clean && buildOptions.watch) { - reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch")); - return ExitStatus.DiagnosticsPresent_OutputsSkipped; - } - if (buildOptions.watch && buildOptions.dry) { - reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry")); - return ExitStatus.DiagnosticsPresent_OutputsSkipped; - } - - if (projects.length === 0) { - // tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ." - addProject("."); - } - // TODO: change this to host if watch => watchHost otherwiue without wathc const builder = createSolutionBuilder(createSolutionBuilderWithWatchHost(sys, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty()), createWatchStatusReporter()), projects, buildOptions); if (buildOptions.clean) { @@ -294,15 +216,6 @@ namespace ts { } return builder.buildAllProjects(); - - function addProject(projectSpecification: string) { - const fileName = resolvePath(sys.getCurrentDirectory(), projectSpecification); - const refPath = resolveProjectReferencePath(sys, { path: fileName }); - if (!sys.fileExists(refPath)) { - return reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, fileName)); - } - projects.push(refPath); - } } function performCompilation(rootNames: string[], projectReferences: ReadonlyArray | undefined, options: CompilerOptions, configFileParsingDiagnostics?: ReadonlyArray) { From 111300ccd55f2ca6d5ea48ff8294c94c4a889ffd Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 29 Aug 2018 12:57:05 -0700 Subject: [PATCH 090/163] Fix overlapping test runs in 'gulp watch' --- Gulpfile.js | 92 ++++++++++++++++++++++------------- package.json | 1 + scripts/build/cancellation.js | 71 --------------------------- scripts/build/exec.js | 29 ++++++----- scripts/build/project.js | 79 +++++++++++++++++++++--------- scripts/build/tests.js | 6 ++- 6 files changed, 135 insertions(+), 143 deletions(-) delete mode 100644 scripts/build/cancellation.js diff --git a/Gulpfile.js b/Gulpfile.js index b31462755ad..704fbba4447 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -24,10 +24,9 @@ const baselineAccept = require("./scripts/build/baselineAccept"); const cmdLineOptions = require("./scripts/build/options"); const exec = require("./scripts/build/exec"); const browserify = require("./scripts/build/browserify"); -const debounce = require("./scripts/build/debounce"); const prepend = require("./scripts/build/prepend"); const { removeSourceMaps } = require("./scripts/build/sourcemaps"); -const { CancelSource, CancelError } = require("./scripts/build/cancellation"); +const { CancellationTokenSource, CancelError, delay, Semaphore } = require("prex"); const { libraryTargets, generateLibs } = require("./scripts/build/lib"); const { runConsoleTests, cleanTestDirs, writeTestConfigFile, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } = require("./scripts/build/tests"); @@ -534,57 +533,80 @@ gulp.task( ["watch-diagnostics", "watch-lib"].concat(useCompilerDeps), () => project.watch(tsserverProject, { typescript: useCompiler })); -gulp.task( - "watch-local", - /*help*/ false, - ["watch-lib", "watch-tsc", "watch-services", "watch-server"]); - gulp.task( "watch-runner", /*help*/ false, useCompilerDeps, () => project.watch(testRunnerProject, { typescript: useCompiler })); -const watchPatterns = [ - runJs, - typescriptDts, - tsserverlibraryDts -]; +gulp.task( + "watch-local", + "Watches for changes to projects in src/ (but does not execute tests).", + ["watch-lib", "watch-tsc", "watch-services", "watch-server", "watch-runner", "watch-lssl"]); gulp.task( "watch", - "Watches for changes to the build inputs for built/local/run.js, then executes runtests-parallel.", + "Watches for changes to the build inputs for built/local/run.js, then runs tests.", ["build-rules", "watch-runner", "watch-services", "watch-lssl"], () => { - /** @type {CancelSource | undefined} */ - let runTestsSource; + const sem = new Semaphore(1); - const fn = debounce(() => { - runTests().catch(error => { - if (error instanceof CancelError) { - log.warn("Operation was canceled"); - } - else { - log.error(error); - } - }); - }, /*timeout*/ 100, { max: 500 }); - - gulp.watch(watchPatterns, () => project.wait().then(fn)); + gulp.watch([runJs, typescriptDts, tsserverlibraryDts], () => { + runTests(); + }); // NOTE: gulp.watch is far too slow when watching tests/cases/**/* as it first enumerates *every* file const testFilePattern = /(\.ts|[\\/]tsconfig\.json)$/; fs.watch("tests/cases", { recursive: true }, (_, file) => { - if (testFilePattern.test(file)) project.wait().then(fn); + if (testFilePattern.test(file)) runTests(); }); - function runTests() { - if (runTestsSource) runTestsSource.cancel(); - runTestsSource = new CancelSource(); - return cmdLineOptions.tests || cmdLineOptions.failed - ? runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ true, runTestsSource.token) - : runConsoleTests(runJs, "min", /*runInParallel*/ true, /*watchMode*/ true, runTestsSource.token); - } + async function runTests() { + try { + // Ensure only one instance of the test runner is running at any given time. + if (sem.count > 0) { + await sem.wait(); + try { + // Wait for any concurrent recompilations to complete... + try { + await delay(100); + while (project.hasRemainingWork()) { + await project.waitForWorkToComplete(); + await delay(500); + } + } + catch (e) { + if (e instanceof CancelError) return; + throw e; + } + + // cancel any pending or active test run if a new recompilation is triggered + const source = new CancellationTokenSource(); + project.waitForWorkToStart().then(() => { + source.cancel(); + }); + + if (cmdLineOptions.tests || cmdLineOptions.failed) { + await runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ true, source.token); + } + else { + await runConsoleTests(runJs, "min", /*runInParallel*/ true, /*watchMode*/ true, source.token); + } + } + finally { + sem.release(); + } + } + } + catch (e) { + if (e instanceof CancelError) { + log.warn("Operation was canceled"); + } + else { + log.error(e); + } + } + }; }); gulp.task("clean-built", /*help*/ false, [`clean:${diagnosticInformationMapTs}`], () => del(["built"])); diff --git a/package.json b/package.json index 510d3aab53b..55acc40268d 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "mocha": "latest", "mocha-fivemat-progress-reporter": "latest", "plugin-error": "latest", + "prex": "^0.4.3", "q": "latest", "remove-internal": "^2.9.2", "run-sequence": "latest", diff --git a/scripts/build/cancellation.js b/scripts/build/cancellation.js deleted file mode 100644 index 793aaf19d86..00000000000 --- a/scripts/build/cancellation.js +++ /dev/null @@ -1,71 +0,0 @@ -// @ts-check -const symSource = Symbol("CancelToken.source"); -const symToken = Symbol("CancelSource.token"); -const symCancellationRequested = Symbol("CancelSource.cancellationRequested"); -const symCancellationCallbacks = Symbol("CancelSource.cancellationCallbacks"); - -class CancelSource { - constructor() { - this[symCancellationRequested] = false; - this[symCancellationCallbacks] = []; - } - - /** @type {CancelToken} */ - get token() { - return this[symToken] || (this[symToken] = new CancelToken(this)); - } - - cancel() { - if (!this[symCancellationRequested]) { - this[symCancellationRequested] = true; - for (const callback of this[symCancellationCallbacks]) { - callback(); - } - } - } -} -exports.CancelSource = CancelSource; - -class CancelToken { - /** - * @param {CancelSource} source - */ - constructor(source) { - if (source[symToken]) return source[symToken]; - this[symSource] = source; - } - - /** @type {boolean} */ - get cancellationRequested() { - return this[symSource][symCancellationRequested]; - } - - /** - * @param {() => void} callback - */ - subscribe(callback) { - const source = this[symSource]; - if (source[symCancellationRequested]) { - callback(); - return; - } - - source[symCancellationCallbacks].push(callback); - - return { - unsubscribe() { - const index = source[symCancellationCallbacks].indexOf(callback); - if (index !== -1) source[symCancellationCallbacks].splice(index, 1); - } - }; - } -} -exports.CancelToken = CancelToken; - -class CancelError extends Error { - constructor(message = "Operation was canceled") { - super(message); - this.name = "CancelError"; - } -} -exports.CancelError = CancelError; \ No newline at end of file diff --git a/scripts/build/exec.js b/scripts/build/exec.js index 04336321dd4..8e0a058fed0 100644 --- a/scripts/build/exec.js +++ b/scripts/build/exec.js @@ -3,7 +3,7 @@ const cp = require("child_process"); const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util) const isWin = /^win/.test(process.platform); const chalk = require("./chalk"); -const { CancelToken, CancelError } = require("./cancellation"); +const { CancellationToken, CancelError } = require("prex"); module.exports = exec; @@ -15,31 +15,36 @@ module.exports = exec; * * @typedef ExecOptions * @property {boolean} [ignoreExitCode] - * @property {CancelToken} [cancelToken] + * @property {import("prex").CancellationToken} [cancelToken] */ function exec(cmd, args, options = {}) { return /**@type {Promise<{exitCode: number}>}*/(new Promise((resolve, reject) => { - log(`> ${chalk.green(cmd)} ${args.join(" ")}`); + const { ignoreExitCode, cancelToken = CancellationToken.none } = options; + cancelToken.throwIfCancellationRequested(); + // TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition const subshellFlag = isWin ? "/c" : "-c"; const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`]; - const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true }); - const subscription = options.cancelToken && options.cancelToken.subscribe(() => { - ex.kill("SIGINT"); - ex.kill("SIGTERM"); + + log(`> ${chalk.green(cmd)} ${args.join(" ")}`); + const proc = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true }); + const registration = cancelToken.register(() => { + log(`${chalk.red("killing")} '${chalk.green(cmd)} ${args.join(" ")}'...`); + proc.kill("SIGINT"); + proc.kill("SIGTERM"); reject(new CancelError()); }); - ex.on("exit", exitCode => { - subscription && subscription.unsubscribe(); - if (exitCode === 0 || options.ignoreExitCode) { + proc.on("exit", exitCode => { + registration.unregister(); + if (exitCode === 0 || ignoreExitCode) { resolve({ exitCode }); } else { reject(new Error(`Process exited with code: ${exitCode}`)); } }); - ex.on("error", error => { - subscription && subscription.unsubscribe(); + proc.on("error", error => { + registration.unregister(); reject(error); }); })); diff --git a/scripts/build/project.js b/scripts/build/project.js index 933f7c44c65..0375faa2820 100644 --- a/scripts/build/project.js +++ b/scripts/build/project.js @@ -3,6 +3,8 @@ const path = require("path"); const fs = require("fs"); const gulp = require("./gulp"); const gulpif = require("gulp-if"); +const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util) +const chalk = require("./chalk"); const sourcemaps = require("gulp-sourcemaps"); const merge2 = require("merge2"); const tsc = require("gulp-typescript"); @@ -12,7 +14,12 @@ const ts = require("../../lib/typescript"); const del = require("del"); const needsUpdate = require("./needsUpdate"); const mkdirp = require("./mkdirp"); +const prettyTime = require("pretty-hrtime"); const { reportDiagnostics } = require("./diagnostics"); +const { CountdownEvent, ManualResetEvent } = require("prex"); + +const workStartedEvent = new ManualResetEvent(); +const countdown = new CountdownEvent(0); class CompilationGulp extends gulp.Gulp { /** @@ -20,15 +27,39 @@ class CompilationGulp extends gulp.Gulp { */ fork(verbose) { const child = new ForkedGulp(this.tasks); - if (verbose) { - child.on("task_start", e => gulp.emit("task_start", e)); - child.on("task_stop", e => gulp.emit("task_stop", e)); - child.on("task_err", e => gulp.emit("task_err", e)); - child.on("task_not_found", e => gulp.emit("task_not_found", e)); - child.on("task_recursion", e => gulp.emit("task_recursion", e)); - } + child.on("task_start", e => { + if (countdown.remainingCount === 0) { + countdown.reset(1); + workStartedEvent.set(); + workStartedEvent.reset(); + } + else { + countdown.add(); + } + if (verbose) { + log('Starting', `'${chalk.cyan(e.task)}' ${chalk.gray(`(${countdown.remainingCount} remaining)`)}...`); + } + }); + child.on("task_stop", e => { + countdown.signal(); + if (verbose) { + log('Finished', `'${chalk.cyan(e.task)}' after ${chalk.magenta(prettyTime(/** @type {*}*/(e).hrDuration))} ${chalk.gray(`(${countdown.remainingCount} remaining)`)}`); + } + }); + child.on("task_err", e => { + countdown.signal(); + if (verbose) { + log(`'${chalk.cyan(e.task)}' ${chalk.red("errored after")} ${chalk.magenta(prettyTime(/** @type {*}*/(e).hrDuration))} ${chalk.gray(`(${countdown.remainingCount} remaining)`)}`); + log(e.err ? e.err.stack : e.message); + } + }); return child; } + + // @ts-ignore + start() { + throw new Error("Not supported, use fork."); + } } class ForkedGulp extends gulp.Gulp { @@ -211,24 +242,26 @@ exports.flatten = flatten; /** * Returns a Promise that resolves when all pending build tasks have completed + * @param {import("prex").CancellationToken} [token] */ -function wait() { - return new Promise(resolve => { - if (compilationGulp.allDone()) { - resolve(); - } - else { - const onDone = () => { - compilationGulp.removeListener("onDone", onDone); - compilationGulp.removeListener("err", onDone); - resolve(); - }; - compilationGulp.on("stop", onDone); - compilationGulp.on("err", onDone); - } - }); +function waitForWorkToComplete(token) { + return countdown.wait(token); } -exports.wait = wait; +exports.waitForWorkToComplete = waitForWorkToComplete; + +/** + * Returns a Promise that resolves when all pending build tasks have completed + * @param {import("prex").CancellationToken} [token] + */ +function waitForWorkToStart(token) { + return workStartedEvent.wait(token); +} +exports.waitForWorkToStart = waitForWorkToStart; + +function getRemainingWork() { + return countdown.remainingCount > 0; +} +exports.hasRemainingWork = getRemainingWork; /** * Resolve a TypeScript specifier into a fully-qualified module specifier and any requisite dependencies. diff --git a/scripts/build/tests.js b/scripts/build/tests.js index d631f1e35ac..5bc619e3823 100644 --- a/scripts/build/tests.js +++ b/scripts/build/tests.js @@ -8,6 +8,7 @@ const mkdirP = require("./mkdirp"); const cmdLineOptions = require("./options"); const exec = require("./exec"); const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util) +const { CancellationToken } = require("prex"); const mochaJs = require.resolve("mocha/bin/_mocha"); exports.localBaseline = "tests/baselines/local/"; @@ -21,9 +22,9 @@ exports.localTest262Baseline = "internal/baselines/test262/local"; * @param {string} defaultReporter * @param {boolean} runInParallel * @param {boolean} watchMode - * @param {InstanceType} [cancelToken] + * @param {import("prex").CancellationToken} [cancelToken] */ -async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, cancelToken) { +async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, cancelToken = CancellationToken.none) { let testTimeout = cmdLineOptions.timeout; let tests = cmdLineOptions.tests; const lintFlag = cmdLineOptions.lint; @@ -37,6 +38,7 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, const keepFailed = cmdLineOptions.keepFailed; if (!cmdLineOptions.dirty) { await cleanTestDirs(); + cancelToken.throwIfCancellationRequested(); } if (fs.existsSync(testConfigFile)) { From 90abaa1c45a3e926170b298c95cc3fccf1ea807b Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 29 Aug 2018 13:06:35 -0700 Subject: [PATCH 091/163] Reset the build queue correctly Fixes issue reported in #26545#issuecomment-416961260 --- src/compiler/tsbuild.ts | 1 + src/testRunner/unittests/tsbuildWatchMode.ts | 50 ++++++++++++-------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index e52c743bb36..95beb65e28e 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -429,6 +429,7 @@ namespace ts { projectPendingBuild.removeKey(proj); if (!projectPendingBuild.getSize()) { invalidatedProjectQueue.length = 0; + nextIndex = 0; } return proj; } diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts index d1405fa9e2c..b7884350061 100644 --- a/src/testRunner/unittests/tsbuildWatchMode.ts +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -98,34 +98,42 @@ namespace ts.tscWatch { for (const stamp of outputFileStamps) { assert.isDefined(stamp[1], `${stamp[0]} expected to be present`); } - return { host, outputFileStamps }; + return host; } it("creates solution in watch mode", () => { createSolutionInWatchMode(); }); it("change builds changes and reports found errors message", () => { - const { host, outputFileStamps } = createSolutionInWatchMode(); - host.writeFile(core[1].path, `${core[1].content} + const host = createSolutionInWatchMode(); + verifyChange(`${core[1].content} export class someClass { }`); - host.checkTimeoutQueueLengthAndRun(1); // Builds core - const changedCore = getOutputFileStamps(host); - verifyChangedFiles(changedCore, outputFileStamps, [ - ...getOutputFileNames(SubProject.core, "anotherModule"), // This should not be written really - ...getOutputFileNames(SubProject.core, "index") - ]); - host.checkTimeoutQueueLengthAndRun(1); // Builds tests - const changedTests = getOutputFileStamps(host); - verifyChangedFiles(changedTests, changedCore, [ - ...getOutputFileNames(SubProject.tests, "index") // Again these need not be written - ]); - host.checkTimeoutQueueLengthAndRun(1); // Builds logic - const changedLogic = getOutputFileStamps(host); - verifyChangedFiles(changedLogic, changedTests, [ - ...getOutputFileNames(SubProject.logic, "index") // Again these need not be written - ]); - host.checkTimeoutQueueLength(0); - checkOutputErrorsIncremental(host, emptyArray); + + // Another change requeues and builds it + verifyChange(core[1].content); + + function verifyChange(coreContent: string) { + const outputFileStamps = getOutputFileStamps(host); + host.writeFile(core[1].path, coreContent); + host.checkTimeoutQueueLengthAndRun(1); // Builds core + const changedCore = getOutputFileStamps(host); + verifyChangedFiles(changedCore, outputFileStamps, [ + ...getOutputFileNames(SubProject.core, "anotherModule"), // This should not be written really + ...getOutputFileNames(SubProject.core, "index") + ]); + host.checkTimeoutQueueLengthAndRun(1); // Builds tests + const changedTests = getOutputFileStamps(host); + verifyChangedFiles(changedTests, changedCore, [ + ...getOutputFileNames(SubProject.tests, "index") // Again these need not be written + ]); + host.checkTimeoutQueueLengthAndRun(1); // Builds logic + const changedLogic = getOutputFileStamps(host); + verifyChangedFiles(changedLogic, changedTests, [ + ...getOutputFileNames(SubProject.logic, "index") // Again these need not be written + ]); + host.checkTimeoutQueueLength(0); + checkOutputErrorsIncremental(host, emptyArray); + } }); // TODO: write tests reporting errors but that will have more involved work since file From 529ed2d59dac770fc6dc53551e9231fddc09f690 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 29 Aug 2018 13:42:20 -0700 Subject: [PATCH 092/163] Stop inferring unions for disjoint callback parameter inferences --- src/compiler/checker.ts | 13 ++++++------- src/compiler/types.ts | 5 ++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db02365fd17..e2ebf31a304 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13658,7 +13658,7 @@ namespace ts { return inference.priority! & InferencePriority.PriorityImpliesCombination ? getIntersectionType(inference.contraCandidates!) : getCommonSubtype(inference.contraCandidates!); } - function getCovariantInference(inference: InferenceInfo, context: InferenceContext, signature: Signature) { + function getCovariantInference(inference: InferenceInfo, signature: Signature) { // Extract all object literal types and replace them with a single widened and normalized type. const candidates = widenObjectLiteralCandidates(inference.candidates!); // We widen inferred literal types if @@ -13671,10 +13671,9 @@ namespace ts { const baseCandidates = primitiveConstraint ? sameMap(candidates, getRegularTypeOfLiteralType) : widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates; - // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if - // union types were requested or if all inferences were made from the return type position, infer a - // union type. Otherwise, infer a common supertype. - const unwidenedType = context.flags & InferenceFlags.InferUnionTypes || inference.priority! & InferencePriority.PriorityImpliesCombination ? + // If all inferences were made from a position that implies a combined result, infer a union type. + // Otherwise, infer a common supertype. + const unwidenedType = inference.priority! & InferencePriority.PriorityImpliesCombination ? getUnionType(baseCandidates, UnionReduction.Subtype) : getCommonSupertype(baseCandidates); return getWidenedType(unwidenedType); @@ -13694,7 +13693,7 @@ namespace ts { inference.contraCandidates = undefined; } if (inference.candidates) { - inferredType = getCovariantInference(inference, context, signature); + inferredType = getCovariantInference(inference, signature); } else if (context.flags & InferenceFlags.NoDefault) { // We use silentNeverType as the wildcard that signals no inferences. @@ -18633,7 +18632,7 @@ namespace ts { // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec) function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper, compareTypes?: TypeComparer): Signature { - const context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.InferUnionTypes, compareTypes); + const context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.None, compareTypes); const sourceSignature = contextualMapper ? instantiateSignature(contextualSignature, contextualMapper) : contextualSignature; forEachMatchingParameterType(sourceSignature, signature, (source, target) => { // Type parameters from outer context referenced by source type are fixed by instantiation of the source type diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 54e19154376..64a00f78ced 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4175,9 +4175,8 @@ namespace ts { /* @internal */ export const enum InferenceFlags { None = 0, // No special inference behaviors - InferUnionTypes = 1 << 0, // Infer union types for disjoint candidates (otherwise unknownType) - NoDefault = 1 << 1, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType) - AnyDefault = 1 << 2, // Infer anyType for no inferences (otherwise emptyObjectType) + NoDefault = 1 << 0, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType) + AnyDefault = 1 << 1, // Infer anyType for no inferences (otherwise emptyObjectType) } /** From c48c3632bd4aa45db807698a1886d60d6d5295d3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 29 Aug 2018 14:02:15 -0700 Subject: [PATCH 093/163] Update tests --- .../contextualSignatureInstatiationContravariance.ts | 2 +- .../assignmentCompatWithGenericCallSignatures2.ts | 2 +- .../callSignatureAssignabilityInInheritance2.ts | 2 +- .../callSignatureAssignabilityInInheritance5.ts | 2 +- .../constructSignatureAssignabilityInInheritance2.ts | 2 +- .../constructSignatureAssignabilityInInheritance5.ts | 2 +- .../subtypingWithConstructSignatures5.ts | 2 +- .../typeInference/contextualSignatureInstantiation.ts | 6 +++--- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/cases/compiler/contextualSignatureInstatiationContravariance.ts b/tests/cases/compiler/contextualSignatureInstatiationContravariance.ts index 83b5cbafb6a..2bd0673abd5 100644 --- a/tests/cases/compiler/contextualSignatureInstatiationContravariance.ts +++ b/tests/cases/compiler/contextualSignatureInstatiationContravariance.ts @@ -5,7 +5,7 @@ interface Elephant extends Animal { y2 } var f2: (x: T, y: T) => void; var g2: (g: Giraffe, e: Elephant) => void; -g2 = f2; // valid because both Giraffe and Elephant satisfy the constraint. T is Animal +g2 = f2; // error because Giraffe and Elephant are disjoint types var h2: (g1: Giraffe, g2: Giraffe) => void; h2 = f2; // valid because Giraffe satisfies the constraint. It is safe in the traditional contravariant fashion. \ No newline at end of file diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts index c4904413617..e2cc7a69ee5 100644 --- a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts @@ -11,6 +11,6 @@ interface B { var a: A; var b: B; -// Both ok +// Both errors a = b; b = a; diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance2.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance2.ts index eaabadb7741..9e6cd52ac2b 100644 --- a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance2.ts +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance2.ts @@ -61,7 +61,7 @@ interface I extends A { a11: (x: T, y: T) => T; // ok a12: >(x: Array, y: T) => Array; // ok, less specific parameter type a13: >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: (x: { a: T; b: U }) => T; // ok a15: (x: T) => T[]; // ok a16: (x: T) => number[]; // ok a17: (x: (a: T) => T) => T[]; // ok diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance5.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance5.ts index b5aa243f6c1..bf60d6518cf 100644 --- a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance5.ts +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance5.ts @@ -44,5 +44,5 @@ interface I extends B { a11: (x: T, y: T) => T; // ok a12: >(x: Array, y: T) => Array; // ok, less specific parameter type a13: >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: (x: { a: T; b: U }) => T; // ok } \ No newline at end of file diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance2.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance2.ts index 2a598bb01ed..65e4f4c962e 100644 --- a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance2.ts +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance2.ts @@ -61,7 +61,7 @@ interface I extends A { a11: new (x: T, y: T) => T; // ok a12: new >(x: Array, y: T) => Array; // ok, less specific parameter type a13: new >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok a15: new (x: T) => T[]; // ok a16: new (x: T) => number[]; // ok a17: new (x: new (a: T) => T) => T[]; // ok diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance5.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance5.ts index 43813faf8ae..f33820218ea 100644 --- a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance5.ts +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance5.ts @@ -44,5 +44,5 @@ interface I extends B { a11: new (x: T, y: T) => T; // ok a12: new >(x: Array, y: T) => Array; // ok, less specific parameter type a13: new >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok } \ No newline at end of file diff --git a/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures5.ts b/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures5.ts index 43813faf8ae..f33820218ea 100644 --- a/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures5.ts +++ b/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures5.ts @@ -44,5 +44,5 @@ interface I extends B { a11: new (x: T, y: T) => T; // ok a12: new >(x: Array, y: T) => Array; // ok, less specific parameter type a13: new >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok } \ No newline at end of file diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts b/tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts index 393d0e10d37..30c6579dabb 100644 --- a/tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts +++ b/tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts @@ -16,9 +16,9 @@ var a = bar(1, 1, g); // Should be number var a = baz(1, 1, g); // Should be number var b: number | string; -var b = foo(g); // Should be number | string -var b = bar(1, "one", g); // Should be number | string -var b = bar("one", 1, g); // Should be number | string +var b = foo(g); // Error, number and string are disjoint types +var b = bar(1, "one", g); // Error, number and string are disjoint types +var b = bar("one", 1, g); // Error, number and string are disjoint types var b = baz(b, b, g); // Should be number | string var d: number[] | string[]; From b17aaf0edf0d75e40bae769ab0e874c7974aaf8c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 29 Aug 2018 14:15:09 -0700 Subject: [PATCH 094/163] Accept new baselines --- ...gnmentCompatWithCallSignatures3.errors.txt | 13 ++++- ...gnmentCompatWithCallSignatures4.errors.txt | 12 +++-- ...gnmentCompatWithCallSignatures5.errors.txt | 27 +++++++--- ...gnmentCompatWithCallSignatures6.errors.txt | 13 ++++- ...tCompatWithConstructSignatures3.errors.txt | 13 ++++- ...tCompatWithConstructSignatures4.errors.txt | 12 +++-- ...tCompatWithConstructSignatures5.errors.txt | 27 +++++++--- ...tCompatWithConstructSignatures6.errors.txt | 13 ++++- ...ompatWithGenericCallSignatures2.errors.txt | 11 +++- ...ignmentCompatWithGenericCallSignatures2.js | 4 +- ...ntCompatWithGenericCallSignatures2.symbols | 2 +- ...mentCompatWithGenericCallSignatures2.types | 2 +- ...allSignatureAssignabilityInInheritance2.js | 2 +- ...gnatureAssignabilityInInheritance2.symbols | 13 ++--- ...SignatureAssignabilityInInheritance2.types | 8 +-- ...tureAssignabilityInInheritance3.errors.txt | 12 +++-- ...allSignatureAssignabilityInInheritance5.js | 2 +- ...gnatureAssignabilityInInheritance5.symbols | 11 ++-- ...SignatureAssignabilityInInheritance5.types | 8 +-- ...uctSignatureAssignabilityInInheritance2.js | 2 +- ...gnatureAssignabilityInInheritance2.symbols | 13 ++--- ...SignatureAssignabilityInInheritance2.types | 8 +-- ...tureAssignabilityInInheritance3.errors.txt | 12 +++-- ...uctSignatureAssignabilityInInheritance5.js | 2 +- ...gnatureAssignabilityInInheritance5.symbols | 11 ++-- ...SignatureAssignabilityInInheritance5.types | 8 +-- ...ontextualSignatureInstantiation.errors.txt | 53 +++++++++++++++++++ .../contextualSignatureInstantiation.js | 12 ++--- .../contextualSignatureInstantiation.symbols | 6 +-- .../contextualSignatureInstantiation.types | 12 ++--- ...atureInstatiationContravariance.errors.txt | 23 ++++++++ ...tualSignatureInstatiationContravariance.js | 4 +- ...ignatureInstatiationContravariance.symbols | 2 +- ...lSignatureInstatiationContravariance.types | 2 +- .../subtypingWithCallSignatures2.types | 12 ++--- .../subtypingWithCallSignatures4.types | 8 +-- .../subtypingWithConstructSignatures2.types | 12 ++--- .../subtypingWithConstructSignatures4.types | 8 +-- .../subtypingWithConstructSignatures5.js | 2 +- .../subtypingWithConstructSignatures5.symbols | 11 ++-- .../subtypingWithConstructSignatures5.types | 8 +-- 41 files changed, 305 insertions(+), 131 deletions(-) create mode 100644 tests/baselines/reference/contextualSignatureInstantiation.errors.txt create mode 100644 tests/baselines/reference/contextualSignatureInstatiationContravariance.errors.txt diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt index 28fe7c738a6..441810033d2 100644 --- a/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt @@ -45,6 +45,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Property 'baz' is missing in type 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(83,1): error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '(x: Base[], y: T) => T'. Type 'Derived[]' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(85,1): error TS2322: Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => Object'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. + Types of property 'b' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '(x: { a: T; b: T; }) => T'. Types of parameters 'x' and 'x' are incompatible. Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. @@ -52,7 +57,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Type 'T' is not assignable to type 'string'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (14 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (15 errors) ==== // these are all permitted with the current rules, since we do not do contextual signature instantiation class Base { foo: string; } @@ -198,6 +203,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'Derived[]' is not assignable to type 'T'. var b14: (x: { a: T; b: T }) => T; a14 = b14; // ok + ~~~ +!!! error TS2322: Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => Object'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. b14 = a14; // ok ~~~ !!! error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '(x: { a: T; b: T; }) => T'. diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt index 39d3a2a3593..0a2ae478989 100644 --- a/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt @@ -22,8 +22,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(66,9): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '(x: Base[], y: Base[]) => T'. Type 'Derived[]' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(69,9): error TS2322: Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. + Types of property 'b' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(70,9): error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '(x: { a: T; b: T; }) => T'. Types of parameters 'x' and 'x' are incompatible. Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. @@ -156,8 +158,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a15 = b15; ~~~ !!! error TS2322: Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. b15 = a15; ~~~ !!! error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '(x: { a: T; b: T; }) => T'. diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt index ba8f5304aa2..57944ae9863 100644 --- a/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt @@ -1,9 +1,15 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(40,1): error TS2322: Type '(x: T) => void' is not assignable to type '(x: T) => T'. Type 'void' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(52,1): error TS2322: Type '(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type '(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'. + Types of parameters 'y' and 'y' are incompatible. + Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'. + Types of property 'foo' are incompatible. + Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(55,1): error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: U; b: V; }) => U[]'. - Type '(U | V)[]' is not assignable to type 'U[]'. - Type 'U | V' is not assignable to type 'U'. - Type 'V' is not assignable to type 'U'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: U; b: V; }' is not assignable to type '{ a: U; b: U; }'. + Types of property 'b' are incompatible. + Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(58,1): error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: U; b: V; }) => U[]'. Types of parameters 'x' and 'x' are incompatible. Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'. @@ -11,7 +17,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Type 'U' is not assignable to type 'Base'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts (3 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts (4 errors) ==== // checking assignment compat for function types. No errors in this file class Base { foo: string; } @@ -67,14 +73,21 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var b11: (x: { foo: T }, y: { foo: U; bar: U }) => Base; a11 = b11; // ok b11 = a11; // ok + ~~~ +!!! error TS2322: Type '(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type '(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'. +!!! error TS2322: Types of property 'foo' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type 'T'. var b15: (x: { a: U; b: V; }) => U[]; a15 = b15; // ok, T = U, T = V b15 = a15; // ok ~~~ !!! error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: U; b: V; }) => U[]'. -!!! error TS2322: Type '(U | V)[]' is not assignable to type 'U[]'. -!!! error TS2322: Type 'U | V' is not assignable to type 'U'. -!!! error TS2322: Type 'V' is not assignable to type 'U'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: U; b: V; }' is not assignable to type '{ a: U; b: U; }'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'V' is not assignable to type 'U'. var b16: (x: { a: T; b: T }) => T[]; a15 = b16; // ok b15 = a16; // ok diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt index b8399a1855b..e3d7fda7ba3 100644 --- a/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt @@ -1,5 +1,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(30,1): error TS2322: Type '(x: T) => void' is not assignable to type '(x: T) => T'. Type 'void' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(39,1): error TS2322: Type '(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type '(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'. + Types of parameters 'y' and 'y' are incompatible. + Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'. + Types of property 'foo' are incompatible. + Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(42,1): error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: T; b: T; }) => T[]'. Types of parameters 'x' and 'x' are incompatible. Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'. @@ -7,7 +12,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Type 'T' is not assignable to type 'Base'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts (2 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts (3 errors) ==== // checking assignment compatibility relations for function types. All valid class Base { foo: string; } @@ -50,6 +55,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var b11: (x: { foo: T }, y: { foo: U; bar: U }) => Base; x.a11 = b11; b11 = x.a11; + ~~~ +!!! error TS2322: Type '(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type '(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'. +!!! error TS2322: Types of property 'foo' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type 'T'. var b16: (x: { a: T; b: T }) => T[]; x.a16 = b16; b16 = x.a16; diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt index f9a5be732c9..3bce93635d0 100644 --- a/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt @@ -45,6 +45,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Property 'baz' is missing in type 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(83,1): error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new (x: Base[], y: T) => T'. Type 'Derived[]' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(85,1): error TS2322: Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => Object'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. + Types of property 'b' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new (x: { a: T; b: T; }) => T'. Types of parameters 'x' and 'x' are incompatible. Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. @@ -52,7 +57,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Type 'T' is not assignable to type 'string'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (14 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (15 errors) ==== // checking assignment compatibility relations for function types. All of these are valid. class Base { foo: string; } @@ -198,6 +203,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme !!! error TS2322: Type 'Derived[]' is not assignable to type 'T'. var b14: new (x: { a: T; b: T }) => T; a14 = b14; // ok + ~~~ +!!! error TS2322: Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => Object'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. b14 = a14; // ok ~~~ !!! error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new (x: { a: T; b: T; }) => T'. diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt index 8679b1d85f1..620e83e1603 100644 --- a/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt @@ -22,8 +22,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(66,9): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new (x: Base[], y: Base[]) => T'. Type 'Derived[]' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(69,9): error TS2322: Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. + Types of property 'b' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(70,9): error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new (x: { a: T; b: T; }) => T'. Types of parameters 'x' and 'x' are incompatible. Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. @@ -172,8 +174,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a15 = b15; // ok ~~~ !!! error TS2322: Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. b15 = a15; // ok ~~~ !!! error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new (x: { a: T; b: T; }) => T'. diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt index 23e0c682fdc..5445d9ee35a 100644 --- a/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt @@ -1,9 +1,15 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(40,1): error TS2322: Type 'new (x: T) => void' is not assignable to type 'new (x: T) => T'. Type 'void' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(52,1): error TS2322: Type 'new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type 'new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base'. + Types of parameters 'y' and 'y' are incompatible. + Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'. + Types of property 'foo' are incompatible. + Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(55,1): error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: U; b: V; }) => U[]'. - Type '(U | V)[]' is not assignable to type 'U[]'. - Type 'U | V' is not assignable to type 'U'. - Type 'V' is not assignable to type 'U'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: U; b: V; }' is not assignable to type '{ a: U; b: U; }'. + Types of property 'b' are incompatible. + Type 'V' is not assignable to type 'U'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(58,1): error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: U; b: V; }) => U[]'. Types of parameters 'x' and 'x' are incompatible. Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'. @@ -11,7 +17,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Type 'U' is not assignable to type 'Base'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts (3 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts (4 errors) ==== // checking assignment compat for function types. All valid class Base { foo: string; } @@ -67,14 +73,21 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var b11: new (x: { foo: T }, y: { foo: U; bar: U }) => Base; a11 = b11; // ok b11 = a11; // ok + ~~~ +!!! error TS2322: Type 'new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type 'new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'. +!!! error TS2322: Types of property 'foo' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type 'T'. var b15: new (x: { a: U; b: V; }) => U[]; a15 = b15; // ok b15 = a15; // ok ~~~ !!! error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: U; b: V; }) => U[]'. -!!! error TS2322: Type '(U | V)[]' is not assignable to type 'U[]'. -!!! error TS2322: Type 'U | V' is not assignable to type 'U'. -!!! error TS2322: Type 'V' is not assignable to type 'U'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: U; b: V; }' is not assignable to type '{ a: U; b: U; }'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'V' is not assignable to type 'U'. var b16: new (x: { a: T; b: T }) => T[]; a15 = b16; // ok b15 = a16; // ok diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt index f89db500202..399a56e4136 100644 --- a/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt @@ -1,5 +1,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(30,1): error TS2322: Type 'new (x: T) => void' is not assignable to type 'new (x: T) => T'. Type 'void' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(39,1): error TS2322: Type 'new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type 'new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base'. + Types of parameters 'y' and 'y' are incompatible. + Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'. + Types of property 'foo' are incompatible. + Type 'U' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(42,1): error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: T; b: T; }) => T[]'. Types of parameters 'x' and 'x' are incompatible. Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'. @@ -7,7 +12,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Type 'T' is not assignable to type 'Base'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts (2 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts (3 errors) ==== // checking assignment compatibility relations for function types. All valid. class Base { foo: string; } @@ -50,6 +55,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var b11: new (x: { foo: T }, y: { foo: U; bar: U }) => Base; x.a11 = b11; b11 = x.a11; + ~~~ +!!! error TS2322: Type 'new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type 'new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'. +!!! error TS2322: Types of property 'foo' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type 'T'. var b16: new (x: { a: T; b: T }) => T[]; x.a16 = b16; b16 = x.a16; diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt index 7e39c3305a3..38f03ca68c4 100644 --- a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt @@ -1,9 +1,12 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts(15,1): error TS2322: Type 'B' is not assignable to type 'A'. + Types of parameters 'y' and 'y' are incompatible. + Type 'T[]' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts(16,1): error TS2322: Type 'A' is not assignable to type 'B'. Types of parameters 'y' and 'y' are incompatible. Type 'S' is not assignable to type 'S[]'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts (1 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts (2 errors) ==== // some complex cases of assignment compat of generic signatures. No contextual signature instantiation interface A { @@ -17,8 +20,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var a: A; var b: B; - // Both ok + // Both errors a = b; + ~ +!!! error TS2322: Type 'B' is not assignable to type 'A'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type 'T[]' is not assignable to type 'T'. b = a; ~ !!! error TS2322: Type 'A' is not assignable to type 'B'. diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.js b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.js index dd9b553791d..057cbebb382 100644 --- a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.js +++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.js @@ -12,7 +12,7 @@ interface B { var a: A; var b: B; -// Both ok +// Both errors a = b; b = a; @@ -21,6 +21,6 @@ b = a; // some complex cases of assignment compat of generic signatures. No contextual signature instantiation var a; var b; -// Both ok +// Both errors a = b; b = a; diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.symbols b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.symbols index 73991a789a2..9a37bebd6e2 100644 --- a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.symbols +++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.symbols @@ -31,7 +31,7 @@ var b: B; >b : Symbol(b, Decl(assignmentCompatWithGenericCallSignatures2.ts, 11, 3)) >B : Symbol(B, Decl(assignmentCompatWithGenericCallSignatures2.ts, 4, 1)) -// Both ok +// Both errors a = b; >a : Symbol(a, Decl(assignmentCompatWithGenericCallSignatures2.ts, 10, 3)) >b : Symbol(b, Decl(assignmentCompatWithGenericCallSignatures2.ts, 11, 3)) diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.types b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.types index 31b075d5bce..ab5bc2d49e8 100644 --- a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.types +++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.types @@ -19,7 +19,7 @@ var a: A; var b: B; >b : B -// Both ok +// Both errors a = b; >a = b : B >a : A diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance2.js b/tests/baselines/reference/callSignatureAssignabilityInInheritance2.js index 6913975d757..fe8f9330a5f 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance2.js +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance2.js @@ -62,7 +62,7 @@ interface I extends A { a11: (x: T, y: T) => T; // ok a12: >(x: Array, y: T) => Array; // ok, less specific parameter type a13: >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: (x: { a: T; b: U }) => T; // ok a15: (x: T) => T[]; // ok a16: (x: T) => number[]; // ok a17: (x: (a: T) => T) => T[]; // ok diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance2.symbols b/tests/baselines/reference/callSignatureAssignabilityInInheritance2.symbols index 849bcb1cf60..14e25b4e9d9 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance2.symbols +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance2.symbols @@ -354,18 +354,19 @@ interface I extends A { >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance2.ts, 62, 10)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance2.ts, 62, 10)) - a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: (x: { a: T; b: U }) => T; // ok >a14 : Symbol(I.a14, Decl(callSignatureAssignabilityInInheritance2.ts, 62, 63)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 10)) ->x : Symbol(x, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 13)) ->a : Symbol(a, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 17)) ->T : Symbol(T, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 10)) ->b : Symbol(b, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 23)) +>U : Symbol(U, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 12)) +>x : Symbol(x, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 16)) +>a : Symbol(a, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 20)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 10)) +>b : Symbol(b, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 26)) +>U : Symbol(U, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 12)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 10)) a15: (x: T) => T[]; // ok ->a15 : Symbol(I.a15, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 37)) +>a15 : Symbol(I.a15, Decl(callSignatureAssignabilityInInheritance2.ts, 63, 40)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance2.ts, 64, 10)) >x : Symbol(x, Decl(callSignatureAssignabilityInInheritance2.ts, 64, 13)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance2.ts, 64, 10)) diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance2.types b/tests/baselines/reference/callSignatureAssignabilityInInheritance2.types index ab6daaf8b5b..065d0027ed3 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance2.types +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance2.types @@ -230,11 +230,11 @@ interface I extends A { >x : Base[] >y : T - a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature ->a14 : (x: { a: T; b: T; }) => T ->x : { a: T; b: T; } + a14: (x: { a: T; b: U }) => T; // ok +>a14 : (x: { a: T; b: U; }) => T +>x : { a: T; b: U; } >a : T ->b : T +>b : U a15: (x: T) => T[]; // ok >a15 : (x: T) => T[] diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt index 5bf725b06e3..33af0d9f4bf 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt @@ -14,8 +14,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(76,19): error TS2430: Interface 'I6' incorrectly extends interface 'A'. Types of property 'a15' are incompatible. Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. + Types of property 'b' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(80,19): error TS2430: Interface 'I7' incorrectly extends interface 'A'. Types of property 'a15' are incompatible. Type '(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'. @@ -131,8 +133,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign !!! error TS2430: Interface 'I6' incorrectly extends interface 'A'. !!! error TS2430: Types of property 'a15' are incompatible. !!! error TS2430: Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'. -!!! error TS2430: Type 'string | number' is not assignable to type 'number'. -!!! error TS2430: Type 'string' is not assignable to type 'number'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. +!!! error TS2430: Types of property 'b' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. a15: (x: { a: T; b: T }) => T; // error, T is {} which isn't an acceptable return type } diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance5.js b/tests/baselines/reference/callSignatureAssignabilityInInheritance5.js index c04d5bcb2ab..9d7dbc9eab6 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance5.js +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance5.js @@ -45,7 +45,7 @@ interface I extends B { a11: (x: T, y: T) => T; // ok a12: >(x: Array, y: T) => Array; // ok, less specific parameter type a13: >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: (x: { a: T; b: U }) => T; // ok } //// [callSignatureAssignabilityInInheritance5.js] diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance5.symbols b/tests/baselines/reference/callSignatureAssignabilityInInheritance5.symbols index 4a9030e443b..de3bdf742d0 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance5.symbols +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance5.symbols @@ -302,13 +302,14 @@ interface I extends B { >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance5.ts, 45, 10)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance5.ts, 45, 10)) - a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: (x: { a: T; b: U }) => T; // ok >a14 : Symbol(I.a14, Decl(callSignatureAssignabilityInInheritance5.ts, 45, 63)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 10)) ->x : Symbol(x, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 13)) ->a : Symbol(a, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 17)) ->T : Symbol(T, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 10)) ->b : Symbol(b, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 23)) +>U : Symbol(U, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 12)) +>x : Symbol(x, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 16)) +>a : Symbol(a, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 20)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 10)) +>b : Symbol(b, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 26)) +>U : Symbol(U, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 12)) >T : Symbol(T, Decl(callSignatureAssignabilityInInheritance5.ts, 46, 10)) } diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance5.types b/tests/baselines/reference/callSignatureAssignabilityInInheritance5.types index 2d133bc6d65..3f892ff0b17 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance5.types +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance5.types @@ -180,9 +180,9 @@ interface I extends B { >x : Base[] >y : T - a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature ->a14 : (x: { a: T; b: T; }) => T ->x : { a: T; b: T; } + a14: (x: { a: T; b: U }) => T; // ok +>a14 : (x: { a: T; b: U; }) => T +>x : { a: T; b: U; } >a : T ->b : T +>b : U } diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.js b/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.js index 0c4b5c62380..a85f64f95a1 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.js +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.js @@ -62,7 +62,7 @@ interface I extends A { a11: new (x: T, y: T) => T; // ok a12: new >(x: Array, y: T) => Array; // ok, less specific parameter type a13: new >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok a15: new (x: T) => T[]; // ok a16: new (x: T) => number[]; // ok a17: new (x: new (a: T) => T) => T[]; // ok diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.symbols b/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.symbols index 1ad1c3707c5..2aaa5eda84f 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.symbols +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.symbols @@ -354,18 +354,19 @@ interface I extends A { >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance2.ts, 62, 14)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance2.ts, 62, 14)) - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok >a14 : Symbol(I.a14, Decl(constructSignatureAssignabilityInInheritance2.ts, 62, 67)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 14)) ->x : Symbol(x, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 17)) ->a : Symbol(a, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 21)) ->T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 14)) ->b : Symbol(b, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 27)) +>U : Symbol(U, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 16)) +>x : Symbol(x, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 20)) +>a : Symbol(a, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 24)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 14)) +>b : Symbol(b, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 30)) +>U : Symbol(U, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 16)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 14)) a15: new (x: T) => T[]; // ok ->a15 : Symbol(I.a15, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 41)) +>a15 : Symbol(I.a15, Decl(constructSignatureAssignabilityInInheritance2.ts, 63, 44)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance2.ts, 64, 14)) >x : Symbol(x, Decl(constructSignatureAssignabilityInInheritance2.ts, 64, 17)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance2.ts, 64, 14)) diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.types b/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.types index 01941d5219b..08a687d8867 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.types +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance2.types @@ -230,11 +230,11 @@ interface I extends A { >x : Base[] >y : T - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature ->a14 : new (x: { a: T; b: T; }) => T ->x : { a: T; b: T; } + a14: new (x: { a: T; b: U }) => T; // ok +>a14 : new (x: { a: T; b: U; }) => T +>x : { a: T; b: U; } >a : T ->b : T +>b : U a15: new (x: T) => T[]; // ok >a15 : new (x: T) => T[] diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt index 9646acd071f..1a9edc159af 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt @@ -14,8 +14,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(66,19): error TS2430: Interface 'I6' incorrectly extends interface 'A'. Types of property 'a15' are incompatible. Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. + Types of property 'b' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(70,19): error TS2430: Interface 'I7' incorrectly extends interface 'A'. Types of property 'a15' are incompatible. Type 'new (x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'. @@ -121,8 +123,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc !!! error TS2430: Interface 'I6' incorrectly extends interface 'A'. !!! error TS2430: Types of property 'a15' are incompatible. !!! error TS2430: Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'. -!!! error TS2430: Type 'string | number' is not assignable to type 'number'. -!!! error TS2430: Type 'string' is not assignable to type 'number'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'. +!!! error TS2430: Types of property 'b' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. a15: new (x: { a: T; b: T }) => T; // error, T is {} which isn't an acceptable return type } diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.js b/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.js index d81722fc950..8431b225440 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.js +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.js @@ -45,7 +45,7 @@ interface I extends B { a11: new (x: T, y: T) => T; // ok a12: new >(x: Array, y: T) => Array; // ok, less specific parameter type a13: new >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok } //// [constructSignatureAssignabilityInInheritance5.js] diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.symbols b/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.symbols index e1991673f98..c08d7537f65 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.symbols +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.symbols @@ -302,13 +302,14 @@ interface I extends B { >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance5.ts, 45, 14)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance5.ts, 45, 14)) - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok >a14 : Symbol(I.a14, Decl(constructSignatureAssignabilityInInheritance5.ts, 45, 67)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 14)) ->x : Symbol(x, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 17)) ->a : Symbol(a, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 21)) ->T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 14)) ->b : Symbol(b, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 27)) +>U : Symbol(U, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 16)) +>x : Symbol(x, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 20)) +>a : Symbol(a, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 24)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 14)) +>b : Symbol(b, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 30)) +>U : Symbol(U, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 16)) >T : Symbol(T, Decl(constructSignatureAssignabilityInInheritance5.ts, 46, 14)) } diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.types b/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.types index 0397a78f678..9296ce8295d 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.types +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance5.types @@ -180,9 +180,9 @@ interface I extends B { >x : Base[] >y : T - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature ->a14 : new (x: { a: T; b: T; }) => T ->x : { a: T; b: T; } + a14: new (x: { a: T; b: U }) => T; // ok +>a14 : new (x: { a: T; b: U; }) => T +>x : { a: T; b: U; } >a : T ->b : T +>b : U } diff --git a/tests/baselines/reference/contextualSignatureInstantiation.errors.txt b/tests/baselines/reference/contextualSignatureInstantiation.errors.txt new file mode 100644 index 00000000000..6c14ad3c150 --- /dev/null +++ b/tests/baselines/reference/contextualSignatureInstantiation.errors.txt @@ -0,0 +1,53 @@ +tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts(19,13): error TS2345: Argument of type '(x: T, y: T) => T' is not assignable to parameter of type '(x: number, y: string) => number'. + Types of parameters 'y' and 'y' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts(20,23): error TS2345: Argument of type '(x: T, y: T) => T' is not assignable to parameter of type '(x: number, y: string) => number'. + Types of parameters 'y' and 'y' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts(21,23): error TS2345: Argument of type '(x: T, y: T) => T' is not assignable to parameter of type '(x: string, y: number) => string'. + Types of parameters 'y' and 'y' are incompatible. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts (3 errors) ==== + // TypeScript Spec, section 4.12.2: + // If e is an expression of a function type that contains exactly one generic call signature and no other members, + // and T is a function type with exactly one non - generic call signature and no other members, then any inferences + // made for type parameters referenced by the parameters of T's call signature are fixed, and e's type is changed + // to a function type with e's call signature instantiated in the context of T's call signature (section 3.8.5). + + declare function foo(cb: (x: number, y: string) => T): T; + declare function bar(x: T, y: U, cb: (x: T, y: U) => V): V; + declare function baz(x: T, y: T, cb: (x: T, y: T) => U): U; + + declare function g(x: T, y: T): T; + declare function h(x: T, y: U): T[] | U[]; + + var a: number; + var a = bar(1, 1, g); // Should be number + var a = baz(1, 1, g); // Should be number + + var b: number | string; + var b = foo(g); // Error, number and string are disjoint types + ~ +!!! error TS2345: Argument of type '(x: T, y: T) => T' is not assignable to parameter of type '(x: number, y: string) => number'. +!!! error TS2345: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. + var b = bar(1, "one", g); // Error, number and string are disjoint types + ~ +!!! error TS2345: Argument of type '(x: T, y: T) => T' is not assignable to parameter of type '(x: number, y: string) => number'. +!!! error TS2345: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. + var b = bar("one", 1, g); // Error, number and string are disjoint types + ~ +!!! error TS2345: Argument of type '(x: T, y: T) => T' is not assignable to parameter of type '(x: string, y: number) => string'. +!!! error TS2345: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + var b = baz(b, b, g); // Should be number | string + + var d: number[] | string[]; + var d = foo(h); // Should be number[] | string[] + var d = bar(1, "one", h); // Should be number[] | string[] + var d = bar("one", 1, h); // Should be number[] | string[] + var d = baz(d, d, g); // Should be number[] | string[] + \ No newline at end of file diff --git a/tests/baselines/reference/contextualSignatureInstantiation.js b/tests/baselines/reference/contextualSignatureInstantiation.js index 11e19b3262e..d945592bbda 100644 --- a/tests/baselines/reference/contextualSignatureInstantiation.js +++ b/tests/baselines/reference/contextualSignatureInstantiation.js @@ -17,9 +17,9 @@ var a = bar(1, 1, g); // Should be number var a = baz(1, 1, g); // Should be number var b: number | string; -var b = foo(g); // Should be number | string -var b = bar(1, "one", g); // Should be number | string -var b = bar("one", 1, g); // Should be number | string +var b = foo(g); // Error, number and string are disjoint types +var b = bar(1, "one", g); // Error, number and string are disjoint types +var b = bar("one", 1, g); // Error, number and string are disjoint types var b = baz(b, b, g); // Should be number | string var d: number[] | string[]; @@ -39,9 +39,9 @@ var a; var a = bar(1, 1, g); // Should be number var a = baz(1, 1, g); // Should be number var b; -var b = foo(g); // Should be number | string -var b = bar(1, "one", g); // Should be number | string -var b = bar("one", 1, g); // Should be number | string +var b = foo(g); // Error, number and string are disjoint types +var b = bar(1, "one", g); // Error, number and string are disjoint types +var b = bar("one", 1, g); // Error, number and string are disjoint types var b = baz(b, b, g); // Should be number | string var d; var d = foo(h); // Should be number[] | string[] diff --git a/tests/baselines/reference/contextualSignatureInstantiation.symbols b/tests/baselines/reference/contextualSignatureInstantiation.symbols index c16ffed84b7..742ae58905c 100644 --- a/tests/baselines/reference/contextualSignatureInstantiation.symbols +++ b/tests/baselines/reference/contextualSignatureInstantiation.symbols @@ -83,17 +83,17 @@ var a = baz(1, 1, g); // Should be number var b: number | string; >b : Symbol(b, Decl(contextualSignatureInstantiation.ts, 17, 3), Decl(contextualSignatureInstantiation.ts, 18, 3), Decl(contextualSignatureInstantiation.ts, 19, 3), Decl(contextualSignatureInstantiation.ts, 20, 3), Decl(contextualSignatureInstantiation.ts, 21, 3)) -var b = foo(g); // Should be number | string +var b = foo(g); // Error, number and string are disjoint types >b : Symbol(b, Decl(contextualSignatureInstantiation.ts, 17, 3), Decl(contextualSignatureInstantiation.ts, 18, 3), Decl(contextualSignatureInstantiation.ts, 19, 3), Decl(contextualSignatureInstantiation.ts, 20, 3), Decl(contextualSignatureInstantiation.ts, 21, 3)) >foo : Symbol(foo, Decl(contextualSignatureInstantiation.ts, 0, 0)) >g : Symbol(g, Decl(contextualSignatureInstantiation.ts, 8, 65)) -var b = bar(1, "one", g); // Should be number | string +var b = bar(1, "one", g); // Error, number and string are disjoint types >b : Symbol(b, Decl(contextualSignatureInstantiation.ts, 17, 3), Decl(contextualSignatureInstantiation.ts, 18, 3), Decl(contextualSignatureInstantiation.ts, 19, 3), Decl(contextualSignatureInstantiation.ts, 20, 3), Decl(contextualSignatureInstantiation.ts, 21, 3)) >bar : Symbol(bar, Decl(contextualSignatureInstantiation.ts, 6, 60)) >g : Symbol(g, Decl(contextualSignatureInstantiation.ts, 8, 65)) -var b = bar("one", 1, g); // Should be number | string +var b = bar("one", 1, g); // Error, number and string are disjoint types >b : Symbol(b, Decl(contextualSignatureInstantiation.ts, 17, 3), Decl(contextualSignatureInstantiation.ts, 18, 3), Decl(contextualSignatureInstantiation.ts, 19, 3), Decl(contextualSignatureInstantiation.ts, 20, 3), Decl(contextualSignatureInstantiation.ts, 21, 3)) >bar : Symbol(bar, Decl(contextualSignatureInstantiation.ts, 6, 60)) >g : Symbol(g, Decl(contextualSignatureInstantiation.ts, 8, 65)) diff --git a/tests/baselines/reference/contextualSignatureInstantiation.types b/tests/baselines/reference/contextualSignatureInstantiation.types index 0f8c1ed49ba..ae5a4000537 100644 --- a/tests/baselines/reference/contextualSignatureInstantiation.types +++ b/tests/baselines/reference/contextualSignatureInstantiation.types @@ -59,23 +59,23 @@ var a = baz(1, 1, g); // Should be number var b: number | string; >b : string | number -var b = foo(g); // Should be number | string +var b = foo(g); // Error, number and string are disjoint types >b : string | number ->foo(g) : string | number +>foo(g) : any >foo : (cb: (x: number, y: string) => T) => T >g : (x: T, y: T) => T -var b = bar(1, "one", g); // Should be number | string +var b = bar(1, "one", g); // Error, number and string are disjoint types >b : string | number ->bar(1, "one", g) : string | number +>bar(1, "one", g) : any >bar : (x: T, y: U, cb: (x: T, y: U) => V) => V >1 : 1 >"one" : "one" >g : (x: T, y: T) => T -var b = bar("one", 1, g); // Should be number | string +var b = bar("one", 1, g); // Error, number and string are disjoint types >b : string | number ->bar("one", 1, g) : string | number +>bar("one", 1, g) : any >bar : (x: T, y: U, cb: (x: T, y: U) => V) => V >"one" : "one" >1 : 1 diff --git a/tests/baselines/reference/contextualSignatureInstatiationContravariance.errors.txt b/tests/baselines/reference/contextualSignatureInstatiationContravariance.errors.txt new file mode 100644 index 00000000000..fe9c6cf3f14 --- /dev/null +++ b/tests/baselines/reference/contextualSignatureInstatiationContravariance.errors.txt @@ -0,0 +1,23 @@ +tests/cases/compiler/contextualSignatureInstatiationContravariance.ts(8,1): error TS2322: Type '(x: T, y: T) => void' is not assignable to type '(g: Giraffe, e: Elephant) => void'. + Types of parameters 'y' and 'e' are incompatible. + Type 'Elephant' is not assignable to type 'Giraffe'. + Property 'y' is missing in type 'Elephant'. + + +==== tests/cases/compiler/contextualSignatureInstatiationContravariance.ts (1 errors) ==== + interface Animal { x } + interface Giraffe extends Animal { y } + interface Elephant extends Animal { y2 } + + var f2: (x: T, y: T) => void; + + var g2: (g: Giraffe, e: Elephant) => void; + g2 = f2; // error because Giraffe and Elephant are disjoint types + ~~ +!!! error TS2322: Type '(x: T, y: T) => void' is not assignable to type '(g: Giraffe, e: Elephant) => void'. +!!! error TS2322: Types of parameters 'y' and 'e' are incompatible. +!!! error TS2322: Type 'Elephant' is not assignable to type 'Giraffe'. +!!! error TS2322: Property 'y' is missing in type 'Elephant'. + + var h2: (g1: Giraffe, g2: Giraffe) => void; + h2 = f2; // valid because Giraffe satisfies the constraint. It is safe in the traditional contravariant fashion. \ No newline at end of file diff --git a/tests/baselines/reference/contextualSignatureInstatiationContravariance.js b/tests/baselines/reference/contextualSignatureInstatiationContravariance.js index 6e731d61713..6e2de5d2907 100644 --- a/tests/baselines/reference/contextualSignatureInstatiationContravariance.js +++ b/tests/baselines/reference/contextualSignatureInstatiationContravariance.js @@ -6,7 +6,7 @@ interface Elephant extends Animal { y2 } var f2: (x: T, y: T) => void; var g2: (g: Giraffe, e: Elephant) => void; -g2 = f2; // valid because both Giraffe and Elephant satisfy the constraint. T is Animal +g2 = f2; // error because Giraffe and Elephant are disjoint types var h2: (g1: Giraffe, g2: Giraffe) => void; h2 = f2; // valid because Giraffe satisfies the constraint. It is safe in the traditional contravariant fashion. @@ -14,6 +14,6 @@ h2 = f2; // valid because Giraffe satisfies the constraint. It is safe in the tr //// [contextualSignatureInstatiationContravariance.js] var f2; var g2; -g2 = f2; // valid because both Giraffe and Elephant satisfy the constraint. T is Animal +g2 = f2; // error because Giraffe and Elephant are disjoint types var h2; h2 = f2; // valid because Giraffe satisfies the constraint. It is safe in the traditional contravariant fashion. diff --git a/tests/baselines/reference/contextualSignatureInstatiationContravariance.symbols b/tests/baselines/reference/contextualSignatureInstatiationContravariance.symbols index 37a0c4adb02..fc11cca8aa6 100644 --- a/tests/baselines/reference/contextualSignatureInstatiationContravariance.symbols +++ b/tests/baselines/reference/contextualSignatureInstatiationContravariance.symbols @@ -29,7 +29,7 @@ var g2: (g: Giraffe, e: Elephant) => void; >e : Symbol(e, Decl(contextualSignatureInstatiationContravariance.ts, 6, 20)) >Elephant : Symbol(Elephant, Decl(contextualSignatureInstatiationContravariance.ts, 1, 38)) -g2 = f2; // valid because both Giraffe and Elephant satisfy the constraint. T is Animal +g2 = f2; // error because Giraffe and Elephant are disjoint types >g2 : Symbol(g2, Decl(contextualSignatureInstatiationContravariance.ts, 6, 3)) >f2 : Symbol(f2, Decl(contextualSignatureInstatiationContravariance.ts, 4, 3)) diff --git a/tests/baselines/reference/contextualSignatureInstatiationContravariance.types b/tests/baselines/reference/contextualSignatureInstatiationContravariance.types index d0d281b7d49..0ca89f7016c 100644 --- a/tests/baselines/reference/contextualSignatureInstatiationContravariance.types +++ b/tests/baselines/reference/contextualSignatureInstatiationContravariance.types @@ -18,7 +18,7 @@ var g2: (g: Giraffe, e: Elephant) => void; >g : Giraffe >e : Elephant -g2 = f2; // valid because both Giraffe and Elephant satisfy the constraint. T is Animal +g2 = f2; // error because Giraffe and Elephant are disjoint types >g2 = f2 : (x: T, y: T) => void >g2 : (g: Giraffe, e: Elephant) => void >f2 : (x: T, y: T) => void diff --git a/tests/baselines/reference/subtypingWithCallSignatures2.types b/tests/baselines/reference/subtypingWithCallSignatures2.types index 52b763cdaff..c8ac07429f3 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures2.types +++ b/tests/baselines/reference/subtypingWithCallSignatures2.types @@ -737,20 +737,20 @@ var r14arg2 = (x: { a: string; b: number }) => null; >null : null var r14 = foo14(r14arg1); // any ->r14 : (x: { a: string; b: number; }) => Object ->foo14(r14arg1) : (x: { a: string; b: number; }) => Object +>r14 : any +>foo14(r14arg1) : any >foo14 : { (a: (x: { a: string; b: number; }) => Object): (x: { a: string; b: number; }) => Object; (a: any): any; } >r14arg1 : (x: { a: T; b: T; }) => T var r14a = [r14arg1, r14arg2]; ->r14a : ((x: { a: string; b: number; }) => Object)[] ->[r14arg1, r14arg2] : ((x: { a: string; b: number; }) => Object)[] +>r14a : (((x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => Object))[] +>[r14arg1, r14arg2] : (((x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => Object))[] >r14arg1 : (x: { a: T; b: T; }) => T >r14arg2 : (x: { a: string; b: number; }) => Object var r14b = [r14arg2, r14arg1]; ->r14b : ((x: { a: string; b: number; }) => Object)[] ->[r14arg2, r14arg1] : ((x: { a: string; b: number; }) => Object)[] +>r14b : (((x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => Object))[] +>[r14arg2, r14arg1] : (((x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => Object))[] >r14arg2 : (x: { a: string; b: number; }) => Object >r14arg1 : (x: { a: T; b: T; }) => T diff --git a/tests/baselines/reference/subtypingWithCallSignatures4.types b/tests/baselines/reference/subtypingWithCallSignatures4.types index e169885b87f..4a0b3416e56 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures4.types +++ b/tests/baselines/reference/subtypingWithCallSignatures4.types @@ -381,14 +381,14 @@ var r11 = foo11(r11arg); >r11arg : (x: { foo: T; }, y: { foo: U; bar: U; }) => Base var r11a = [r11arg, r11arg2]; ->r11a : ((x: { foo: T; }, y: { foo: U; bar: U; }) => Base)[] ->[r11arg, r11arg2] : ((x: { foo: T; }, y: { foo: U; bar: U; }) => Base)[] +>r11a : ((x: { foo: T; }, y: { foo: T; bar: T; }) => Base)[] +>[r11arg, r11arg2] : ((x: { foo: T; }, y: { foo: T; bar: T; }) => Base)[] >r11arg : (x: { foo: T; }, y: { foo: U; bar: U; }) => Base >r11arg2 : (x: { foo: T; }, y: { foo: T; bar: T; }) => Base var r11b = [r11arg2, r11arg]; ->r11b : ((x: { foo: T; }, y: { foo: U; bar: U; }) => Base)[] ->[r11arg2, r11arg] : ((x: { foo: T; }, y: { foo: U; bar: U; }) => Base)[] +>r11b : ((x: { foo: T; }, y: { foo: T; bar: T; }) => Base)[] +>[r11arg2, r11arg] : ((x: { foo: T; }, y: { foo: T; bar: T; }) => Base)[] >r11arg2 : (x: { foo: T; }, y: { foo: T; bar: T; }) => Base >r11arg : (x: { foo: T; }, y: { foo: U; bar: U; }) => Base diff --git a/tests/baselines/reference/subtypingWithConstructSignatures2.types b/tests/baselines/reference/subtypingWithConstructSignatures2.types index 8021e2105fb..0d2ff802911 100644 --- a/tests/baselines/reference/subtypingWithConstructSignatures2.types +++ b/tests/baselines/reference/subtypingWithConstructSignatures2.types @@ -653,20 +653,20 @@ var r14arg2: new (x: { a: string; b: number }) => Object; >b : number var r14 = foo14(r14arg1); // any ->r14 : new (x: { a: string; b: number; }) => Object ->foo14(r14arg1) : new (x: { a: string; b: number; }) => Object +>r14 : any +>foo14(r14arg1) : any >foo14 : { (a: new (x: { a: string; b: number; }) => Object): new (x: { a: string; b: number; }) => Object; (a: any): any; } >r14arg1 : new (x: { a: T; b: T; }) => T var r14a = [r14arg1, r14arg2]; ->r14a : (new (x: { a: string; b: number; }) => Object)[] ->[r14arg1, r14arg2] : (new (x: { a: string; b: number; }) => Object)[] +>r14a : ((new (x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => Object))[] +>[r14arg1, r14arg2] : ((new (x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => Object))[] >r14arg1 : new (x: { a: T; b: T; }) => T >r14arg2 : new (x: { a: string; b: number; }) => Object var r14b = [r14arg2, r14arg1]; ->r14b : (new (x: { a: string; b: number; }) => Object)[] ->[r14arg2, r14arg1] : (new (x: { a: string; b: number; }) => Object)[] +>r14b : ((new (x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => Object))[] +>[r14arg2, r14arg1] : ((new (x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => Object))[] >r14arg2 : new (x: { a: string; b: number; }) => Object >r14arg1 : new (x: { a: T; b: T; }) => T diff --git a/tests/baselines/reference/subtypingWithConstructSignatures4.types b/tests/baselines/reference/subtypingWithConstructSignatures4.types index 412f7b2f73b..6c9881d1228 100644 --- a/tests/baselines/reference/subtypingWithConstructSignatures4.types +++ b/tests/baselines/reference/subtypingWithConstructSignatures4.types @@ -343,14 +343,14 @@ var r11 = foo11(r11arg); >r11arg : new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base var r11a = [r11arg, r11arg2]; ->r11a : (new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base)[] ->[r11arg, r11arg2] : (new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base)[] +>r11a : (new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base)[] +>[r11arg, r11arg2] : (new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base)[] >r11arg : new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base >r11arg2 : new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base var r11b = [r11arg2, r11arg]; ->r11b : (new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base)[] ->[r11arg2, r11arg] : (new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base)[] +>r11b : (new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base)[] +>[r11arg2, r11arg] : (new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base)[] >r11arg2 : new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base >r11arg : new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base diff --git a/tests/baselines/reference/subtypingWithConstructSignatures5.js b/tests/baselines/reference/subtypingWithConstructSignatures5.js index d3f47955ffc..de10469def0 100644 --- a/tests/baselines/reference/subtypingWithConstructSignatures5.js +++ b/tests/baselines/reference/subtypingWithConstructSignatures5.js @@ -45,7 +45,7 @@ interface I extends B { a11: new (x: T, y: T) => T; // ok a12: new >(x: Array, y: T) => Array; // ok, less specific parameter type a13: new >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok } //// [subtypingWithConstructSignatures5.js] diff --git a/tests/baselines/reference/subtypingWithConstructSignatures5.symbols b/tests/baselines/reference/subtypingWithConstructSignatures5.symbols index cbb55d20155..2daf0631a09 100644 --- a/tests/baselines/reference/subtypingWithConstructSignatures5.symbols +++ b/tests/baselines/reference/subtypingWithConstructSignatures5.symbols @@ -302,13 +302,14 @@ interface I extends B { >T : Symbol(T, Decl(subtypingWithConstructSignatures5.ts, 45, 14)) >T : Symbol(T, Decl(subtypingWithConstructSignatures5.ts, 45, 14)) - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature + a14: new (x: { a: T; b: U }) => T; // ok >a14 : Symbol(I.a14, Decl(subtypingWithConstructSignatures5.ts, 45, 67)) >T : Symbol(T, Decl(subtypingWithConstructSignatures5.ts, 46, 14)) ->x : Symbol(x, Decl(subtypingWithConstructSignatures5.ts, 46, 17)) ->a : Symbol(a, Decl(subtypingWithConstructSignatures5.ts, 46, 21)) ->T : Symbol(T, Decl(subtypingWithConstructSignatures5.ts, 46, 14)) ->b : Symbol(b, Decl(subtypingWithConstructSignatures5.ts, 46, 27)) +>U : Symbol(U, Decl(subtypingWithConstructSignatures5.ts, 46, 16)) +>x : Symbol(x, Decl(subtypingWithConstructSignatures5.ts, 46, 20)) +>a : Symbol(a, Decl(subtypingWithConstructSignatures5.ts, 46, 24)) >T : Symbol(T, Decl(subtypingWithConstructSignatures5.ts, 46, 14)) +>b : Symbol(b, Decl(subtypingWithConstructSignatures5.ts, 46, 30)) +>U : Symbol(U, Decl(subtypingWithConstructSignatures5.ts, 46, 16)) >T : Symbol(T, Decl(subtypingWithConstructSignatures5.ts, 46, 14)) } diff --git a/tests/baselines/reference/subtypingWithConstructSignatures5.types b/tests/baselines/reference/subtypingWithConstructSignatures5.types index a7adde7a480..d86cfe1c51d 100644 --- a/tests/baselines/reference/subtypingWithConstructSignatures5.types +++ b/tests/baselines/reference/subtypingWithConstructSignatures5.types @@ -180,9 +180,9 @@ interface I extends B { >x : Base[] >y : T - a14: new (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature ->a14 : new (x: { a: T; b: T; }) => T ->x : { a: T; b: T; } + a14: new (x: { a: T; b: U }) => T; // ok +>a14 : new (x: { a: T; b: U; }) => T +>x : { a: T; b: U; } >a : T ->b : T +>b : U } From 7b4f864b4957cad758dbd7b57b6ee4c9d33c567c Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 29 Aug 2018 15:06:26 -0700 Subject: [PATCH 095/163] moduleSpecifiers: Simpler criteria for preferring relative path vs baseUrl (#25803) * moduleSpecifiers: Simpler criteria for preferring relative path vs baseUrl * Don't unconditonally use a path mapping --- src/compiler/moduleSpecifiers.ts | 60 +++++-------------- .../importNameCodeFixNewImportPaths0.ts | 5 +- .../importNameCodeFixNewImportPaths1.ts | 5 +- .../importNameCodeFixNewImportPaths2.ts | 5 +- ...NameCodeFixNewImportPaths_withExtension.ts | 5 +- ...deFixNewImportPaths_withLeadingDotSlash.ts | 5 +- ...ixNewImportPaths_withParentRelativePath.ts | 5 +- .../importNameCodeFix_fromPathMapping.ts | 3 + .../importNameCodeFix_preferBaseUrl.ts | 20 +++++++ 9 files changed, 61 insertions(+), 52 deletions(-) create mode 100644 tests/cases/fourslash/importNameCodeFix_preferBaseUrl.ts diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index b34471a107a..2e4d1ec86de 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -127,53 +127,30 @@ namespace ts.moduleSpecifiers { } const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions); - if (paths) { - const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); - if (fromPaths) { - return [fromPaths]; - } - } + const fromPaths = paths && tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + const nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths; if (relativePreference === RelativePreference.NonRelative) { - return [importRelativeToBaseUrl]; + return [nonRelative]; } if (relativePreference !== RelativePreference.Auto) Debug.assertNever(relativePreference); - if (isPathRelativeToParent(relativeToBaseUrl)) { + if (isPathRelativeToParent(nonRelative)) { return [relativePath]; } - /* - Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. + // Prefer a relative import over a baseUrl import if it has fewer components. + const relativeFirst = countPathComponents(relativePath) < countPathComponents(nonRelative); + return relativeFirst ? [relativePath, nonRelative] : [nonRelative, relativePath]; + } - Suppose we have: - baseUrl = /base - sourceDirectory = /base/a/b - moduleFileName = /base/foo/bar - Then: - relativePath = ../../foo/bar - getRelativePathNParents(relativePath) = 2 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 2 < 2 = false - In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/foo/a - moduleFileName = /base/foo/bar - Then: - relativePath = ../a - getRelativePathNParents(relativePath) = 1 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 1 < 2 = true - In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". - */ - const pathFromSourceToBaseUrl = ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); - const relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); - return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; + function countPathComponents(path: string): number { + let count = 0; + for (let i = startsWith(path, "./") ? 2 : 0; i < path.length; i++) { + if (path.charCodeAt(i) === CharacterCodes.slash) count++; + } + return count; } function usesJsExtensionOnImports({ imports }: SourceFile): boolean { @@ -245,15 +222,6 @@ namespace ts.moduleSpecifiers { return result; } - function getRelativePathNParents(relativePath: string): number { - const components = getPathComponents(relativePath); - if (components[0] || components.length === 1) return 0; - for (let i = 1; i < components.length; i++) { - if (components[i] !== "..") return i - 1; - } - return components.length - 1; - } - function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined { const decl = find(moduleSymbol.declarations, d => isNonGlobalAmbientModule(d) && (!isExternalModuleAugmentation(d) || !isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name))) diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths0.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths0.ts index bd3fd9a84b3..90f21703326 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths0.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths0.ts @@ -18,5 +18,8 @@ verify.importFixAtPosition([ `import { foo } from "a"; -foo();` +foo();`, +`import { foo } from "./folder_a/f2"; + +foo();`, ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths1.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths1.ts index 5ac195e9ab4..041ef40380d 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths1.ts @@ -18,5 +18,8 @@ verify.importFixAtPosition([ `import { foo } from "b/f2"; -foo();` +foo();`, +`import { foo } from "./folder_b/f2"; + +foo();`, ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths2.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths2.ts index 33b8d9330be..63aabfc4e5f 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths2.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths2.ts @@ -24,5 +24,8 @@ verify.importFixAtPosition([ `import { foo } from "b"; -foo();` +foo();`, +`import { foo } from "./folder_b"; + +foo();`, ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts index c383b09862e..2275758cda1 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts @@ -19,5 +19,8 @@ verify.importFixAtPosition([ `import { foo } from "foo"; -foo` +foo`, +`import { foo } from "./thisHasPathMapping"; + +foo`, ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts index f29932eed73..acf1fa369ef 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts @@ -19,5 +19,8 @@ verify.importFixAtPosition([ `import { foo } from "foo"; -foo` +foo`, +`import { foo } from "./thisHasPathMapping"; + +foo`, ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts index 4bd938ae0b9..816fb309a08 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts @@ -19,5 +19,8 @@ verify.importFixAtPosition([ `import { foo } from "foo"; -foo` +foo`, +`import { foo } from "../thisHasPathMapping"; + +foo`, ]); diff --git a/tests/cases/fourslash/importNameCodeFix_fromPathMapping.ts b/tests/cases/fourslash/importNameCodeFix_fromPathMapping.ts index dda8b855123..35a42d8cbf1 100644 --- a/tests/cases/fourslash/importNameCodeFix_fromPathMapping.ts +++ b/tests/cases/fourslash/importNameCodeFix_fromPathMapping.ts @@ -18,6 +18,9 @@ goTo.file("/b.ts"); verify.importFixAtPosition([ +`import { foo } from "./a"; + +foo;`, `import { foo } from "@root/a"; foo;`, diff --git a/tests/cases/fourslash/importNameCodeFix_preferBaseUrl.ts b/tests/cases/fourslash/importNameCodeFix_preferBaseUrl.ts new file mode 100644 index 00000000000..5d2d861550e --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_preferBaseUrl.ts @@ -0,0 +1,20 @@ +/// + +// @Filename: /tsconfig.json +////{ "compilerOptions": { "baseUrl": "./src" } } + +// @Filename: /src/d0/d1/d2/file.ts +////foo/**/; + +// @Filename: /src/d0/a.ts +////export const foo = 0; + +goTo.file("/src/d0/d1/d2/file.ts"); +verify.importFixAtPosition([ +`import { foo } from "d0/a"; + +foo;`, +`import { foo } from "../../a"; + +foo;`, +]); From 29dbabe2e14a343a94d621e2acefd0121bd2a818 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 29 Aug 2018 15:06:38 -0700 Subject: [PATCH 096/163] In JS, fix contextual type of this assignments (#26743) in object literal methods inside an object literal with a type annotation. Note that this does not change: 1. The type of `this` in object literal methods. 2. The fact that this-property assignments are still declarations. They just don't block contextual typing like most declarations do. This change is a bit expensive. It first calls getThisContainer, which walks the tree upward. Then it calls checkThisExpression, which will usually call getContextualType on the object literal method. If the new code then returns true, it will proceed to redo much of that work. Calling checkThisExpression should not cause incorrect circularity failures; we only have to inspect the shape of the object literal and not the types of its properties to determine its type. --- src/compiler/checker.ts | 10 ++++ .../typeFromContextualThisType.symbols | 40 ++++++++++++++++ .../typeFromContextualThisType.types | 48 +++++++++++++++++++ .../salsa/typeFromContextualThisType.ts | 20 ++++++++ 4 files changed, 118 insertions(+) create mode 100644 tests/baselines/reference/typeFromContextualThisType.symbols create mode 100644 tests/baselines/reference/typeFromContextualThisType.types create mode 100644 tests/cases/conformance/salsa/typeFromContextualThisType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db02365fd17..070a5c2650b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16140,6 +16140,16 @@ namespace ts { return true; } case SpecialPropertyAssignmentKind.ThisProperty: + if (!binaryExpression.symbol || + binaryExpression.symbol.valueDeclaration && !!getJSDocTypeTag(binaryExpression.symbol.valueDeclaration)) { + return true; + } + const thisAccess = binaryExpression.left as PropertyAccessExpression; + if (!isObjectLiteralMethod(getThisContainer(thisAccess.expression, /*includeArrowFunctions*/ false))) { + return false; + } + const thisType = checkThisExpression(thisAccess.expression); + return thisType && !!getPropertyOfType(thisType, thisAccess.name.escapedText); case SpecialPropertyAssignmentKind.ModuleExports: return !binaryExpression.symbol || binaryExpression.symbol.valueDeclaration && !!getJSDocTypeTag(binaryExpression.symbol.valueDeclaration); default: diff --git a/tests/baselines/reference/typeFromContextualThisType.symbols b/tests/baselines/reference/typeFromContextualThisType.symbols new file mode 100644 index 00000000000..c243123491d --- /dev/null +++ b/tests/baselines/reference/typeFromContextualThisType.symbols @@ -0,0 +1,40 @@ +=== tests/cases/conformance/salsa/bug25926.js === +/** @type {{ a(): void; b?(n: number): number; }} */ +const o1 = { +>o1 : Symbol(o1, Decl(bug25926.js, 1, 5)) + + a() { +>a : Symbol(a, Decl(bug25926.js, 1, 12)) + + this.b = n => n; +>this.b : Symbol(b, Decl(bug25926.js, 0, 23)) +>this : Symbol(__type, Decl(bug25926.js, 0, 11)) +>b : Symbol(b, Decl(bug25926.js, 2, 9)) +>n : Symbol(n, Decl(bug25926.js, 3, 16)) +>n : Symbol(n, Decl(bug25926.js, 3, 16)) + } +}; + +/** @type {{ d(): void; e?(n: number): number; f?(n: number): number; g?: number }} */ +const o2 = { +>o2 : Symbol(o2, Decl(bug25926.js, 8, 5)) + + d() { +>d : Symbol(d, Decl(bug25926.js, 8, 12)) + + this.e = this.f = m => this.g || m; +>this.e : Symbol(e, Decl(bug25926.js, 7, 23)) +>this : Symbol(__type, Decl(bug25926.js, 7, 11)) +>e : Symbol(e, Decl(bug25926.js, 9, 9)) +>this.f : Symbol(f, Decl(bug25926.js, 7, 46)) +>this : Symbol(__type, Decl(bug25926.js, 7, 11)) +>f : Symbol(f, Decl(bug25926.js, 10, 16)) +>m : Symbol(m, Decl(bug25926.js, 10, 25)) +>this.g : Symbol(g, Decl(bug25926.js, 7, 69)) +>this : Symbol(__type, Decl(bug25926.js, 7, 11)) +>g : Symbol(g, Decl(bug25926.js, 7, 69)) +>m : Symbol(m, Decl(bug25926.js, 10, 25)) + } +}; + + diff --git a/tests/baselines/reference/typeFromContextualThisType.types b/tests/baselines/reference/typeFromContextualThisType.types new file mode 100644 index 00000000000..fc6e3961800 --- /dev/null +++ b/tests/baselines/reference/typeFromContextualThisType.types @@ -0,0 +1,48 @@ +=== tests/cases/conformance/salsa/bug25926.js === +/** @type {{ a(): void; b?(n: number): number; }} */ +const o1 = { +>o1 : { a(): void; } +>{ a() { this.b = n => n; }} : { a(): void; } + + a() { +>a : () => void + + this.b = n => n; +>this.b = n => n : (n: number) => number +>this.b : ((n: number) => number) | undefined +>this : { a(): void; } +>b : ((n: number) => number) | undefined +>n => n : (n: number) => number +>n : number +>n : number + } +}; + +/** @type {{ d(): void; e?(n: number): number; f?(n: number): number; g?: number }} */ +const o2 = { +>o2 : { d(): void; g?: number | undefined; } +>{ d() { this.e = this.f = m => this.g || m; }} : { d(): void; } + + d() { +>d : () => void + + this.e = this.f = m => this.g || m; +>this.e = this.f = m => this.g || m : (m: number) => number +>this.e : ((n: number) => number) | undefined +>this : { d(): void; g?: number | undefined; } +>e : ((n: number) => number) | undefined +>this.f = m => this.g || m : (m: number) => number +>this.f : ((n: number) => number) | undefined +>this : { d(): void; g?: number | undefined; } +>f : ((n: number) => number) | undefined +>m => this.g || m : (m: number) => number +>m : number +>this.g || m : number +>this.g : number | undefined +>this : { d(): void; g?: number | undefined; } +>g : number | undefined +>m : number + } +}; + + diff --git a/tests/cases/conformance/salsa/typeFromContextualThisType.ts b/tests/cases/conformance/salsa/typeFromContextualThisType.ts new file mode 100644 index 00000000000..062b238eb8d --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromContextualThisType.ts @@ -0,0 +1,20 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @strict: true +// @Filename: bug25926.js + +/** @type {{ a(): void; b?(n: number): number; }} */ +const o1 = { + a() { + this.b = n => n; + } +}; + +/** @type {{ d(): void; e?(n: number): number; f?(n: number): number; g?: number }} */ +const o2 = { + d() { + this.e = this.f = m => this.g || m; + } +}; + From d21c0783633680be1ddbc2d73db52e094ab3fa02 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Wed, 15 Aug 2018 16:19:54 -0700 Subject: [PATCH 097/163] Test for existence of diagnostic when running tests --- src/testRunner/unittests/convertToAsyncFunction.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index f39b8080ed2..f3bdc889c34 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -362,11 +362,11 @@ interface Array {}` const diagnostics = languageService.getSuggestionDiagnostics(f.path); const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === description.message); - assert.isNotNull(diagnostic); + assert.exists(diagnostic); const actions = codefix.getFixes(context); const action = find(actions, action => action.description === description.message)!; - assert.isNotNull(action); + assert.exists(action); const data: string[] = []; data.push(`// ==ORIGINAL==`); From cc4e1f833e1d15535e6aff11f12fa13973c9728f Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Thu, 16 Aug 2018 08:53:48 -0700 Subject: [PATCH 098/163] Look for correct description --- src/testRunner/unittests/convertToAsyncFunction.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index f3bdc889c34..a1e8169e45d 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -319,7 +319,7 @@ interface String { charAt: any; } interface Array {}` }; - function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) { + function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, diagnosticDescription: DiagnosticMessage, codeFixDescription: DiagnosticMessage, includeLib?: boolean) { const t = getTest(text); const selectionRange = t.ranges.get("selection")!; if (!selectionRange) { @@ -361,11 +361,11 @@ interface Array {}` }; const diagnostics = languageService.getSuggestionDiagnostics(f.path); - const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === description.message); + const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === diagnosticDescription.message); assert.exists(diagnostic); const actions = codefix.getFixes(context); - const action = find(actions, action => action.description === description.message)!; + const action = find(actions, action => action.description === codeFixDescription.message)!; assert.exists(action); const data: string[] = []; @@ -380,7 +380,7 @@ interface Array {}` const diagProgram = makeProgram({ path, content: newText }, includeLib)!; assert.isFalse(hasSyntacticDiagnostics(diagProgram)); - Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, data.join(newLineCharacter)); + Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, () => data.join(newLineCharacter)); } function makeProgram(f: { path: string, content: string }, includeLib?: boolean) { @@ -1182,7 +1182,7 @@ function [#|f|]() { }); function _testConvertToAsyncFunction(caption: string, text: string) { - testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", Diagnostics.Convert_to_async_function, /*includeLib*/ true); + testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", Diagnostics.This_may_be_converted_to_an_async_function, Diagnostics.Convert_to_async_function, /*includeLib*/ true); } function _testConvertToAsyncFunctionFailed(caption: string, text: string) { From 158f0b0c0b9f7a14b4af10041c033418ce96e61a Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 14:28:11 -0700 Subject: [PATCH 099/163] Allow codefix to apply to function expression in variable declaration --- src/services/codefixes/convertToAsyncFunction.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 195586c6b6e..1650baac0ea 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -42,7 +42,16 @@ namespace ts.codefix { function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void { // get the function declaration - returns a promise - const functionToConvert: FunctionLikeDeclaration = getContainingFunction(getTokenAtPosition(sourceFile, position)) as FunctionLikeDeclaration; + const tokenAtPosition = getTokenAtPosition(sourceFile, position); + let functionToConvert: FunctionLikeDeclaration; + if (isIdentifier(tokenAtPosition) && isVariableDeclaration(tokenAtPosition.parent) && + tokenAtPosition.parent.initializer && isFunctionLikeDeclaration(tokenAtPosition.parent.initializer)) { + functionToConvert = tokenAtPosition.parent.initializer; + } + else { + functionToConvert = getContainingFunction(getTokenAtPosition(sourceFile, position)) as FunctionLikeDeclaration; + } + if (!functionToConvert) { return; } From 3ad6a66e69bc31d780eb1bef19dbdbf2f70c2893 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 14:28:58 -0700 Subject: [PATCH 100/163] Add tests and validate diagnostic spans --- .../unittests/convertToAsyncFunction.ts | 16 ++++++++++++++++ ...tToAsyncFunction_ArrowFunctionNoAnnotation.js | 11 +++++++++++ ...tToAsyncFunction_ArrowFunctionNoAnnotation.ts | 11 +++++++++++ ...oAsyncFunction_basicNoReturnTypeAnnotation.js | 11 +++++++++++ ...oAsyncFunction_basicNoReturnTypeAnnotation.ts | 11 +++++++++++ ...rtToAsyncFunction_simpleFunctionExpression.js | 12 ++++++++++++ ...rtToAsyncFunction_simpleFunctionExpression.ts | 12 ++++++++++++ 7 files changed, 84 insertions(+) create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.js create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.ts create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.js create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.ts create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.js create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.ts diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index a1e8169e45d..186b9059a3d 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -363,6 +363,8 @@ interface Array {}` const diagnostics = languageService.getSuggestionDiagnostics(f.path); const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === diagnosticDescription.message); assert.exists(diagnostic); + assert.equal(diagnostic!.start, context.span.start); + assert.equal(diagnostic!.length, context.span.length); const actions = codefix.getFixes(context); const action = find(actions, action => action.description === codeFixDescription.message)!; @@ -423,6 +425,10 @@ interface Array {}` _testConvertToAsyncFunction("convertToAsyncFunction_basic", ` function [#|f|](): Promise{ return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +}`); + _testConvertToAsyncFunction("convertToAsyncFunction_basicNoReturnTypeAnnotation", ` +function [#|f|]() { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); }`); _testConvertToAsyncFunction("convertToAsyncFunction_basicWithComments", ` function [#|f|](): Promise{ @@ -436,6 +442,10 @@ function [#|f|](): Promise{ _testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunction", ` [#|():Promise => {|] return fetch('https://typescriptlang.org').then(result => console.log(result)); +}`); + _testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunctionNoAnnotation", ` +[#|() => {|] + return fetch('https://typescriptlang.org').then(result => console.log(result)); }`); _testConvertToAsyncFunction("convertToAsyncFunction_Catch", ` function [#|f|]():Promise { @@ -1178,6 +1188,12 @@ function [#|f|]() { } `); + _testConvertToAsyncFunction("convertToAsyncFunction_simpleFunctionExpression", ` +const [#|foo|] = function () { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} +`); + }); diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.js b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.js new file mode 100644 index 00000000000..500d546971b --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.js @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +/*[#|*/() => {/*|]*/ + return fetch('https://typescriptlang.org').then(result => console.log(result)); +} +// ==ASYNC FUNCTION::Convert to async function== + +async () => { + const result = await fetch('https://typescriptlang.org'); + return console.log(result); +} \ No newline at end of file diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.ts b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.ts new file mode 100644 index 00000000000..500d546971b --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.ts @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +/*[#|*/() => {/*|]*/ + return fetch('https://typescriptlang.org').then(result => console.log(result)); +} +// ==ASYNC FUNCTION::Convert to async function== + +async () => { + const result = await fetch('https://typescriptlang.org'); + return console.log(result); +} \ No newline at end of file diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.js b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.js new file mode 100644 index 00000000000..8aec78c6670 --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.js @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +function /*[#|*/f/*|]*/() { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} +// ==ASYNC FUNCTION::Convert to async function== + +async function f() { + const result = await fetch('https://typescriptlang.org'); + console.log(result); +} \ No newline at end of file diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.ts b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.ts new file mode 100644 index 00000000000..8aec78c6670 --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.ts @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +function /*[#|*/f/*|]*/() { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} +// ==ASYNC FUNCTION::Convert to async function== + +async function f() { + const result = await fetch('https://typescriptlang.org'); + console.log(result); +} \ No newline at end of file diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.js b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.js new file mode 100644 index 00000000000..a92497ca937 --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.js @@ -0,0 +1,12 @@ +// ==ORIGINAL== + +const /*[#|*/foo/*|]*/ = function () { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} + +// ==ASYNC FUNCTION::Convert to async function== + +const foo = async function () { + const result = await fetch('https://typescriptlang.org'); + console.log(result); +} diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.ts b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.ts new file mode 100644 index 00000000000..a92497ca937 --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.ts @@ -0,0 +1,12 @@ +// ==ORIGINAL== + +const /*[#|*/foo/*|]*/ = function () { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} + +// ==ASYNC FUNCTION::Convert to async function== + +const foo = async function () { + const result = await fetch('https://typescriptlang.org'); + console.log(result); +} From 97e539339ddf175269b223fbbef7523aa791d6a0 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 14:37:09 -0700 Subject: [PATCH 101/163] Add comment explaining special casing --- src/services/codefixes/convertToAsyncFunction.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 1650baac0ea..6162e311266 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -44,6 +44,8 @@ namespace ts.codefix { // get the function declaration - returns a promise const tokenAtPosition = getTokenAtPosition(sourceFile, position); let functionToConvert: FunctionLikeDeclaration; + + // if the parent of a FunctionLikeDeclaration is a variable declaration, the convertToAsync diagnostic will be reported on the variable name if (isIdentifier(tokenAtPosition) && isVariableDeclaration(tokenAtPosition.parent) && tokenAtPosition.parent.initializer && isFunctionLikeDeclaration(tokenAtPosition.parent.initializer)) { functionToConvert = tokenAtPosition.parent.initializer; From bb892d951d59496566d38e117cad3cfe038569e8 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Wed, 29 Aug 2018 15:54:19 -0700 Subject: [PATCH 102/163] Use non-diagnostics-producing typechecker to get type --- src/services/suggestionDiagnostics.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 51a1701c351..167bcb6bbac 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -3,7 +3,7 @@ namespace ts { export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] { program.getSemanticDiagnostics(sourceFile, cancellationToken); const diags: DiagnosticWithLocation[] = []; - const checker = program.getDiagnosticsProducingTypeChecker(); + const checker = program.getTypeChecker(); if (sourceFile.commonJsModuleIndicator && (programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) && @@ -115,11 +115,12 @@ namespace ts { function addConvertToAsyncFunctionDiagnostics(node: FunctionLikeDeclaration, checker: TypeChecker, diags: DiagnosticWithLocation[]): void { - const functionType = node.type ? checker.getTypeFromTypeNode(node.type) : undefined; - if (isAsyncFunction(node) || !node.body || !functionType) { + if (isAsyncFunction(node) || !node.body) { return; } + const functionType = checker.getTypeAtLocation(node); + const callSignatures = checker.getSignaturesOfType(functionType, SignatureKind.Call); const returnType = callSignatures.length ? checker.getReturnTypeOfSignature(callSignatures[0]) : undefined; From f4765a6ea3435f8d6691325c7a19d3be4db243c8 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Fri, 24 Aug 2018 09:05:13 -0700 Subject: [PATCH 103/163] Fix error introduced by rebase --- src/testRunner/unittests/convertToAsyncFunction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index 186b9059a3d..99788e1310e 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -382,7 +382,7 @@ interface Array {}` const diagProgram = makeProgram({ path, content: newText }, includeLib)!; assert.isFalse(hasSyntacticDiagnostics(diagProgram)); - Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, () => data.join(newLineCharacter)); + Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, data.join(newLineCharacter)); } function makeProgram(f: { path: string, content: string }, includeLib?: boolean) { From 38a85cfbf47cf1b96077bbdb13cbbfc23cd0aa89 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 29 Aug 2018 15:47:52 -0700 Subject: [PATCH 104/163] Add test to verify #26669 where declaration output is incorrect when declaration flag is not set explicitly in options --- .../reference/declarationEmitWithComposite.js | 14 ++++++++++++++ .../reference/declarationEmitWithComposite.symbols | 10 ++++++++++ .../reference/declarationEmitWithComposite.types | 8 ++++++++ .../cases/compiler/declarationEmitWithComposite.ts | 13 +++++++++++++ 4 files changed, 45 insertions(+) create mode 100644 tests/baselines/reference/declarationEmitWithComposite.js create mode 100644 tests/baselines/reference/declarationEmitWithComposite.symbols create mode 100644 tests/baselines/reference/declarationEmitWithComposite.types create mode 100644 tests/cases/compiler/declarationEmitWithComposite.ts diff --git a/tests/baselines/reference/declarationEmitWithComposite.js b/tests/baselines/reference/declarationEmitWithComposite.js new file mode 100644 index 00000000000..ba6b838ac8f --- /dev/null +++ b/tests/baselines/reference/declarationEmitWithComposite.js @@ -0,0 +1,14 @@ +//// [test.ts] +interface Foo { + x: number; +} +export default Foo; + + +//// [/foo/out/test.js] +"use strict"; +exports.__esModule = true; + + +//// [/foo/out/test.d.ts] +export default Foo; diff --git a/tests/baselines/reference/declarationEmitWithComposite.symbols b/tests/baselines/reference/declarationEmitWithComposite.symbols new file mode 100644 index 00000000000..74f9fba394b --- /dev/null +++ b/tests/baselines/reference/declarationEmitWithComposite.symbols @@ -0,0 +1,10 @@ +=== /foo/test.ts === +interface Foo { +>Foo : Symbol(Foo, Decl(test.ts, 0, 0)) + + x: number; +>x : Symbol(Foo.x, Decl(test.ts, 0, 15)) +} +export default Foo; +>Foo : Symbol(Foo, Decl(test.ts, 0, 0)) + diff --git a/tests/baselines/reference/declarationEmitWithComposite.types b/tests/baselines/reference/declarationEmitWithComposite.types new file mode 100644 index 00000000000..489a84bb9f1 --- /dev/null +++ b/tests/baselines/reference/declarationEmitWithComposite.types @@ -0,0 +1,8 @@ +=== /foo/test.ts === +interface Foo { + x: number; +>x : number +} +export default Foo; +>Foo : Foo + diff --git a/tests/cases/compiler/declarationEmitWithComposite.ts b/tests/cases/compiler/declarationEmitWithComposite.ts new file mode 100644 index 00000000000..9d039ce2271 --- /dev/null +++ b/tests/cases/compiler/declarationEmitWithComposite.ts @@ -0,0 +1,13 @@ +// @composite: true +// @fullEmitPaths: true + +// @filename: /foo/tsconfig.json +{ + "compilerOptions": { "composite": true, "outDir": "out" } +} + +// @filename: /foo/test.ts +interface Foo { + x: number; +} +export default Foo; From 262fa3ac312f19c50d5966f76ec84e6aded15918 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 29 Aug 2018 16:16:01 -0700 Subject: [PATCH 105/163] Correctly mark visibile nodes when declaration isnt explicitly turned on but composite is true Fixes #26669 --- src/compiler/checker.ts | 4 ++-- tests/baselines/reference/declarationEmitWithComposite.js | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db02365fd17..5fc3f2b1ac2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26347,7 +26347,7 @@ namespace ts { function checkExportSpecifier(node: ExportSpecifier) { checkAliasSymbol(node); - if (compilerOptions.declaration) { + if (getEmitDeclarations(compilerOptions)) { collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true); } if (!node.parent.parent.moduleSpecifier) { @@ -26388,7 +26388,7 @@ namespace ts { if (node.expression.kind === SyntaxKind.Identifier) { markExportAsReferenced(node); - if (compilerOptions.declaration) { + if (getEmitDeclarations(compilerOptions)) { collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true); } } diff --git a/tests/baselines/reference/declarationEmitWithComposite.js b/tests/baselines/reference/declarationEmitWithComposite.js index ba6b838ac8f..3ccdf5c1ea1 100644 --- a/tests/baselines/reference/declarationEmitWithComposite.js +++ b/tests/baselines/reference/declarationEmitWithComposite.js @@ -11,4 +11,7 @@ exports.__esModule = true; //// [/foo/out/test.d.ts] +interface Foo { + x: number; +} export default Foo; From f78dc2ad11e0c8986f5238207525ff53c504b2d2 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 29 Aug 2018 16:18:56 -0700 Subject: [PATCH 106/163] importFixes: Only provide a fix using the best module specifier for a given module (#26738) --- src/compiler/checker.ts | 4 +-- src/compiler/moduleSpecifiers.ts | 26 +++++++------------ src/services/codefixes/importFixes.ts | 11 ++++---- .../importNameCodeFixNewImportBaseUrl0.ts | 3 --- .../importNameCodeFixNewImportBaseUrl1.ts | 5 +--- .../importNameCodeFixNewImportBaseUrl2.ts | 3 --- .../importNameCodeFixNewImportPaths0.ts | 5 +--- .../importNameCodeFixNewImportPaths1.ts | 5 +--- .../importNameCodeFixNewImportPaths2.ts | 5 +--- ...NameCodeFixNewImportPaths_withExtension.ts | 5 +--- ...deFixNewImportPaths_withLeadingDotSlash.ts | 5 +--- ...ixNewImportPaths_withParentRelativePath.ts | 5 +--- .../importNameCodeFixNewImportTypeRoots1.ts | 5 +--- .../importNameCodeFix_fromPathMapping.ts | 7 ++--- .../importNameCodeFix_preferBaseUrl.ts | 5 +--- .../fourslash/importNameCodeFix_rootDirs.ts | 2 +- 16 files changed, 29 insertions(+), 72 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 69f2beca89f..7b7fea4efbd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3933,7 +3933,7 @@ namespace ts { // specifier preference const { moduleResolverHost } = context.tracker; const specifierCompilerOptions = isBundle ? { ...compilerOptions, baseUrl: moduleResolverHost.getCommonSourceDirectory() } : compilerOptions; - specifier = first(first(moduleSpecifiers.getModuleSpecifiers( + specifier = first(moduleSpecifiers.getModuleSpecifiers( symbol, specifierCompilerOptions, contextFile, @@ -3941,7 +3941,7 @@ namespace ts { host.getSourceFiles(), { importModuleSpecifierPreference: isBundle ? "non-relative" : "relative" }, host.redirectTargetsMap, - ))); + )); links.specifierCache = links.specifierCache || createMap(); links.specifierCache.set(contextFile.path, specifier); } diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 2e4d1ec86de..eda480d032c 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -75,10 +75,10 @@ namespace ts.moduleSpecifiers { const info = getInfo(importingSourceFileName, host); const modulePaths = getAllModulePaths(files, importingSourceFileName, toFileName, info.getCanonicalFileName, host, redirectTargetsMap); return firstDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions)) || - first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); + getLocalModuleSpecifier(toFileName, info, compilerOptions, preferences); } - // For each symlink/original for a module, returns a list of ways to import that file. + // Returns an import for each symlink and for the realpath. export function getModuleSpecifiers( moduleSymbol: Symbol, compilerOptions: CompilerOptions, @@ -87,9 +87,9 @@ namespace ts.moduleSpecifiers { files: ReadonlyArray, userPreferences: UserPreferences, redirectTargetsMap: RedirectTargetsMap, - ): ReadonlyArray> { + ): ReadonlyArray { const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); - if (ambient) return [[ambient]]; + if (ambient) return [ambient]; const info = getInfo(importingSourceFile.path, host); const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol)); @@ -97,8 +97,7 @@ namespace ts.moduleSpecifiers { const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile); const global = mapDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions)); - return global.length ? global.map(g => [g]) : modulePaths.map(moduleFileName => - getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences)); + return global.length ? global : modulePaths.map(moduleFileName => getLocalModuleSpecifier(moduleFileName, info, compilerOptions, preferences)); } interface Info { @@ -112,18 +111,18 @@ namespace ts.moduleSpecifiers { return { getCanonicalFileName, sourceDirectory }; } - function getLocalModuleSpecifiers(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): ReadonlyArray { + function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): string { const { baseUrl, paths, rootDirs } = compilerOptions; const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) || removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions); if (!baseUrl || relativePreference === RelativePreference.Relative) { - return [relativePath]; + return relativePath; } const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); if (!relativeToBaseUrl) { - return [relativePath]; + return relativePath; } const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions); @@ -131,18 +130,13 @@ namespace ts.moduleSpecifiers { const nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths; if (relativePreference === RelativePreference.NonRelative) { - return [nonRelative]; + return nonRelative; } if (relativePreference !== RelativePreference.Auto) Debug.assertNever(relativePreference); - if (isPathRelativeToParent(nonRelative)) { - return [relativePath]; - } - // Prefer a relative import over a baseUrl import if it has fewer components. - const relativeFirst = countPathComponents(relativePath) < countPathComponents(nonRelative); - return relativeFirst ? [relativePath, nonRelative] : [nonRelative, relativePath]; + return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative; } function countPathComponents(path: string): number { diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 7ff5d30c954..963d1cd64f2 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -283,14 +283,13 @@ namespace ts.codefix { preferences: UserPreferences, ): ReadonlyArray { const isJs = isSourceFileJavaScript(sourceFile); - const choicesForEachExportingModule = flatMap>(moduleSymbols, ({ moduleSymbol, importKind, exportedSymbolIsTypeOnly }) => { - const modulePathsGroups = moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences, program.redirectTargetsMap); - return modulePathsGroups.map(group => group.map((moduleSpecifier): FixAddNewImport | FixUseImportType => + const choicesForEachExportingModule = flatMap(moduleSymbols, ({ moduleSymbol, importKind, exportedSymbolIsTypeOnly }) => + moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences, program.redirectTargetsMap) + .map((moduleSpecifier): FixAddNewImport | FixUseImportType => // `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types. exportedSymbolIsTypeOnly && isJs ? { kind: ImportFixKind.ImportType, moduleSpecifier, position: Debug.assertDefined(position) } : { kind: ImportFixKind.AddNew, moduleSpecifier, importKind })); - }); - // Sort to keep the shortest paths first, but keep [relativePath, importRelativeToBaseUrl] groups together - return flatten(choicesForEachExportingModule.sort((a, b) => first(a).moduleSpecifier.length - first(b).moduleSpecifier.length)); + // Sort to keep the shortest paths first + return choicesForEachExportingModule.sort((a, b) => a.moduleSpecifier.length - b.moduleSpecifier.length); } function getFixesForAddImport( diff --git a/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl0.ts b/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl0.ts index fba8875a610..c30bee2b993 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl0.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl0.ts @@ -15,8 +15,5 @@ verify.importFixAtPosition([ `import { f1 } from "b"; -f1();`, -`import { f1 } from "./a/b"; - f1();`, ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl1.ts b/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl1.ts index fa28dea5fe2..285a2e6ff53 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl1.ts @@ -14,14 +14,11 @@ ////[|f1/*0*/();|] goTo.file("/a/b/y.ts"); -// Order the local import first because it's simpler. +// Use the local import because it's simpler. verify.importFixAtPosition([ `import { f1 } from "./x"; f1();`, -`import { f1 } from "b/x"; - -f1();` ]); verify.importFixAtPosition([ diff --git a/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl2.ts b/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl2.ts index 8fc9a97afe3..1923251d10e 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl2.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportBaseUrl2.ts @@ -19,9 +19,6 @@ verify.importFixAtPosition([ `import { f1 } from "b/x"; f1();`, -`import { f1 } from "../b/x"; - -f1();` ]); verify.importFixAtPosition([ diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths0.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths0.ts index 90f21703326..bd3fd9a84b3 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths0.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths0.ts @@ -18,8 +18,5 @@ verify.importFixAtPosition([ `import { foo } from "a"; -foo();`, -`import { foo } from "./folder_a/f2"; - -foo();`, +foo();` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths1.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths1.ts index 041ef40380d..5ac195e9ab4 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths1.ts @@ -18,8 +18,5 @@ verify.importFixAtPosition([ `import { foo } from "b/f2"; -foo();`, -`import { foo } from "./folder_b/f2"; - -foo();`, +foo();` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths2.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths2.ts index 63aabfc4e5f..33b8d9330be 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths2.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths2.ts @@ -24,8 +24,5 @@ verify.importFixAtPosition([ `import { foo } from "b"; -foo();`, -`import { foo } from "./folder_b"; - -foo();`, +foo();` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts index 2275758cda1..c383b09862e 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withExtension.ts @@ -19,8 +19,5 @@ verify.importFixAtPosition([ `import { foo } from "foo"; -foo`, -`import { foo } from "./thisHasPathMapping"; - -foo`, +foo` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts index acf1fa369ef..f29932eed73 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withLeadingDotSlash.ts @@ -19,8 +19,5 @@ verify.importFixAtPosition([ `import { foo } from "foo"; -foo`, -`import { foo } from "./thisHasPathMapping"; - -foo`, +foo` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts index 816fb309a08..4bd938ae0b9 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportPaths_withParentRelativePath.ts @@ -19,8 +19,5 @@ verify.importFixAtPosition([ `import { foo } from "foo"; -foo`, -`import { foo } from "../thisHasPathMapping"; - -foo`, +foo` ]); diff --git a/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots1.ts b/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots1.ts index 9743d164a9c..f4aa86ca7d7 100644 --- a/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots1.ts +++ b/tests/cases/fourslash/importNameCodeFixNewImportTypeRoots1.ts @@ -16,12 +16,9 @@ //// } //// } -// "typeRoots" does not affect module resolution. Importing from "random" would be a compile error. +// "typeRoots" does not affect module resolution, though "baseUrl" does. Importing from "random" would be a compile error. verify.importFixAtPosition([ `import { foo } from "types/random"; foo();`, -`import { foo } from "../types/random"; - -foo();` ]); diff --git a/tests/cases/fourslash/importNameCodeFix_fromPathMapping.ts b/tests/cases/fourslash/importNameCodeFix_fromPathMapping.ts index 35a42d8cbf1..4affd5e33ba 100644 --- a/tests/cases/fourslash/importNameCodeFix_fromPathMapping.ts +++ b/tests/cases/fourslash/importNameCodeFix_fromPathMapping.ts @@ -3,7 +3,7 @@ // @Filename: /a.ts ////export const foo = 0; -// @Filename: /b.ts +// @Filename: /x/y.ts ////foo; // @Filename: /tsconfig.json @@ -16,11 +16,8 @@ //// } ////} -goTo.file("/b.ts"); +goTo.file("/x/y.ts"); verify.importFixAtPosition([ -`import { foo } from "./a"; - -foo;`, `import { foo } from "@root/a"; foo;`, diff --git a/tests/cases/fourslash/importNameCodeFix_preferBaseUrl.ts b/tests/cases/fourslash/importNameCodeFix_preferBaseUrl.ts index 5d2d861550e..c2aaef471a4 100644 --- a/tests/cases/fourslash/importNameCodeFix_preferBaseUrl.ts +++ b/tests/cases/fourslash/importNameCodeFix_preferBaseUrl.ts @@ -13,8 +13,5 @@ goTo.file("/src/d0/d1/d2/file.ts"); verify.importFixAtPosition([ `import { foo } from "d0/a"; -foo;`, -`import { foo } from "../../a"; - -foo;`, +foo;` ]); diff --git a/tests/cases/fourslash/importNameCodeFix_rootDirs.ts b/tests/cases/fourslash/importNameCodeFix_rootDirs.ts index d19bb8f4fa5..1367f53b9f3 100644 --- a/tests/cases/fourslash/importNameCodeFix_rootDirs.ts +++ b/tests/cases/fourslash/importNameCodeFix_rootDirs.ts @@ -18,6 +18,6 @@ const nonRelative = 'import { a } from "a";\n\na;'; const relative = nonRelative.replace('"a"', '"./a"'); goTo.file("/b.ts"); -verify.importFixAtPosition([nonRelative, relative]); +verify.importFixAtPosition([nonRelative]); verify.importFixAtPosition([nonRelative], undefined, { importModuleSpecifierPreference: "non-relative" }); verify.importFixAtPosition([relative], undefined, { importModuleSpecifierPreference: "relative" }); From cea49dfb0d2a8d1bb440c287374c3401f67eed84 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 29 Aug 2018 16:38:42 -0700 Subject: [PATCH 107/163] Completion for tuple index doesn't need to include quotes (#26750) --- src/services/completions.ts | 3 +++ tests/cases/fourslash/completionsTuple.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/cases/fourslash/completionsTuple.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index a82c4e02882..1e74ea3bbf1 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -264,6 +264,9 @@ namespace ts.Completions { } function quote(text: string, preferences: UserPreferences): string { + if (/^\d+$/.test(text)) { + return text; + } const quoted = JSON.stringify(text); switch (preferences.quotePreference) { case undefined: diff --git a/tests/cases/fourslash/completionsTuple.ts b/tests/cases/fourslash/completionsTuple.ts new file mode 100644 index 00000000000..9ce11b53d99 --- /dev/null +++ b/tests/cases/fourslash/completionsTuple.ts @@ -0,0 +1,18 @@ +/// + +////declare const x: [number, number]; +////x[|./**/|]; + +const replacementSpan = test.ranges()[0]; +verify.completions({ + marker: "", + includes: [ + { name: "0", insertText: '[0]', replacementSpan }, + { name: "1", insertText: '[1]', replacementSpan }, + "length", + ], + excludes: "2", + preferences: { + includeInsertTextCompletions: true, + }, +}); From d37caf1c0d838323c55c97b3e24929d119c9bcd2 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 29 Aug 2018 17:43:22 -0700 Subject: [PATCH 108/163] Remove unnecessary `getContainingClass` calls (#26753) --- src/compiler/checker.ts | 13 +++++++------ src/compiler/utilities.ts | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7b7fea4efbd..afd9b6d5b34 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27344,12 +27344,10 @@ namespace ts { } if (isPartOfTypeNode(node)) { - let typeFromTypeNode = getTypeFromTypeNode(node); + const typeFromTypeNode = getTypeFromTypeNode(node); if (isExpressionWithTypeArgumentsInClassImplementsClause(node)) { - const containingClass = getContainingClass(node)!; - const classType = getTypeOfNode(containingClass) as InterfaceType; - typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType); + return getTypeWithThisArgument(typeFromTypeNode, getTypeOfClassContainingHeritageClause(node).thisType); } return typeFromTypeNode; @@ -27362,8 +27360,7 @@ namespace ts { if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) { // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the // extends clause of a class. We handle that case here. - const classNode = getContainingClass(node)!; - const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode)) as InterfaceType; + const classType = getTypeOfClassContainingHeritageClause(node); const baseType = firstOrUndefined(getBaseTypes(classType)); return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType; } @@ -27405,6 +27402,10 @@ namespace ts { return errorType; } + function getTypeOfClassContainingHeritageClause(node: ExpressionWithTypeArguments): InterfaceType { + return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node.parent.parent)); + } + // Gets the type of object literal or array literal of destructuring assignment. // { a } from // for ( { a } of elems) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0e92bad7f55..6ecc80aaa3f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3743,7 +3743,7 @@ namespace ts { return false; } - export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean { + export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): node is ExpressionWithTypeArguments { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } From d604199602aeec7a43ba1d6955ccdb5c5d9de35f Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 30 Aug 2018 04:10:39 +0000 Subject: [PATCH 109/163] LEGO: check in for master to temporary branch. --- .../diagnosticMessages/diagnosticMessages.generated.json.lcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index dc8079b6a53..cf26e2044e7 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -588,7 +588,7 @@ - + From c327ab40bce344ea7a58b4dc2d178bd5c3c0be1e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 30 Aug 2018 08:39:39 -0700 Subject: [PATCH 110/163] Make SymbolFlags.ObjectLiteral a Value (#26752) Previously it was a Type We couldn't think of a way to observe this change since object literals don't merge with anything. Ideas? --- src/compiler/types.ts | 4 +-- .../reference/api/tsserverlibrary.d.ts | 26 +++++++++---------- tests/baselines/reference/api/typescript.d.ts | 26 +++++++++---------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 64a00f78ced..5ed722a4571 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3441,8 +3441,8 @@ namespace ts { Enum = RegularEnum | ConstEnum, Variable = FunctionScopedVariable | BlockScopedVariable, - Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | JSContainer, - Type = Class | Interface | Enum | EnumMember | TypeLiteral | ObjectLiteral | TypeParameter | TypeAlias | JSContainer, + Value = Variable | Property | EnumMember | ObjectLiteral | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | JSContainer, + Type = Class | Interface | Enum | EnumMember | TypeLiteral | TypeParameter | TypeAlias | JSContainer, Namespace = ValueModule | NamespaceModule | Enum, Module = ValueModule | NamespaceModule, Accessor = GetAccessor | SetAccessor, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 911fd328f3b..7d24aab8345 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2060,28 +2060,28 @@ declare namespace ts { ModuleExports = 134217728, Enum = 384, Variable = 3, - Value = 67216319, - Type = 67901928, + Value = 67220415, + Type = 67897832, Namespace = 1920, Module = 1536, Accessor = 98304, - FunctionScopedVariableExcludes = 67216318, - BlockScopedVariableExcludes = 67216319, - ParameterExcludes = 67216319, + FunctionScopedVariableExcludes = 67220414, + BlockScopedVariableExcludes = 67220415, + ParameterExcludes = 67220415, PropertyExcludes = 0, EnumMemberExcludes = 68008959, - FunctionExcludes = 67215791, + FunctionExcludes = 67219887, ClassExcludes = 68008383, - InterfaceExcludes = 67901832, + InterfaceExcludes = 67897736, RegularEnumExcludes = 68008191, ConstEnumExcludes = 68008831, - ValueModuleExcludes = 67215503, + ValueModuleExcludes = 67219599, NamespaceModuleExcludes = 0, - MethodExcludes = 67208127, - GetAccessorExcludes = 67150783, - SetAccessorExcludes = 67183551, - TypeParameterExcludes = 67639784, - TypeAliasExcludes = 67901928, + MethodExcludes = 67212223, + GetAccessorExcludes = 67154879, + SetAccessorExcludes = 67187647, + TypeParameterExcludes = 67635688, + TypeAliasExcludes = 67897832, AliasExcludes = 2097152, ModuleMember = 2623475, ExportHasLocal = 944, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c12d797bea8..eaf566bb161 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2060,28 +2060,28 @@ declare namespace ts { ModuleExports = 134217728, Enum = 384, Variable = 3, - Value = 67216319, - Type = 67901928, + Value = 67220415, + Type = 67897832, Namespace = 1920, Module = 1536, Accessor = 98304, - FunctionScopedVariableExcludes = 67216318, - BlockScopedVariableExcludes = 67216319, - ParameterExcludes = 67216319, + FunctionScopedVariableExcludes = 67220414, + BlockScopedVariableExcludes = 67220415, + ParameterExcludes = 67220415, PropertyExcludes = 0, EnumMemberExcludes = 68008959, - FunctionExcludes = 67215791, + FunctionExcludes = 67219887, ClassExcludes = 68008383, - InterfaceExcludes = 67901832, + InterfaceExcludes = 67897736, RegularEnumExcludes = 68008191, ConstEnumExcludes = 68008831, - ValueModuleExcludes = 67215503, + ValueModuleExcludes = 67219599, NamespaceModuleExcludes = 0, - MethodExcludes = 67208127, - GetAccessorExcludes = 67150783, - SetAccessorExcludes = 67183551, - TypeParameterExcludes = 67639784, - TypeAliasExcludes = 67901928, + MethodExcludes = 67212223, + GetAccessorExcludes = 67154879, + SetAccessorExcludes = 67187647, + TypeParameterExcludes = 67635688, + TypeAliasExcludes = 67897832, AliasExcludes = 2097152, ModuleMember = 2623475, ExportHasLocal = 944, From 038f665171ffe59c2a483b4ef52c1390fb27ebbf Mon Sep 17 00:00:00 2001 From: Wenlu Wang Date: Thu, 30 Aug 2018 23:48:49 +0800 Subject: [PATCH 111/163] fix lookup regression again (#26762) * fix lookup regression again * add test case --- src/compiler/checker.ts | 2 +- ...meterInitializersForwardReferencing1.errors.txt | 2 ++ .../parameterInitializersForwardReferencing1.js | 5 +++++ ...arameterInitializersForwardReferencing1.symbols | 6 ++++++ .../parameterInitializersForwardReferencing1.types | 6 ++++++ ...rInitializersForwardReferencing1_es6.errors.txt | 2 ++ ...parameterInitializersForwardReferencing1_es6.js | 3 +++ ...eterInitializersForwardReferencing1_es6.symbols | 8 +++++++- ...ameterInitializersForwardReferencing1_es6.types | 14 ++++++++++---- .../parameterInitializersForwardReferencing1.ts | 2 ++ ...parameterInitializersForwardReferencing1_es6.ts | 2 ++ 11 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2ae4682b919..394a5a581cb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1212,7 +1212,7 @@ namespace ts { } if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.Variable) { // expression inside parameter will lookup as normal variable scope when targeting es2015+ - if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && !isParameterPropertyDeclaration(lastLocation) && result.valueDeclaration !== lastLocation) { + if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && !isParameterPropertyDeclaration(lastLocation) && result.valueDeclaration.pos > lastLocation.end) { useResult = false; } else if (result.flags & SymbolFlags.FunctionScopedVariable) { diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt index 94f4175f5e5..73f4f27d08b 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.errors.txt @@ -55,4 +55,6 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts(29 class Foo { constructor(public x = 12, public y = x) {} } + + function f8(foo1: string, bar = foo1) { } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.js b/tests/baselines/reference/parameterInitializersForwardReferencing1.js index bb3a4c87e69..bd2b62e4216 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.js +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.js @@ -34,6 +34,8 @@ function f7({[foo]: bar}: any[]) { class Foo { constructor(public x = 12, public y = x) {} } + +function f8(foo1: string, bar = foo1) { } //// [parameterInitializersForwardReferencing1.js] @@ -81,3 +83,6 @@ var Foo = /** @class */ (function () { } return Foo; }()); +function f8(foo1, bar) { + if (bar === void 0) { bar = foo1; } +} diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols index 10f94a2bd64..74b00fe04b8 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.symbols @@ -84,3 +84,9 @@ class Foo { >x : Symbol(x, Decl(parameterInitializersForwardReferencing1.ts, 33, 16)) } +function f8(foo1: string, bar = foo1) { } +>f8 : Symbol(f8, Decl(parameterInitializersForwardReferencing1.ts, 34, 1)) +>foo1 : Symbol(foo1, Decl(parameterInitializersForwardReferencing1.ts, 36, 12)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1.ts, 36, 25)) +>foo1 : Symbol(foo1, Decl(parameterInitializersForwardReferencing1.ts, 36, 12)) + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1.types b/tests/baselines/reference/parameterInitializersForwardReferencing1.types index d6eee6a9c30..2b80bfe87e0 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1.types @@ -92,3 +92,9 @@ class Foo { >x : number } +function f8(foo1: string, bar = foo1) { } +>f8 : (foo1: string, bar?: string) => void +>foo1 : string +>bar : string +>foo1 : string + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt index d84519e406e..90390fbe3a4 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -42,4 +42,6 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t class Foo { constructor(public x = 12, public y = x) {} } + + function f8(foo1: string, bar = foo1) { } \ No newline at end of file diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js index a5b00cfeb44..ecabb8ceba9 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.js @@ -34,6 +34,8 @@ function f7({[foo]: bar}: any[]) { class Foo { constructor(public x = 12, public y = x) {} } + +function f8(foo1: string, bar = foo1) { } //// [parameterInitializersForwardReferencing1_es6.js] @@ -67,3 +69,4 @@ class Foo { this.y = y; } } +function f8(foo1, bar = foo1) { } diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols index 3d678a021ba..c0d42ab8b11 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols @@ -42,7 +42,7 @@ function f4 (foo, bar = foo) { >f4 : Symbol(f4, Decl(parameterInitializersForwardReferencing1_es6.ts, 14, 1)) >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 13)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 17)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 13)) return bar >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 16, 17)) @@ -84,3 +84,9 @@ class Foo { >x : Symbol(x, Decl(parameterInitializersForwardReferencing1_es6.ts, 33, 16)) } +function f8(foo1: string, bar = foo1) { } +>f8 : Symbol(f8, Decl(parameterInitializersForwardReferencing1_es6.ts, 34, 1)) +>foo1 : Symbol(foo1, Decl(parameterInitializersForwardReferencing1_es6.ts, 36, 12)) +>bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 36, 25)) +>foo1 : Symbol(foo1, Decl(parameterInitializersForwardReferencing1_es6.ts, 36, 12)) + diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types index ca8ae55557e..009ec47ddb8 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types @@ -45,13 +45,13 @@ function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime } function f4 (foo, bar = foo) { ->f4 : (foo: any, bar?: string) => string +>f4 : (foo: any, bar?: any) => any +>foo : any +>bar : any >foo : any ->bar : string ->foo : string return bar ->bar : string +>bar : any } function f5 (a = a) { @@ -92,3 +92,9 @@ class Foo { >x : number } +function f8(foo1: string, bar = foo1) { } +>f8 : (foo1: string, bar?: string) => void +>foo1 : string +>bar : string +>foo1 : string + diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts index cf667840f20..a3b88150f4f 100644 --- a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1.ts @@ -33,3 +33,5 @@ function f7({[foo]: bar}: any[]) { class Foo { constructor(public x = 12, public y = x) {} } + +function f8(foo1: string, bar = foo1) { } diff --git a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts index 5643ea2cc0a..f83eb2dd34e 100644 --- a/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts +++ b/tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts @@ -35,3 +35,5 @@ function f7({[foo]: bar}: any[]) { class Foo { constructor(public x = 12, public y = x) {} } + +function f8(foo1: string, bar = foo1) { } From 20a2b0cadeb5147c9a5e608dff70a652533fa02f Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 30 Aug 2018 11:01:33 -0600 Subject: [PATCH 112/163] Ignore newline and asterisk when parsing JSDoc typedef (#26775) --- src/compiler/parser.ts | 2 +- .../reference/typedefTagWrapping.symbols | 23 ++++++++++++++++++ .../reference/typedefTagWrapping.types | 24 +++++++++++++++++++ .../conformance/jsdoc/typedefTagWrapping.ts | 20 ++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/typedefTagWrapping.symbols create mode 100644 tests/baselines/reference/typedefTagWrapping.types create mode 100644 tests/cases/conformance/jsdoc/typedefTagWrapping.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e9eb953d22a..b40648033de 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6856,7 +6856,7 @@ namespace ts { function parseTypedefTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocTypedefTag { const typeExpression = tryParseTypeExpression(); - skipWhitespace(); + skipWhitespaceOrAsterisk(); const typedefTag = createNode(SyntaxKind.JSDocTypedefTag, atToken.pos); typedefTag.atToken = atToken; diff --git a/tests/baselines/reference/typedefTagWrapping.symbols b/tests/baselines/reference/typedefTagWrapping.symbols new file mode 100644 index 00000000000..ec93da5a45b --- /dev/null +++ b/tests/baselines/reference/typedefTagWrapping.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/jsdoc/mod1.js === +/** + * @typedef {function(string): boolean} + * MyType + */ + +/** + * Tries to use a type whose name is on a different + * line than the typedef tag. + * @param {MyType} func The function to call. + * @param {string} arg The argument to call it with. + * @returns {boolean} The return. + */ +function callIt(func, arg) { +>callIt : Symbol(callIt, Decl(mod1.js, 0, 0)) +>func : Symbol(func, Decl(mod1.js, 12, 16)) +>arg : Symbol(arg, Decl(mod1.js, 12, 21)) + + return func(arg); +>func : Symbol(func, Decl(mod1.js, 12, 16)) +>arg : Symbol(arg, Decl(mod1.js, 12, 21)) +} + diff --git a/tests/baselines/reference/typedefTagWrapping.types b/tests/baselines/reference/typedefTagWrapping.types new file mode 100644 index 00000000000..8c92717d1a1 --- /dev/null +++ b/tests/baselines/reference/typedefTagWrapping.types @@ -0,0 +1,24 @@ +=== tests/cases/conformance/jsdoc/mod1.js === +/** + * @typedef {function(string): boolean} + * MyType + */ + +/** + * Tries to use a type whose name is on a different + * line than the typedef tag. + * @param {MyType} func The function to call. + * @param {string} arg The argument to call it with. + * @returns {boolean} The return. + */ +function callIt(func, arg) { +>callIt : (func: (arg0: string) => boolean, arg: string) => boolean +>func : (arg0: string) => boolean +>arg : string + + return func(arg); +>func(arg) : boolean +>func : (arg0: string) => boolean +>arg : string +} + diff --git a/tests/cases/conformance/jsdoc/typedefTagWrapping.ts b/tests/cases/conformance/jsdoc/typedefTagWrapping.ts new file mode 100644 index 00000000000..53cff6d02c0 --- /dev/null +++ b/tests/cases/conformance/jsdoc/typedefTagWrapping.ts @@ -0,0 +1,20 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: mod1.js + +/** + * @typedef {function(string): boolean} + * MyType + */ + +/** + * Tries to use a type whose name is on a different + * line than the typedef tag. + * @param {MyType} func The function to call. + * @param {string} arg The argument to call it with. + * @returns {boolean} The return. + */ +function callIt(func, arg) { + return func(arg); +} From bf6d265b97af74be3a87fdc4b73e0a2eb6cef9ba Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 30 Aug 2018 10:12:04 -0700 Subject: [PATCH 113/163] Add test for signaure help with recursive type Test for #26155 --- .../fourslash/signatureHelpInRecursiveType.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/cases/fourslash/signatureHelpInRecursiveType.ts diff --git a/tests/cases/fourslash/signatureHelpInRecursiveType.ts b/tests/cases/fourslash/signatureHelpInRecursiveType.ts new file mode 100644 index 00000000000..ca55be37b55 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpInRecursiveType.ts @@ -0,0 +1,18 @@ +/// + +////type Tail = +//// ((...args: T) => any) extends ((head: any, ...tail: infer R) => any) ? R : never; +//// +////type Reverse = _Reverse; +//// +////type _Reverse = { +//// 1: Result, +//// 0: _Reverse, 0>, +////}[Source extends [] ? 1 : 0]; +//// +////type Foo = Reverse<[0,/**/]>; + +verify.signatureHelp({ + marker: "", + text: "Reverse", +}); \ No newline at end of file From 496b18ef5e1187d03311b0f98772cf64c9637551 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 30 Aug 2018 11:38:34 -0700 Subject: [PATCH 114/163] Report file change detected only once when save takes place multiple times before timeout --- src/compiler/tsbuild.ts | 7 ++++++- src/testRunner/unittests/tsbuildWatchMode.ts | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 95beb65e28e..4ddda98a41f 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -507,6 +507,7 @@ namespace ts { const configFileCache = createConfigFileCache(host); let context = createBuildContext(defaultOptions); let timerToBuildInvalidatedProject: any; + let reportFileChangeDetected = false; const existingWatchersForWildcards = createMap(); return { @@ -584,7 +585,7 @@ namespace ts { } function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName) { - reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation); + reportFileChangeDetected = true; invalidateProject(resolved); scheduleBuildInvalidatedProject(); } @@ -817,6 +818,10 @@ namespace ts { function buildInvalidatedProject() { timerToBuildInvalidatedProject = undefined; + if (reportFileChangeDetected) { + reportFileChangeDetected = false; + reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation); + } const buildProject = context.getNextInvalidatedProject(); buildSomeProjects(p => p === buildProject); if (context.hasPendingInvalidatedProjects()) { diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts index b7884350061..daa1276e023 100644 --- a/src/testRunner/unittests/tsbuildWatchMode.ts +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -112,9 +112,22 @@ export class someClass { }`); // Another change requeues and builds it verifyChange(core[1].content); + // Two changes together report only single time message: File change detected. Starting incremental compilation... + const outputFileStamps = getOutputFileStamps(host); + const change1 = `${core[1].content} +export class someClass { }`; + host.writeFile(core[1].path, change1); + host.writeFile(core[1].path, `${change1} +export class someClass2 { }`); + verifyChangeAfterTimeout(outputFileStamps); + function verifyChange(coreContent: string) { const outputFileStamps = getOutputFileStamps(host); host.writeFile(core[1].path, coreContent); + verifyChangeAfterTimeout(outputFileStamps); + } + + function verifyChangeAfterTimeout(outputFileStamps: OutputFileStamp[]) { host.checkTimeoutQueueLengthAndRun(1); // Builds core const changedCore = getOutputFileStamps(host); verifyChangedFiles(changedCore, outputFileStamps, [ From 316739e1c0284d580fecbaab4bfa9d92eedcf357 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 30 Aug 2018 12:46:29 -0700 Subject: [PATCH 115/163] Exclude generic types from weak object checks --- src/compiler/checker.ts | 65 ++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db02365fd17..2bd5d40bffa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11185,13 +11185,10 @@ namespace ts { } } - if (relation !== comparableRelation && - !(source.flags & TypeFlags.Union) && - !(target.flags & TypeFlags.Union) && - !isIntersectionConstituent && - source !== globalObjectType && + if (relation !== comparableRelation && !isIntersectionConstituent && + source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType && + target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) && (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source)) && - isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { const calls = getSignaturesOfType(source, SignatureKind.Call); @@ -12011,34 +12008,6 @@ namespace ts { return result; } - /** - * A type is 'weak' if it is an object type with at least one optional property - * and no required properties, call/construct signatures or index signatures - */ - function isWeakType(type: Type): boolean { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type); - return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && - !resolved.stringIndexInfo && !resolved.numberIndexInfo && - resolved.properties.length > 0 && - every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); - } - if (type.flags & TypeFlags.Intersection) { - return every((type).types, isWeakType); - } - return false; - } - - function hasCommonProperties(source: Type, target: Type) { - const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); - for (const prop of getPropertiesOfType(source)) { - if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { - return true; - } - } - return false; - } - function propertiesIdenticalTo(source: Type, target: Type): Ternary { if (!(source.flags & TypeFlags.Object && target.flags & TypeFlags.Object)) { return Ternary.False; @@ -12283,6 +12252,34 @@ namespace ts { } } + /** + * A type is 'weak' if it is an object type with at least one optional property + * and no required properties, call/construct signatures or index signatures + */ + function isWeakType(type: Type): boolean { + if (type.flags & TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type); + return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && + !resolved.stringIndexInfo && !resolved.numberIndexInfo && + resolved.properties.length > 0 && + every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); + } + if (type.flags & TypeFlags.Intersection) { + return every((type).types, isWeakType); + } + return false; + } + + function hasCommonProperties(source: Type, target: Type) { + const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes); + for (const prop of getPropertiesOfType(source)) { + if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { + return true; + } + } + return false; + } + // Return a type reference where the source type parameter is replaced with the target marker // type, and flag the result as a marker type reference. function getMarkerTypeReference(type: GenericType, source: TypeParameter, target: Type) { From 1fb6f11a88526673541938be62d00bcf20722625 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 30 Aug 2018 12:46:40 -0700 Subject: [PATCH 116/163] Accept new baselines --- .../reference/infiniteConstraints.errors.txt | 18 +++++++++++++++++- .../reference/infiniteConstraints.types | 16 ++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/tests/baselines/reference/infiniteConstraints.errors.txt b/tests/baselines/reference/infiniteConstraints.errors.txt index 387b0daac68..7cc00a98a9e 100644 --- a/tests/baselines/reference/infiniteConstraints.errors.txt +++ b/tests/baselines/reference/infiniteConstraints.errors.txt @@ -1,11 +1,19 @@ +error TS2321: Excessive stack depth comparing types 'Extract], Record<"val", string>>["val"]' and 'Extract>], Record<"val", string>>["val"]'. tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' cannot be used to index type 'B[Exclude]'. +tests/cases/compiler/infiniteConstraints.ts(27,36): error TS2345: Argument of type '{ main: Record<"val", "test">; alternate: Record<"val", "test2">; }' is not assignable to parameter of type '{ main: never; alternate: never; }'. + Types of property 'main' are incompatible. + Type 'Record<"val", "test">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(29,44): error TS2345: Argument of type '{ main: Record<"val", "test">; }' is not assignable to parameter of type '{ main: never; }'. + Types of property 'main' are incompatible. + Type 'Record<"val", "test">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(31,42): error TS2345: Argument of type '{ main: Record<"val", "dup">; alternate: Record<"val", "dup">; }' is not assignable to parameter of type '{ main: never; alternate: never; }'. Types of property 'main' are incompatible. Type 'Record<"val", "dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'. -==== tests/cases/compiler/infiniteConstraints.ts (3 errors) ==== +!!! error TS2321: Excessive stack depth comparing types 'Extract], Record<"val", string>>["val"]' and 'Extract>], Record<"val", string>>["val"]'. +==== tests/cases/compiler/infiniteConstraints.ts (5 errors) ==== // Both of the following types trigger the recursion limiter in getImmediateBaseConstraint type T1], { val: string }>["val"] }> = B; @@ -35,8 +43,16 @@ tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' c >(vals: T): void; const noError = ensureNoDuplicates({main: value("test"), alternate: value("test2")}); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ main: Record<"val", "test">; alternate: Record<"val", "test2">; }' is not assignable to parameter of type '{ main: never; alternate: never; }'. +!!! error TS2345: Types of property 'main' are incompatible. +!!! error TS2345: Type 'Record<"val", "test">' is not assignable to type 'never'. const shouldBeNoError = ensureNoDuplicates({main: value("test")}); + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ main: Record<"val", "test">; }' is not assignable to parameter of type '{ main: never; }'. +!!! error TS2345: Types of property 'main' are incompatible. +!!! error TS2345: Type 'Record<"val", "test">' is not assignable to type 'never'. const shouldBeError = ensureNoDuplicates({main: value("dup"), alternate: value("dup")}); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/infiniteConstraints.types b/tests/baselines/reference/infiniteConstraints.types index e23e138c820..7e357fbb01e 100644 --- a/tests/baselines/reference/infiniteConstraints.types +++ b/tests/baselines/reference/infiniteConstraints.types @@ -39,7 +39,7 @@ declare function value(val: V): Value; >val : V declare function ensureNoDuplicates< ->ensureNoDuplicates : >["val"] extends Extract], Record<"val", string>>["val"] ? never : any; }>(vals: T) => void +>ensureNoDuplicates : (vals: T) => void T extends { [K in keyof T]: Extract["val"] extends Extract], Value>["val"] @@ -50,9 +50,9 @@ declare function ensureNoDuplicates< >vals : T const noError = ensureNoDuplicates({main: value("test"), alternate: value("test2")}); ->noError : void ->ensureNoDuplicates({main: value("test"), alternate: value("test2")}) : void ->ensureNoDuplicates : >["val"] extends Extract], Record<"val", string>>["val"] ? never : any; }>(vals: T) => void +>noError : any +>ensureNoDuplicates({main: value("test"), alternate: value("test2")}) : any +>ensureNoDuplicates : (vals: T) => void >{main: value("test"), alternate: value("test2")} : { main: Record<"val", "test">; alternate: Record<"val", "test2">; } >main : Record<"val", "test"> >value("test") : Record<"val", "test"> @@ -64,9 +64,9 @@ const noError = ensureNoDuplicates({main: value("test"), alternate: value("test2 >"test2" : "test2" const shouldBeNoError = ensureNoDuplicates({main: value("test")}); ->shouldBeNoError : void ->ensureNoDuplicates({main: value("test")}) : void ->ensureNoDuplicates : >["val"] extends Extract], Record<"val", string>>["val"] ? never : any; }>(vals: T) => void +>shouldBeNoError : any +>ensureNoDuplicates({main: value("test")}) : any +>ensureNoDuplicates : (vals: T) => void >{main: value("test")} : { main: Record<"val", "test">; } >main : Record<"val", "test"> >value("test") : Record<"val", "test"> @@ -76,7 +76,7 @@ const shouldBeNoError = ensureNoDuplicates({main: value("test")}); const shouldBeError = ensureNoDuplicates({main: value("dup"), alternate: value("dup")}); >shouldBeError : any >ensureNoDuplicates({main: value("dup"), alternate: value("dup")}) : any ->ensureNoDuplicates : >["val"] extends Extract], Record<"val", string>>["val"] ? never : any; }>(vals: T) => void +>ensureNoDuplicates : (vals: T) => void >{main: value("dup"), alternate: value("dup")} : { main: Record<"val", "dup">; alternate: Record<"val", "dup">; } >main : Record<"val", "dup"> >value("dup") : Record<"val", "dup"> From a2928b8fd31ae3f0f3370a521daff506bf378087 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 30 Aug 2018 13:13:21 -0700 Subject: [PATCH 117/163] Optimize relationship checks for arrays and tuples --- src/compiler/checker.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2bd5d40bffa..44c7eba605d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11829,6 +11829,9 @@ namespace ts { errorInfo = saveErrorInfo; } } + else if (isTupleType(source) && (isArrayType(target) || isReadonlyArrayType(target)) || isArrayType(source) && isReadonlyArrayType(target)) { + return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors); + } // Even if relationship doesn't hold for unions, intersections, or generic type references, // it may hold in a structural comparison. // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates From b2850ee4675b72de368d11b0c1443b8139043f09 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Thu, 30 Aug 2018 22:13:39 +0200 Subject: [PATCH 118/163] remove useless condition --- src/compiler/program.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 56300a03f67..2bbf17e6098 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1259,8 +1259,6 @@ namespace ts { } function getProjectReferences() { - if (!resolvedProjectReferences) return; - return resolvedProjectReferences; } From a35c49641d725827e345d4b7da136fc7c477f217 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 30 Aug 2018 13:13:42 -0700 Subject: [PATCH 119/163] Accept new baselines --- ...typeIsAssignableToReadonlyArray.errors.txt | 16 +++++-------- ...nmentCompatBetweenTupleAndArray.errors.txt | 12 ++++------ tests/baselines/reference/for-of39.errors.txt | 20 +++++----------- .../iterableArrayPattern28.errors.txt | 18 +++++--------- .../baselines/reference/tupleTypes.errors.txt | 24 +++++++------------ 5 files changed, 30 insertions(+), 60 deletions(-) diff --git a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt index 7ae20699c85..66a659b3863 100644 --- a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt +++ b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt @@ -1,13 +1,11 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. - Type 'A[]' is not assignable to type 'B[]'. - Type 'A' is not assignable to type 'B'. - Property 'b' is missing in type 'A'. + Type 'A' is not assignable to type 'B'. + Property 'b' is missing in type 'A'. tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C' is not assignable to type 'ReadonlyArray'. Types of property 'concat' are incompatible. Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. Type 'A[]' is not assignable to type 'B[]'. + Type 'A' is not assignable to type 'B'. ==== tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts (2 errors) ==== @@ -26,11 +24,8 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T rrb = ara; // error: 'A' is not assignable to 'B' ~~~ !!! error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray'. -!!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. -!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. -!!! error TS2322: Type 'A' is not assignable to type 'B'. -!!! error TS2322: Property 'b' is missing in type 'A'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Property 'b' is missing in type 'A'. rra = cra; rra = crb; // OK, C is assignable to ReadonlyArray @@ -41,4 +36,5 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T !!! error TS2322: Types of property 'concat' are incompatible. !!! error TS2322: Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. !!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt index 03dcee9baf3..b17973302c6 100644 --- a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt +++ b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt @@ -1,8 +1,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(17,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(18,1): error TS2322: Type '{}[]' is not assignable to type '[{}]'. Property '0' is missing in type '{}[]'. @@ -27,10 +25,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme numArray = numStrTuple; ~~~~~~~~ !!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. emptyObjTuple = emptyObjArray; ~~~~~~~~~~~~~ !!! error TS2322: Type '{}[]' is not assignable to type '[{}]'. diff --git a/tests/baselines/reference/for-of39.errors.txt b/tests/baselines/reference/for-of39.errors.txt index 62edda40de3..5f084961833 100644 --- a/tests/baselines/reference/for-of39.errors.txt +++ b/tests/baselines/reference/for-of39.errors.txt @@ -1,24 +1,16 @@ tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,19): error TS2345: Argument of type '([string, number] | [string, true])[]' is not assignable to parameter of type 'ReadonlyArray<[string, boolean]>'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray<[string, number] | [string, true]>[]): ([string, number] | [string, true])[]; (...items: ([string, number] | [string, true] | ConcatArray<[string, number] | [string, true]>)[]): ([string, number] | [string, true])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, boolean]>[]): [string, boolean][]; (...items: ([string, boolean] | ConcatArray<[string, boolean]>)[]): [string, boolean][]; }'. - Types of parameters 'items' and 'items' are incompatible. - Type 'ConcatArray<[string, boolean]>' is not assignable to type 'ConcatArray<[string, number] | [string, true]>'. - Type '[string, boolean]' is not assignable to type '[string, number] | [string, true]'. - Type '[string, boolean]' is not assignable to type '[string, number]'. - Type 'boolean' is not assignable to type 'number'. + Type '[string, number] | [string, true]' is not assignable to type '[string, boolean]'. + Type '[string, number]' is not assignable to type '[string, boolean]'. + Type 'number' is not assignable to type 'boolean'. ==== tests/cases/conformance/es6/for-ofStatements/for-of39.ts (1 errors) ==== var map = new Map([["", true], ["", 0]]); ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '([string, number] | [string, true])[]' is not assignable to parameter of type 'ReadonlyArray<[string, boolean]>'. -!!! error TS2345: Types of property 'concat' are incompatible. -!!! error TS2345: Type '{ (...items: ConcatArray<[string, number] | [string, true]>[]): ([string, number] | [string, true])[]; (...items: ([string, number] | [string, true] | ConcatArray<[string, number] | [string, true]>)[]): ([string, number] | [string, true])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, boolean]>[]): [string, boolean][]; (...items: ([string, boolean] | ConcatArray<[string, boolean]>)[]): [string, boolean][]; }'. -!!! error TS2345: Types of parameters 'items' and 'items' are incompatible. -!!! error TS2345: Type 'ConcatArray<[string, boolean]>' is not assignable to type 'ConcatArray<[string, number] | [string, true]>'. -!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number] | [string, true]'. -!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number]'. -!!! error TS2345: Type 'boolean' is not assignable to type 'number'. +!!! error TS2345: Type '[string, number] | [string, true]' is not assignable to type '[string, boolean]'. +!!! error TS2345: Type '[string, number]' is not assignable to type '[string, boolean]'. +!!! error TS2345: Type 'number' is not assignable to type 'boolean'. for (var [k, v] of map) { k; v; diff --git a/tests/baselines/reference/iterableArrayPattern28.errors.txt b/tests/baselines/reference/iterableArrayPattern28.errors.txt index 7ca750cd81f..ecc9f0a02c5 100644 --- a/tests/baselines/reference/iterableArrayPattern28.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern28.errors.txt @@ -1,11 +1,8 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(1,33): error TS2501: A rest element cannot contain a binding pattern. tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray<[string, number] | [string, boolean]>[]): ([string, number] | [string, boolean])[]; (...items: ([string, number] | [string, boolean] | ConcatArray<[string, number] | [string, boolean]>)[]): ([string, number] | [string, boolean])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, number]>[]): [string, number][]; (...items: ([string, number] | ConcatArray<[string, number]>)[]): [string, number][]; }'. - Type '([string, number] | [string, boolean])[]' is not assignable to type '[string, number][]'. - Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. - Type '[string, boolean]' is not assignable to type '[string, number]'. - Type 'boolean' is not assignable to type 'number'. + Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. + Type '[string, boolean]' is not assignable to type '[string, number]'. + Type 'boolean' is not assignable to type 'number'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (2 errors) ==== @@ -15,9 +12,6 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error takeFirstTwoEntries(...new Map([["", 0], ["hello", true]])); ~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'. -!!! error TS2345: Types of property 'concat' are incompatible. -!!! error TS2345: Type '{ (...items: ConcatArray<[string, number] | [string, boolean]>[]): ([string, number] | [string, boolean])[]; (...items: ([string, number] | [string, boolean] | ConcatArray<[string, number] | [string, boolean]>)[]): ([string, number] | [string, boolean])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, number]>[]): [string, number][]; (...items: ([string, number] | ConcatArray<[string, number]>)[]): [string, number][]; }'. -!!! error TS2345: Type '([string, number] | [string, boolean])[]' is not assignable to type '[string, number][]'. -!!! error TS2345: Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. -!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number]'. -!!! error TS2345: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file +!!! error TS2345: Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. +!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number]'. +!!! error TS2345: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index 87e17e14d3c..dd5fba3485d 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -9,15 +9,11 @@ tests/cases/compiler/tupleTypes.ts(18,1): error TS2322: Type '[number, string, n Type '3' is not assignable to type '2'. tests/cases/compiler/tupleTypes.ts(41,1): error TS2322: Type '[]' is not assignable to type '[number, string]'. tests/cases/compiler/tupleTypes.ts(47,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => number'. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(49,1): error TS2322: Type '[number, {}]' is not assignable to type 'number[]'. - Types of property 'pop' are incompatible. - Type '() => number | {}' is not assignable to type '() => number'. - Type 'number | {}' is not assignable to type 'number'. - Type '{}' is not assignable to type 'number'. + Type 'number | {}' is not assignable to type 'number'. + Type '{}' is not assignable to type 'number'. tests/cases/compiler/tupleTypes.ts(50,1): error TS2322: Type '[number, number]' is not assignable to type '[number, string]'. Type 'number' is not assignable to type 'string'. tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'. @@ -90,18 +86,14 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n a = a1; // Error ~ !!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. a = a2; a = a3; // Error ~ !!! error TS2322: Type '[number, {}]' is not assignable to type 'number[]'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => number | {}' is not assignable to type '() => number'. -!!! error TS2322: Type 'number | {}' is not assignable to type 'number'. -!!! error TS2322: Type '{}' is not assignable to type 'number'. +!!! error TS2322: Type 'number | {}' is not assignable to type 'number'. +!!! error TS2322: Type '{}' is not assignable to type 'number'. a1 = a2; // Error ~~ !!! error TS2322: Type '[number, number]' is not assignable to type '[number, string]'. From d3f96015f108cda074e8813d4bbdc9f3199939e0 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 30 Aug 2018 13:18:50 -0700 Subject: [PATCH 120/163] Fix namespace expando merge (#26690) * Allow JSContainers to merge with namespaces Expando functions marked with JSContainer previously failed to merge with namespaces. This change adds JSContainer to ValueModuleExcludes, allowing this kind of merge. * Improve symbol flags to fix namespace/expando merging Calls to bindPropertyAssignment now provide which special assignment kind they originated from. This allows better symbol flags to be set: 1. Property assignments get the FunctionScopedVariable flag, since they are equivalent to a `namespace` exporting a `var`. 2. Prototype property assignments get the Method flag if the initialiser is functionlike, and Property otherwise. 3. Prototype assignments get the flag Property. (3) is still not entirely correct (it's missing the Prototype flag), but is what existed previously. I'll try adding the Prototype flag to see whether it changes any baselines. * Add cross-file merge test * Update missed baselines * Namespace declarations are primary for merging purposes Also, property-assignments go back to being property declarations, not function-scoped variable declarations * Revert unneeded changes * Revert unneeded changes (in a codefix this time) * Put JSContainer on all assignment declarations This allows most of the new special-case merge code to go away. It now uses the JSContainer special-case code, which already exists. * Missed comment * Fix extra newline lint --- src/compiler/binder.ts | 14 +- src/compiler/checker.ts | 3 +- src/compiler/types.ts | 2 +- src/compiler/utilities.ts | 4 + .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../jsContainerMergeJsContainer.types | 8 +- .../typeFromPropertyAssignment31.errors.txt | 36 ++++ .../reference/typeFromPropertyAssignment31.js | 56 ++++++ .../typeFromPropertyAssignment31.symbols | 116 +++++++++++++ .../typeFromPropertyAssignment31.types | 156 +++++++++++++++++ .../typeFromPropertyAssignment32.errors.txt | 44 +++++ .../reference/typeFromPropertyAssignment32.js | 62 +++++++ .../typeFromPropertyAssignment32.symbols | 118 +++++++++++++ .../typeFromPropertyAssignment32.types | 158 +++++++++++++++++ .../typeFromPropertyAssignment33.errors.txt | 46 +++++ .../reference/typeFromPropertyAssignment33.js | 64 +++++++ .../typeFromPropertyAssignment33.symbols | 120 +++++++++++++ .../typeFromPropertyAssignment33.types | 160 ++++++++++++++++++ .../salsa/typeFromPropertyAssignment31.ts | 26 +++ .../salsa/typeFromPropertyAssignment32.ts | 29 ++++ .../salsa/typeFromPropertyAssignment33.ts | 31 ++++ 22 files changed, 1242 insertions(+), 15 deletions(-) create mode 100644 tests/baselines/reference/typeFromPropertyAssignment31.errors.txt create mode 100644 tests/baselines/reference/typeFromPropertyAssignment31.js create mode 100644 tests/baselines/reference/typeFromPropertyAssignment31.symbols create mode 100644 tests/baselines/reference/typeFromPropertyAssignment31.types create mode 100644 tests/baselines/reference/typeFromPropertyAssignment32.errors.txt create mode 100644 tests/baselines/reference/typeFromPropertyAssignment32.js create mode 100644 tests/baselines/reference/typeFromPropertyAssignment32.symbols create mode 100644 tests/baselines/reference/typeFromPropertyAssignment32.types create mode 100644 tests/baselines/reference/typeFromPropertyAssignment33.errors.txt create mode 100644 tests/baselines/reference/typeFromPropertyAssignment33.js create mode 100644 tests/baselines/reference/typeFromPropertyAssignment33.symbols create mode 100644 tests/baselines/reference/typeFromPropertyAssignment33.types create mode 100644 tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts create mode 100644 tests/cases/conformance/salsa/typeFromPropertyAssignment32.ts create mode 100644 tests/cases/conformance/salsa/typeFromPropertyAssignment33.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 44e6487c7c4..bab6ca7b360 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -236,8 +236,9 @@ namespace ts { if (symbolFlags & SymbolFlags.Value) { const { valueDeclaration } = symbol; if (!valueDeclaration || + (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) || (valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) { - // other kinds of value declarations take precedence over modules + // other kinds of value declarations take precedence over modules and assignment declarations symbol.valueDeclaration = node; } } @@ -373,7 +374,8 @@ namespace ts { // prototype symbols like methods. symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name)); } - else { + else if (!(includes & SymbolFlags.Variable && symbol.flags & SymbolFlags.JSContainer)) { + // JSContainers are allowed to merge with variables, no matter what other flags they have. if (isNamedDeclaration(node)) { node.name.parent = node; } @@ -2537,12 +2539,10 @@ namespace ts { (namespaceSymbol.members || (namespaceSymbol.members = createSymbolTable())) : (namespaceSymbol.exports || (namespaceSymbol.exports = createSymbolTable())); - // Declare the method/property - const jsContainerFlag = isToplevelNamespaceableInitializer ? SymbolFlags.JSContainer : 0; const isMethod = isFunctionLikeDeclaration(getAssignedJavascriptInitializer(propertyAccess)!); - const symbolFlags = (isMethod ? SymbolFlags.Method : SymbolFlags.Property) | jsContainerFlag; - const symbolExcludes = (isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes) & ~jsContainerFlag; - declareSymbol(symbolTable, namespaceSymbol, propertyAccess, symbolFlags, symbolExcludes); + const includes = isMethod ? SymbolFlags.Method : SymbolFlags.Property; + const excludes = isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes; + declareSymbol(symbolTable, namespaceSymbol, propertyAccess, includes | SymbolFlags.JSContainer, excludes & ~SymbolFlags.JSContainer); } /** diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 394a5a581cb..4ebb8a23de9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -837,8 +837,9 @@ namespace ts { target.flags |= source.flags; if (source.valueDeclaration && (!target.valueDeclaration || + isAssignmentDeclaration(target.valueDeclaration) || isEffectiveModuleDeclaration(target.valueDeclaration) && !isEffectiveModuleDeclaration(source.valueDeclaration))) { - // other kinds of value declarations take precedence over modules + // other kinds of value declarations take precedence over modules and assignment declarations target.valueDeclaration = source.valueDeclaration; } addRange(target.declarations, source.declarations); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5ed722a4571..56bad9c86e3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3463,7 +3463,7 @@ namespace ts { InterfaceExcludes = Type & ~(Interface | Class), RegularEnumExcludes = (Value | Type) & ~(RegularEnum | ValueModule), // regular enums merge only with regular enums and modules ConstEnumExcludes = (Value | Type) & ~ConstEnum, // const enums merge only with const enums - ValueModuleExcludes = Value & ~(Function | Class | RegularEnum | ValueModule), + ValueModuleExcludes = Value & ~(Function | Class | RegularEnum | ValueModule | JSContainer), NamespaceModuleExcludes = 0, MethodExcludes = Value & ~Method, GetAccessorExcludes = Value & ~SetAccessor, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6ecc80aaa3f..da13fcb4391 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1762,6 +1762,10 @@ namespace ts { return decl; } + export function isAssignmentDeclaration(decl: Declaration) { + return isBinaryExpression(decl) || isPropertyAccessExpression(decl) || isIdentifier(decl); + } + /** Get the initializer, taking into account defaulted Javascript initializers */ export function getEffectiveInitializer(node: HasExpressionInitializer) { if (isInJavaScriptFile(node) && node.initializer && diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 7d24aab8345..fd291c5387f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2075,7 +2075,7 @@ declare namespace ts { InterfaceExcludes = 67897736, RegularEnumExcludes = 68008191, ConstEnumExcludes = 68008831, - ValueModuleExcludes = 67219599, + ValueModuleExcludes = 110735, NamespaceModuleExcludes = 0, MethodExcludes = 67212223, GetAccessorExcludes = 67154879, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index eaf566bb161..852ca173b33 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2075,7 +2075,7 @@ declare namespace ts { InterfaceExcludes = 67897736, RegularEnumExcludes = 68008191, ConstEnumExcludes = 68008831, - ValueModuleExcludes = 67219599, + ValueModuleExcludes = 110735, NamespaceModuleExcludes = 0, MethodExcludes = 67212223, GetAccessorExcludes = 67154879, diff --git a/tests/baselines/reference/jsContainerMergeJsContainer.types b/tests/baselines/reference/jsContainerMergeJsContainer.types index 73e61aded0d..75d2152c571 100644 --- a/tests/baselines/reference/jsContainerMergeJsContainer.types +++ b/tests/baselines/reference/jsContainerMergeJsContainer.types @@ -6,18 +6,18 @@ const a = {}; a.d = function() {}; >a.d = function() {} : { (): void; prototype: {}; } ->a.d : { (): void; prototype: {}; } +>a.d : typeof a.d >a : typeof a ->d : { (): void; prototype: {}; } +>d : typeof a.d >function() {} : { (): void; prototype: {}; } === tests/cases/conformance/salsa/b.js === a.d.prototype = {}; >a.d.prototype = {} : {} >a.d.prototype : {} ->a.d : { (): void; prototype: {}; } +>a.d : typeof a.d >a : typeof a ->d : { (): void; prototype: {}; } +>d : typeof a.d >prototype : {} >{} : {} diff --git a/tests/baselines/reference/typeFromPropertyAssignment31.errors.txt b/tests/baselines/reference/typeFromPropertyAssignment31.errors.txt new file mode 100644 index 00000000000..6055e89ffec --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment31.errors.txt @@ -0,0 +1,36 @@ +tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts(13,1): error TS2322: Type 'false' is not assignable to type 'number'. +tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts(25,1): error TS2322: Type 'false' is not assignable to type 'number'. + + +==== tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts (2 errors) ==== + function ExpandoMerge(n: number) { + return n; + } + ExpandoMerge.p1 = 111 + ExpandoMerge.m = function(n: number) { + return n + 1; + } + namespace ExpandoMerge { + export var p2 = 222; + } + ExpandoMerge.p4 = 44444; // ok + ExpandoMerge.p6 = 66666; // ok + ExpandoMerge.p8 = false; // type error + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. + namespace ExpandoMerge { + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; + } + ExpandoMerge.p5 = 555555; // ok + ExpandoMerge.p7 = 777777; // ok + ExpandoMerge.p9 = false; // type error + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. + var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); + \ No newline at end of file diff --git a/tests/baselines/reference/typeFromPropertyAssignment31.js b/tests/baselines/reference/typeFromPropertyAssignment31.js new file mode 100644 index 00000000000..e5c9bda9550 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment31.js @@ -0,0 +1,56 @@ +//// [typeFromPropertyAssignment31.ts] +function ExpandoMerge(n: number) { + return n; +} +ExpandoMerge.p1 = 111 +ExpandoMerge.m = function(n: number) { + return n + 1; +} +namespace ExpandoMerge { + export var p2 = 222; +} +ExpandoMerge.p4 = 44444; // ok +ExpandoMerge.p6 = 66666; // ok +ExpandoMerge.p8 = false; // type error +namespace ExpandoMerge { + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; +} +ExpandoMerge.p5 = 555555; // ok +ExpandoMerge.p7 = 777777; // ok +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); + + +//// [typeFromPropertyAssignment31.js] +function ExpandoMerge(n) { + return n; +} +ExpandoMerge.p1 = 111; +ExpandoMerge.m = function (n) { + return n + 1; +}; +(function (ExpandoMerge) { + ExpandoMerge.p2 = 222; +})(ExpandoMerge || (ExpandoMerge = {})); +ExpandoMerge.p4 = 44444; // ok +ExpandoMerge.p6 = 66666; // ok +ExpandoMerge.p8 = false; // type error +(function (ExpandoMerge) { + ExpandoMerge.p3 = 333; + ExpandoMerge.p4 = 4; + ExpandoMerge.p5 = 5; + ExpandoMerge.p6 = 6; + ExpandoMerge.p7 = 7; + ExpandoMerge.p8 = 6; + ExpandoMerge.p9 = 7; +})(ExpandoMerge || (ExpandoMerge = {})); +ExpandoMerge.p5 = 555555; // ok +ExpandoMerge.p7 = 777777; // ok +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); diff --git a/tests/baselines/reference/typeFromPropertyAssignment31.symbols b/tests/baselines/reference/typeFromPropertyAssignment31.symbols new file mode 100644 index 00000000000..e5a6de9c82a --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment31.symbols @@ -0,0 +1,116 @@ +=== tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts === +function ExpandoMerge(n: number) { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 0, 22)) + + return n; +>n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 0, 22)) +} +ExpandoMerge.p1 = 111 +>ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment31.ts, 2, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment31.ts, 2, 1)) + +ExpandoMerge.m = function(n: number) { +>ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(typeFromPropertyAssignment31.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>m : Symbol(ExpandoMerge.m, Decl(typeFromPropertyAssignment31.ts, 3, 21)) +>n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 4, 26)) + + return n + 1; +>n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 4, 26)) +} +namespace ExpandoMerge { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) + + export var p2 = 222; +>p2 : Symbol(p2, Decl(typeFromPropertyAssignment31.ts, 8, 14)) +} +ExpandoMerge.p4 = 44444; // ok +>ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p4 : Symbol(ExpandoMerge.p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) + +ExpandoMerge.p6 = 66666; // ok +>ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p6 : Symbol(ExpandoMerge.p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) + +ExpandoMerge.p8 = false; // type error +>ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p8 : Symbol(ExpandoMerge.p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) + +namespace ExpandoMerge { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) + + export var p3 = 333; +>p3 : Symbol(p3, Decl(typeFromPropertyAssignment31.ts, 14, 14)) + + export var p4 = 4; +>p4 : Symbol(p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) + + export var p5 = 5; +>p5 : Symbol(p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) + + export let p6 = 6; +>p6 : Symbol(p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) + + export let p7 = 7; +>p7 : Symbol(p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) + + export var p8 = 6; +>p8 : Symbol(p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) + + export let p9 = 7; +>p9 : Symbol(p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) +} +ExpandoMerge.p5 = 555555; // ok +>ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p5 : Symbol(ExpandoMerge.p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) + +ExpandoMerge.p7 = 777777; // ok +>ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p7 : Symbol(ExpandoMerge.p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) + +ExpandoMerge.p9 = false; // type error +>ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p9 : Symbol(ExpandoMerge.p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) + +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); +>n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 25, 3)) +>ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment31.ts, 2, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment31.ts, 2, 1)) +>ExpandoMerge.p2 : Symbol(ExpandoMerge.p2, Decl(typeFromPropertyAssignment31.ts, 8, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p2 : Symbol(ExpandoMerge.p2, Decl(typeFromPropertyAssignment31.ts, 8, 14)) +>ExpandoMerge.p3 : Symbol(ExpandoMerge.p3, Decl(typeFromPropertyAssignment31.ts, 14, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p3 : Symbol(ExpandoMerge.p3, Decl(typeFromPropertyAssignment31.ts, 14, 14)) +>ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p4 : Symbol(ExpandoMerge.p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) +>ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p5 : Symbol(ExpandoMerge.p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) +>ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p6 : Symbol(ExpandoMerge.p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) +>ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p7 : Symbol(ExpandoMerge.p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) +>ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p8 : Symbol(ExpandoMerge.p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) +>ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>p9 : Symbol(ExpandoMerge.p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) +>ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(typeFromPropertyAssignment31.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>m : Symbol(ExpandoMerge.m, Decl(typeFromPropertyAssignment31.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) + diff --git a/tests/baselines/reference/typeFromPropertyAssignment31.types b/tests/baselines/reference/typeFromPropertyAssignment31.types new file mode 100644 index 00000000000..e302d58d507 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment31.types @@ -0,0 +1,156 @@ +=== tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts === +function ExpandoMerge(n: number) { +>ExpandoMerge : typeof ExpandoMerge +>n : number + + return n; +>n : number +} +ExpandoMerge.p1 = 111 +>ExpandoMerge.p1 = 111 : 111 +>ExpandoMerge.p1 : number +>ExpandoMerge : typeof ExpandoMerge +>p1 : number +>111 : 111 + +ExpandoMerge.m = function(n: number) { +>ExpandoMerge.m = function(n: number) { return n + 1;} : (n: number) => number +>ExpandoMerge.m : (n: number) => number +>ExpandoMerge : typeof ExpandoMerge +>m : (n: number) => number +>function(n: number) { return n + 1;} : (n: number) => number +>n : number + + return n + 1; +>n + 1 : number +>n : number +>1 : 1 +} +namespace ExpandoMerge { +>ExpandoMerge : typeof ExpandoMerge + + export var p2 = 222; +>p2 : number +>222 : 222 +} +ExpandoMerge.p4 = 44444; // ok +>ExpandoMerge.p4 = 44444 : 44444 +>ExpandoMerge.p4 : number +>ExpandoMerge : typeof ExpandoMerge +>p4 : number +>44444 : 44444 + +ExpandoMerge.p6 = 66666; // ok +>ExpandoMerge.p6 = 66666 : 66666 +>ExpandoMerge.p6 : number +>ExpandoMerge : typeof ExpandoMerge +>p6 : number +>66666 : 66666 + +ExpandoMerge.p8 = false; // type error +>ExpandoMerge.p8 = false : false +>ExpandoMerge.p8 : number +>ExpandoMerge : typeof ExpandoMerge +>p8 : number +>false : false + +namespace ExpandoMerge { +>ExpandoMerge : typeof ExpandoMerge + + export var p3 = 333; +>p3 : number +>333 : 333 + + export var p4 = 4; +>p4 : number +>4 : 4 + + export var p5 = 5; +>p5 : number +>5 : 5 + + export let p6 = 6; +>p6 : number +>6 : 6 + + export let p7 = 7; +>p7 : number +>7 : 7 + + export var p8 = 6; +>p8 : number +>6 : 6 + + export let p9 = 7; +>p9 : number +>7 : 7 +} +ExpandoMerge.p5 = 555555; // ok +>ExpandoMerge.p5 = 555555 : 555555 +>ExpandoMerge.p5 : number +>ExpandoMerge : typeof ExpandoMerge +>p5 : number +>555555 : 555555 + +ExpandoMerge.p7 = 777777; // ok +>ExpandoMerge.p7 = 777777 : 777777 +>ExpandoMerge.p7 : number +>ExpandoMerge : typeof ExpandoMerge +>p7 : number +>777777 : 777777 + +ExpandoMerge.p9 = false; // type error +>ExpandoMerge.p9 = false : false +>ExpandoMerge.p9 : number +>ExpandoMerge : typeof ExpandoMerge +>p9 : number +>false : false + +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); +>n : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001) : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 : number +>ExpandoMerge.p1 : number +>ExpandoMerge : typeof ExpandoMerge +>p1 : number +>ExpandoMerge.p2 : number +>ExpandoMerge : typeof ExpandoMerge +>p2 : number +>ExpandoMerge.p3 : number +>ExpandoMerge : typeof ExpandoMerge +>p3 : number +>ExpandoMerge.p4 : number +>ExpandoMerge : typeof ExpandoMerge +>p4 : number +>ExpandoMerge.p5 : number +>ExpandoMerge : typeof ExpandoMerge +>p5 : number +>ExpandoMerge.p6 : number +>ExpandoMerge : typeof ExpandoMerge +>p6 : number +>ExpandoMerge.p7 : number +>ExpandoMerge : typeof ExpandoMerge +>p7 : number +>ExpandoMerge.p8 : number +>ExpandoMerge : typeof ExpandoMerge +>p8 : number +>ExpandoMerge.p9 : number +>ExpandoMerge : typeof ExpandoMerge +>p9 : number +>ExpandoMerge.m(12) : number +>ExpandoMerge.m : (n: number) => number +>ExpandoMerge : typeof ExpandoMerge +>m : (n: number) => number +>12 : 12 +>ExpandoMerge(1001) : number +>ExpandoMerge : typeof ExpandoMerge +>1001 : 1001 + diff --git a/tests/baselines/reference/typeFromPropertyAssignment32.errors.txt b/tests/baselines/reference/typeFromPropertyAssignment32.errors.txt new file mode 100644 index 00000000000..bd8d4b003d8 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment32.errors.txt @@ -0,0 +1,44 @@ +tests/cases/conformance/salsa/expando.ts(12,1): error TS2322: Type 'false' is not assignable to type 'number'. +tests/cases/conformance/salsa/expando.ts(13,1): error TS2322: Type 'false' is not assignable to type 'number'. +tests/cases/conformance/salsa/ns.ts(1,11): error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. +tests/cases/conformance/salsa/ns.ts(10,11): error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. + + +==== tests/cases/conformance/salsa/expando.ts (2 errors) ==== + function ExpandoMerge(n: number) { + return n; + } + ExpandoMerge.p1 = 111 + ExpandoMerge.m = function(n: number) { + return n + 1; + } + ExpandoMerge.p4 = 44444; + ExpandoMerge.p5 = 555555; + ExpandoMerge.p6 = 66666; + ExpandoMerge.p7 = 777777; + ExpandoMerge.p8 = false; // type error + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. + ExpandoMerge.p9 = false; // type error + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. + var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); + +==== tests/cases/conformance/salsa/ns.ts (2 errors) ==== + namespace ExpandoMerge { + ~~~~~~~~~~~~ +!!! error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; + } + namespace ExpandoMerge { + ~~~~~~~~~~~~ +!!! error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. + export var p2 = 222; + } + \ No newline at end of file diff --git a/tests/baselines/reference/typeFromPropertyAssignment32.js b/tests/baselines/reference/typeFromPropertyAssignment32.js new file mode 100644 index 00000000000..d805f678358 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment32.js @@ -0,0 +1,62 @@ +//// [tests/cases/conformance/salsa/typeFromPropertyAssignment32.ts] //// + +//// [expando.ts] +function ExpandoMerge(n: number) { + return n; +} +ExpandoMerge.p1 = 111 +ExpandoMerge.m = function(n: number) { + return n + 1; +} +ExpandoMerge.p4 = 44444; +ExpandoMerge.p5 = 555555; +ExpandoMerge.p6 = 66666; +ExpandoMerge.p7 = 777777; +ExpandoMerge.p8 = false; // type error +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); + +//// [ns.ts] +namespace ExpandoMerge { + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; +} +namespace ExpandoMerge { + export var p2 = 222; +} + + +//// [expando.js] +function ExpandoMerge(n) { + return n; +} +ExpandoMerge.p1 = 111; +ExpandoMerge.m = function (n) { + return n + 1; +}; +ExpandoMerge.p4 = 44444; +ExpandoMerge.p5 = 555555; +ExpandoMerge.p6 = 66666; +ExpandoMerge.p7 = 777777; +ExpandoMerge.p8 = false; // type error +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); +//// [ns.js] +var ExpandoMerge; +(function (ExpandoMerge) { + ExpandoMerge.p3 = 333; + ExpandoMerge.p4 = 4; + ExpandoMerge.p5 = 5; + ExpandoMerge.p6 = 6; + ExpandoMerge.p7 = 7; + ExpandoMerge.p8 = 6; + ExpandoMerge.p9 = 7; +})(ExpandoMerge || (ExpandoMerge = {})); +(function (ExpandoMerge) { + ExpandoMerge.p2 = 222; +})(ExpandoMerge || (ExpandoMerge = {})); diff --git a/tests/baselines/reference/typeFromPropertyAssignment32.symbols b/tests/baselines/reference/typeFromPropertyAssignment32.symbols new file mode 100644 index 00000000000..d730f4d7e11 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment32.symbols @@ -0,0 +1,118 @@ +=== tests/cases/conformance/salsa/expando.ts === +function ExpandoMerge(n: number) { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>n : Symbol(n, Decl(expando.ts, 0, 22)) + + return n; +>n : Symbol(n, Decl(expando.ts, 0, 22)) +} +ExpandoMerge.p1 = 111 +>ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) + +ExpandoMerge.m = function(n: number) { +>ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) +>n : Symbol(n, Decl(expando.ts, 4, 26)) + + return n + 1; +>n : Symbol(n, Decl(expando.ts, 4, 26)) +} +ExpandoMerge.p4 = 44444; +>ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p4 : Symbol(ExpandoMerge.p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) + +ExpandoMerge.p5 = 555555; +>ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p5 : Symbol(ExpandoMerge.p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) + +ExpandoMerge.p6 = 66666; +>ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p6 : Symbol(ExpandoMerge.p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) + +ExpandoMerge.p7 = 777777; +>ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p7 : Symbol(ExpandoMerge.p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) + +ExpandoMerge.p8 = false; // type error +>ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p8 : Symbol(ExpandoMerge.p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) + +ExpandoMerge.p9 = false; // type error +>ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p9 : Symbol(ExpandoMerge.p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) + +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); +>n : Symbol(n, Decl(expando.ts, 13, 3)) +>ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) +>ExpandoMerge.p2 : Symbol(ExpandoMerge.p2, Decl(ns.ts, 10, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p2 : Symbol(ExpandoMerge.p2, Decl(ns.ts, 10, 14)) +>ExpandoMerge.p3 : Symbol(ExpandoMerge.p3, Decl(ns.ts, 1, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p3 : Symbol(ExpandoMerge.p3, Decl(ns.ts, 1, 14)) +>ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p4 : Symbol(ExpandoMerge.p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) +>ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p5 : Symbol(ExpandoMerge.p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) +>ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p6 : Symbol(ExpandoMerge.p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) +>ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p7 : Symbol(ExpandoMerge.p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) +>ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p8 : Symbol(ExpandoMerge.p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) +>ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>p9 : Symbol(ExpandoMerge.p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) +>ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) + +=== tests/cases/conformance/salsa/ns.ts === +namespace ExpandoMerge { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) + + export var p3 = 333; +>p3 : Symbol(p3, Decl(ns.ts, 1, 14)) + + export var p4 = 4; +>p4 : Symbol(p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) + + export var p5 = 5; +>p5 : Symbol(p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) + + export let p6 = 6; +>p6 : Symbol(p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) + + export let p7 = 7; +>p7 : Symbol(p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) + + export var p8 = 6; +>p8 : Symbol(p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) + + export let p9 = 7; +>p9 : Symbol(p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) +} +namespace ExpandoMerge { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) + + export var p2 = 222; +>p2 : Symbol(p2, Decl(ns.ts, 10, 14)) +} + diff --git a/tests/baselines/reference/typeFromPropertyAssignment32.types b/tests/baselines/reference/typeFromPropertyAssignment32.types new file mode 100644 index 00000000000..3ed7612d9c0 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment32.types @@ -0,0 +1,158 @@ +=== tests/cases/conformance/salsa/expando.ts === +function ExpandoMerge(n: number) { +>ExpandoMerge : typeof ExpandoMerge +>n : number + + return n; +>n : number +} +ExpandoMerge.p1 = 111 +>ExpandoMerge.p1 = 111 : 111 +>ExpandoMerge.p1 : number +>ExpandoMerge : typeof ExpandoMerge +>p1 : number +>111 : 111 + +ExpandoMerge.m = function(n: number) { +>ExpandoMerge.m = function(n: number) { return n + 1;} : (n: number) => number +>ExpandoMerge.m : (n: number) => number +>ExpandoMerge : typeof ExpandoMerge +>m : (n: number) => number +>function(n: number) { return n + 1;} : (n: number) => number +>n : number + + return n + 1; +>n + 1 : number +>n : number +>1 : 1 +} +ExpandoMerge.p4 = 44444; +>ExpandoMerge.p4 = 44444 : 44444 +>ExpandoMerge.p4 : number +>ExpandoMerge : typeof ExpandoMerge +>p4 : number +>44444 : 44444 + +ExpandoMerge.p5 = 555555; +>ExpandoMerge.p5 = 555555 : 555555 +>ExpandoMerge.p5 : number +>ExpandoMerge : typeof ExpandoMerge +>p5 : number +>555555 : 555555 + +ExpandoMerge.p6 = 66666; +>ExpandoMerge.p6 = 66666 : 66666 +>ExpandoMerge.p6 : number +>ExpandoMerge : typeof ExpandoMerge +>p6 : number +>66666 : 66666 + +ExpandoMerge.p7 = 777777; +>ExpandoMerge.p7 = 777777 : 777777 +>ExpandoMerge.p7 : number +>ExpandoMerge : typeof ExpandoMerge +>p7 : number +>777777 : 777777 + +ExpandoMerge.p8 = false; // type error +>ExpandoMerge.p8 = false : false +>ExpandoMerge.p8 : number +>ExpandoMerge : typeof ExpandoMerge +>p8 : number +>false : false + +ExpandoMerge.p9 = false; // type error +>ExpandoMerge.p9 = false : false +>ExpandoMerge.p9 : number +>ExpandoMerge : typeof ExpandoMerge +>p9 : number +>false : false + +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); +>n : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001) : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 : number +>ExpandoMerge.p1 : number +>ExpandoMerge : typeof ExpandoMerge +>p1 : number +>ExpandoMerge.p2 : number +>ExpandoMerge : typeof ExpandoMerge +>p2 : number +>ExpandoMerge.p3 : number +>ExpandoMerge : typeof ExpandoMerge +>p3 : number +>ExpandoMerge.p4 : number +>ExpandoMerge : typeof ExpandoMerge +>p4 : number +>ExpandoMerge.p5 : number +>ExpandoMerge : typeof ExpandoMerge +>p5 : number +>ExpandoMerge.p6 : number +>ExpandoMerge : typeof ExpandoMerge +>p6 : number +>ExpandoMerge.p7 : number +>ExpandoMerge : typeof ExpandoMerge +>p7 : number +>ExpandoMerge.p8 : number +>ExpandoMerge : typeof ExpandoMerge +>p8 : number +>ExpandoMerge.p9 : number +>ExpandoMerge : typeof ExpandoMerge +>p9 : number +>ExpandoMerge.m(12) : number +>ExpandoMerge.m : (n: number) => number +>ExpandoMerge : typeof ExpandoMerge +>m : (n: number) => number +>12 : 12 +>ExpandoMerge(1001) : number +>ExpandoMerge : typeof ExpandoMerge +>1001 : 1001 + +=== tests/cases/conformance/salsa/ns.ts === +namespace ExpandoMerge { +>ExpandoMerge : typeof ExpandoMerge + + export var p3 = 333; +>p3 : number +>333 : 333 + + export var p4 = 4; +>p4 : number +>4 : 4 + + export var p5 = 5; +>p5 : number +>5 : 5 + + export let p6 = 6; +>p6 : number +>6 : 6 + + export let p7 = 7; +>p7 : number +>7 : 7 + + export var p8 = 6; +>p8 : number +>6 : 6 + + export let p9 = 7; +>p9 : number +>7 : 7 +} +namespace ExpandoMerge { +>ExpandoMerge : typeof ExpandoMerge + + export var p2 = 222; +>p2 : number +>222 : 222 +} + diff --git a/tests/baselines/reference/typeFromPropertyAssignment33.errors.txt b/tests/baselines/reference/typeFromPropertyAssignment33.errors.txt new file mode 100644 index 00000000000..a4617c3d26a --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment33.errors.txt @@ -0,0 +1,46 @@ +tests/cases/conformance/salsa/expando.ts(12,1): error TS2322: Type 'false' is not assignable to type 'number'. +tests/cases/conformance/salsa/expando.ts(13,1): error TS2322: Type 'false' is not assignable to type 'number'. +tests/cases/conformance/salsa/ns.ts(1,11): error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. +tests/cases/conformance/salsa/ns.ts(10,11): error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. + + +==== tests/cases/conformance/salsa/ns.ts (2 errors) ==== + namespace ExpandoMerge { + ~~~~~~~~~~~~ +!!! error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; + } + namespace ExpandoMerge { + ~~~~~~~~~~~~ +!!! error TS2433: A namespace declaration cannot be in a different file from a class or function with which it is merged. + export var p2 = 222; + } + + +==== tests/cases/conformance/salsa/expando.ts (2 errors) ==== + function ExpandoMerge(n: number) { + return n; + } + ExpandoMerge.p1 = 111 + ExpandoMerge.m = function(n: number) { + return n + 1; + } + ExpandoMerge.p4 = 44444; + ExpandoMerge.p5 = 555555; + ExpandoMerge.p6 = 66666; + ExpandoMerge.p7 = 777777; + ExpandoMerge.p8 = false; // type error + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. + ExpandoMerge.p9 = false; // type error + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. + var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); + + \ No newline at end of file diff --git a/tests/baselines/reference/typeFromPropertyAssignment33.js b/tests/baselines/reference/typeFromPropertyAssignment33.js new file mode 100644 index 00000000000..fa431a0f273 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment33.js @@ -0,0 +1,64 @@ +//// [tests/cases/conformance/salsa/typeFromPropertyAssignment33.ts] //// + +//// [ns.ts] +namespace ExpandoMerge { + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; +} +namespace ExpandoMerge { + export var p2 = 222; +} + + +//// [expando.ts] +function ExpandoMerge(n: number) { + return n; +} +ExpandoMerge.p1 = 111 +ExpandoMerge.m = function(n: number) { + return n + 1; +} +ExpandoMerge.p4 = 44444; +ExpandoMerge.p5 = 555555; +ExpandoMerge.p6 = 66666; +ExpandoMerge.p7 = 777777; +ExpandoMerge.p8 = false; // type error +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); + + + +//// [ns.js] +var ExpandoMerge; +(function (ExpandoMerge) { + ExpandoMerge.p3 = 333; + ExpandoMerge.p4 = 4; + ExpandoMerge.p5 = 5; + ExpandoMerge.p6 = 6; + ExpandoMerge.p7 = 7; + ExpandoMerge.p8 = 6; + ExpandoMerge.p9 = 7; +})(ExpandoMerge || (ExpandoMerge = {})); +(function (ExpandoMerge) { + ExpandoMerge.p2 = 222; +})(ExpandoMerge || (ExpandoMerge = {})); +//// [expando.js] +function ExpandoMerge(n) { + return n; +} +ExpandoMerge.p1 = 111; +ExpandoMerge.m = function (n) { + return n + 1; +}; +ExpandoMerge.p4 = 44444; +ExpandoMerge.p5 = 555555; +ExpandoMerge.p6 = 66666; +ExpandoMerge.p7 = 777777; +ExpandoMerge.p8 = false; // type error +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); diff --git a/tests/baselines/reference/typeFromPropertyAssignment33.symbols b/tests/baselines/reference/typeFromPropertyAssignment33.symbols new file mode 100644 index 00000000000..7b21df91b96 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment33.symbols @@ -0,0 +1,120 @@ +=== tests/cases/conformance/salsa/ns.ts === +namespace ExpandoMerge { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) + + export var p3 = 333; +>p3 : Symbol(p3, Decl(ns.ts, 1, 14)) + + export var p4 = 4; +>p4 : Symbol(p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) + + export var p5 = 5; +>p5 : Symbol(p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) + + export let p6 = 6; +>p6 : Symbol(p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) + + export let p7 = 7; +>p7 : Symbol(p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) + + export var p8 = 6; +>p8 : Symbol(p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) + + export let p9 = 7; +>p9 : Symbol(p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) +} +namespace ExpandoMerge { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) + + export var p2 = 222; +>p2 : Symbol(p2, Decl(ns.ts, 10, 14)) +} + + +=== tests/cases/conformance/salsa/expando.ts === +function ExpandoMerge(n: number) { +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>n : Symbol(n, Decl(expando.ts, 0, 22)) + + return n; +>n : Symbol(n, Decl(expando.ts, 0, 22)) +} +ExpandoMerge.p1 = 111 +>ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) + +ExpandoMerge.m = function(n: number) { +>ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) +>n : Symbol(n, Decl(expando.ts, 4, 26)) + + return n + 1; +>n : Symbol(n, Decl(expando.ts, 4, 26)) +} +ExpandoMerge.p4 = 44444; +>ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p4 : Symbol(ExpandoMerge.p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) + +ExpandoMerge.p5 = 555555; +>ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p5 : Symbol(ExpandoMerge.p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) + +ExpandoMerge.p6 = 66666; +>ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p6 : Symbol(ExpandoMerge.p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) + +ExpandoMerge.p7 = 777777; +>ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p7 : Symbol(ExpandoMerge.p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) + +ExpandoMerge.p8 = false; // type error +>ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p8 : Symbol(ExpandoMerge.p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) + +ExpandoMerge.p9 = false; // type error +>ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p9 : Symbol(ExpandoMerge.p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) + +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); +>n : Symbol(n, Decl(expando.ts, 13, 3)) +>ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) +>ExpandoMerge.p2 : Symbol(ExpandoMerge.p2, Decl(ns.ts, 10, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p2 : Symbol(ExpandoMerge.p2, Decl(ns.ts, 10, 14)) +>ExpandoMerge.p3 : Symbol(ExpandoMerge.p3, Decl(ns.ts, 1, 14)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p3 : Symbol(ExpandoMerge.p3, Decl(ns.ts, 1, 14)) +>ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p4 : Symbol(ExpandoMerge.p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) +>ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p5 : Symbol(ExpandoMerge.p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) +>ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p6 : Symbol(ExpandoMerge.p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) +>ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p7 : Symbol(ExpandoMerge.p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) +>ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p8 : Symbol(ExpandoMerge.p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) +>ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>p9 : Symbol(ExpandoMerge.p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) +>ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) + + diff --git a/tests/baselines/reference/typeFromPropertyAssignment33.types b/tests/baselines/reference/typeFromPropertyAssignment33.types new file mode 100644 index 00000000000..1416b798467 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment33.types @@ -0,0 +1,160 @@ +=== tests/cases/conformance/salsa/ns.ts === +namespace ExpandoMerge { +>ExpandoMerge : typeof ExpandoMerge + + export var p3 = 333; +>p3 : number +>333 : 333 + + export var p4 = 4; +>p4 : number +>4 : 4 + + export var p5 = 5; +>p5 : number +>5 : 5 + + export let p6 = 6; +>p6 : number +>6 : 6 + + export let p7 = 7; +>p7 : number +>7 : 7 + + export var p8 = 6; +>p8 : number +>6 : 6 + + export let p9 = 7; +>p9 : number +>7 : 7 +} +namespace ExpandoMerge { +>ExpandoMerge : typeof ExpandoMerge + + export var p2 = 222; +>p2 : number +>222 : 222 +} + + +=== tests/cases/conformance/salsa/expando.ts === +function ExpandoMerge(n: number) { +>ExpandoMerge : typeof ExpandoMerge +>n : number + + return n; +>n : number +} +ExpandoMerge.p1 = 111 +>ExpandoMerge.p1 = 111 : 111 +>ExpandoMerge.p1 : number +>ExpandoMerge : typeof ExpandoMerge +>p1 : number +>111 : 111 + +ExpandoMerge.m = function(n: number) { +>ExpandoMerge.m = function(n: number) { return n + 1;} : (n: number) => number +>ExpandoMerge.m : (n: number) => number +>ExpandoMerge : typeof ExpandoMerge +>m : (n: number) => number +>function(n: number) { return n + 1;} : (n: number) => number +>n : number + + return n + 1; +>n + 1 : number +>n : number +>1 : 1 +} +ExpandoMerge.p4 = 44444; +>ExpandoMerge.p4 = 44444 : 44444 +>ExpandoMerge.p4 : number +>ExpandoMerge : typeof ExpandoMerge +>p4 : number +>44444 : 44444 + +ExpandoMerge.p5 = 555555; +>ExpandoMerge.p5 = 555555 : 555555 +>ExpandoMerge.p5 : number +>ExpandoMerge : typeof ExpandoMerge +>p5 : number +>555555 : 555555 + +ExpandoMerge.p6 = 66666; +>ExpandoMerge.p6 = 66666 : 66666 +>ExpandoMerge.p6 : number +>ExpandoMerge : typeof ExpandoMerge +>p6 : number +>66666 : 66666 + +ExpandoMerge.p7 = 777777; +>ExpandoMerge.p7 = 777777 : 777777 +>ExpandoMerge.p7 : number +>ExpandoMerge : typeof ExpandoMerge +>p7 : number +>777777 : 777777 + +ExpandoMerge.p8 = false; // type error +>ExpandoMerge.p8 = false : false +>ExpandoMerge.p8 : number +>ExpandoMerge : typeof ExpandoMerge +>p8 : number +>false : false + +ExpandoMerge.p9 = false; // type error +>ExpandoMerge.p9 = false : false +>ExpandoMerge.p9 : number +>ExpandoMerge : typeof ExpandoMerge +>p9 : number +>false : false + +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); +>n : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001) : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 : number +>ExpandoMerge.p1 + ExpandoMerge.p2 : number +>ExpandoMerge.p1 : number +>ExpandoMerge : typeof ExpandoMerge +>p1 : number +>ExpandoMerge.p2 : number +>ExpandoMerge : typeof ExpandoMerge +>p2 : number +>ExpandoMerge.p3 : number +>ExpandoMerge : typeof ExpandoMerge +>p3 : number +>ExpandoMerge.p4 : number +>ExpandoMerge : typeof ExpandoMerge +>p4 : number +>ExpandoMerge.p5 : number +>ExpandoMerge : typeof ExpandoMerge +>p5 : number +>ExpandoMerge.p6 : number +>ExpandoMerge : typeof ExpandoMerge +>p6 : number +>ExpandoMerge.p7 : number +>ExpandoMerge : typeof ExpandoMerge +>p7 : number +>ExpandoMerge.p8 : number +>ExpandoMerge : typeof ExpandoMerge +>p8 : number +>ExpandoMerge.p9 : number +>ExpandoMerge : typeof ExpandoMerge +>p9 : number +>ExpandoMerge.m(12) : number +>ExpandoMerge.m : (n: number) => number +>ExpandoMerge : typeof ExpandoMerge +>m : (n: number) => number +>12 : 12 +>ExpandoMerge(1001) : number +>ExpandoMerge : typeof ExpandoMerge +>1001 : 1001 + + diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts new file mode 100644 index 00000000000..7c11a2a64bb --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts @@ -0,0 +1,26 @@ +function ExpandoMerge(n: number) { + return n; +} +ExpandoMerge.p1 = 111 +ExpandoMerge.m = function(n: number) { + return n + 1; +} +namespace ExpandoMerge { + export var p2 = 222; +} +ExpandoMerge.p4 = 44444; // ok +ExpandoMerge.p6 = 66666; // ok +ExpandoMerge.p8 = false; // type error +namespace ExpandoMerge { + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; +} +ExpandoMerge.p5 = 555555; // ok +ExpandoMerge.p7 = 777777; // ok +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment32.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment32.ts new file mode 100644 index 00000000000..498aa151e73 --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment32.ts @@ -0,0 +1,29 @@ +// @Filename: expando.ts +function ExpandoMerge(n: number) { + return n; +} +ExpandoMerge.p1 = 111 +ExpandoMerge.m = function(n: number) { + return n + 1; +} +ExpandoMerge.p4 = 44444; +ExpandoMerge.p5 = 555555; +ExpandoMerge.p6 = 66666; +ExpandoMerge.p7 = 777777; +ExpandoMerge.p8 = false; // type error +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); + +// @Filename: ns.ts +namespace ExpandoMerge { + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; +} +namespace ExpandoMerge { + export var p2 = 222; +} diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment33.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment33.ts new file mode 100644 index 00000000000..d98f689329d --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment33.ts @@ -0,0 +1,31 @@ +// @Filename: ns.ts +namespace ExpandoMerge { + export var p3 = 333; + export var p4 = 4; + export var p5 = 5; + export let p6 = 6; + export let p7 = 7; + export var p8 = 6; + export let p9 = 7; +} +namespace ExpandoMerge { + export var p2 = 222; +} + + +// @Filename: expando.ts +function ExpandoMerge(n: number) { + return n; +} +ExpandoMerge.p1 = 111 +ExpandoMerge.m = function(n: number) { + return n + 1; +} +ExpandoMerge.p4 = 44444; +ExpandoMerge.p5 = 555555; +ExpandoMerge.p6 = 66666; +ExpandoMerge.p7 = 777777; +ExpandoMerge.p8 = false; // type error +ExpandoMerge.p9 = false; // type error +var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); + From 65fa0128bb7a28e7db8fa5bec14f0f3806d867ab Mon Sep 17 00:00:00 2001 From: Sam Lanning Date: Thu, 30 Aug 2018 14:03:51 -0700 Subject: [PATCH 121/163] Add test for ts.equalOwnProperties --- src/testRunner/tsconfig.json | 1 + src/testRunner/unittests/compilerCore.ts | 33 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/testRunner/unittests/compilerCore.ts diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index fa7900f1ca3..27dca8296ed 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -46,6 +46,7 @@ "unittests/cancellableLanguageServiceOperations.ts", "unittests/commandLineParsing.ts", "unittests/compileOnSave.ts", + "unittests/compilerCore.ts", "unittests/configurationExtension.ts", "unittests/convertCompilerOptionsFromJson.ts", "unittests/convertToAsyncFunction.ts", diff --git a/src/testRunner/unittests/compilerCore.ts b/src/testRunner/unittests/compilerCore.ts new file mode 100644 index 00000000000..27f5cdc0887 --- /dev/null +++ b/src/testRunner/unittests/compilerCore.ts @@ -0,0 +1,33 @@ +namespace ts { + describe("compilerCore", () => { + describe("equalOwnProperties", () => { + it("correctly equates objects", () => { + assert.isTrue(equalOwnProperties({}, {})); + assert.isTrue(equalOwnProperties({ a: 1 }, { a: 1 })); + assert.isTrue(equalOwnProperties({ a: 1, b: 2 }, { b: 2, a: 1 })); + }); + it("correctly identifies unmatched objects", () => { + assert.isFalse(equalOwnProperties({}, { a: 1 }), "missing left property"); + assert.isFalse(equalOwnProperties({ a: 1 }, {}), "missing right property"); + assert.isFalse(equalOwnProperties({ a: 1 }, { a: 2 }), "differing property"); + }); + it("correctly identifies undefined vs hasOwnProperty", () => { + assert.isFalse(equalOwnProperties({}, { a: undefined }), "missing left property"); + assert.isFalse(equalOwnProperties({ a: undefined }, {}), "missing right property"); + }); + it("truthiness", () => { + const trythyTest = (l: any, r: any) => !!l === !!r; + assert.isFalse(equalOwnProperties({}, { a: 1 }, trythyTest), "missing left truthy property"); + assert.isFalse(equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property"); + assert.isFalse(equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property"); + assert.isFalse(equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property"); + assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" }, trythyTest), "valid equality"); + }); + it("all equal", () => { + assert.isFalse(equalOwnProperties({}, { a: 1 }, () => true), "missing left property"); + assert.isFalse(equalOwnProperties({ a: 1 }, {}, () => true), "missing right property"); + assert.isTrue(equalOwnProperties({ a: 1 }, { a: 2 }, () => true), "valid equality"); + }); + }); + }); +} From 2c41d8b44e5ade83c8e5391f4bdcc48e151d4bce Mon Sep 17 00:00:00 2001 From: Sam Lanning Date: Thu, 30 Aug 2018 14:08:24 -0700 Subject: [PATCH 122/163] Fix equalOwnProperties equalOwnProperties would incorrectly report two map-like objects as equal in the case where a property defined in `left` was not defined in `right` and whose value was considered "equal" to undefined by the equalityComparer. This bug was found by an alert on LGTM.com --- src/compiler/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 1eaab5b1b59..d5caadf079a 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1272,7 +1272,7 @@ namespace ts { if (!left || !right) return false; for (const key in left) { if (hasOwnProperty.call(left, key)) { - if (!hasOwnProperty.call(right, key) === undefined) return false; + if (!hasOwnProperty.call(right, key)) return false; if (!equalityComparer(left[key], right[key])) return false; } } From 2fe349915319278ca7fbcc7a22da8b0aa175d572 Mon Sep 17 00:00:00 2001 From: Mine Starks Date: Thu, 30 Aug 2018 14:02:26 -0700 Subject: [PATCH 123/163] Fix faulty path handling --- src/server/editorServices.ts | 2 +- src/tsserver/server.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 117887d7611..ca8c61311ec 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -472,7 +472,7 @@ namespace ts.server { this.globalPlugins = opts.globalPlugins || emptyArray; this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray; this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads; - this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation; + this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(getDirectoryPath(this.getExecutingFilePath()), "typesMap.json") : opts.typesMapLocation; this.syntaxOnly = opts.syntaxOnly; Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService"); diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index 3e5986e9408..d7ced146707 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -920,7 +920,7 @@ namespace ts.server { setStackTraceLimit(); const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation)!; // TODO: GH#18217 - const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(sys.getExecutingFilePath(), "../typesMap.json"); + const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(getDirectoryPath(sys.getExecutingFilePath()), "typesMap.json"); const npmLocation = findArgument(Arguments.NpmLocation); function parseStringArray(argName: string): ReadonlyArray { From cd37e41d3dc34a15c7b5fe9faa759c415cb90269 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 30 Aug 2018 15:45:06 -0700 Subject: [PATCH 124/163] Make finer-grained errors get reported on function arguments (#26784) --- src/compiler/checker.ts | 12 ++- ...CompatFunctionsWithOptionalArgs.errors.txt | 11 +-- .../declarationsAndAssignments.errors.txt | 14 ++- ...tructuringParameterDeclaration2.errors.txt | 85 ++++++------------- ...cturingParameterDeclaration3ES5.errors.txt | 10 +-- ...arameterDeclaration3ES5iterable.errors.txt | 10 +-- ...cturingParameterDeclaration3ES6.errors.txt | 10 +-- ...tructuringParameterDeclaration4.errors.txt | 10 +-- ...tructuringParameterDeclaration5.errors.txt | 37 +++----- ...tructuringParameterDeclaration8.errors.txt | 22 ++--- ...structuringParameterProperties2.errors.txt | 8 +- ...structuringParameterProperties5.errors.txt | 18 ++-- ...CallWithFunctionTypedArguments5.errors.txt | 22 ++--- ...enericCallWithObjectLiteralArgs.errors.txt | 11 +-- ...CallWithObjectLiteralArguments1.errors.txt | 55 +++++------- ...thObjectTypeArgsAndConstraints3.errors.txt | 15 ++-- .../genericConstraintSatisfaction1.errors.txt | 11 +-- .../indexedAccessRelation.errors.txt | 25 +++--- .../reference/infiniteConstraints.errors.txt | 17 ++-- ...nvariantGenericErrorElaboration.errors.txt | 11 +-- .../lastPropertyInLiteralWins.errors.txt | 28 +++--- .../reference/mappedTypeErrors.errors.txt | 22 ++--- .../mappedTypeInferenceErrors.errors.txt | 26 +----- .../objectLitTargetTypeCallSite.errors.txt | 11 +-- ...ralFunctionArgContextualTyping2.errors.txt | 27 +++--- ...rthandPropertiesAssignmentError.errors.txt | 11 +-- .../optionalBindingParameters1.errors.txt | 13 +-- .../optionalBindingParameters2.errors.txt | 17 ++-- ...alBindingParametersInOverloads1.errors.txt | 13 +-- ...alBindingParametersInOverloads2.errors.txt | 17 ++-- .../overloadResolutionTest1.errors.txt | 22 ++--- ...meterAsTypeParameterConstraint2.errors.txt | 22 ++--- ...wrappedAndRecursiveConstraints4.errors.txt | 9 +- 33 files changed, 257 insertions(+), 395 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4ebb8a23de9..bf268984a18 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10528,9 +10528,13 @@ namespace ts { * attempt to issue more specific errors on, for example, specific object literal properties or tuple members. */ function checkTypeAssignableToAndOptionallyElaborate(source: Type, target: Type, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { - if (isTypeAssignableTo(source, target)) return true; - if (!elaborateError(expr, source, target)) { - return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain); + return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain); + } + + function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { + if (isTypeRelatedTo(source, target, relation)) return true; + if (!errorNode || !elaborateError(expr, source, target)) { + return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain); } return false; } @@ -18869,7 +18873,7 @@ namespace ts { // we obtain the regular type of any object literal arguments because we may not have inferred complete // parameter types yet and therefore excess property checks may yield false positives (see #17041). const checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType; - if (!checkTypeRelatedTo(checkArgType, paramType, relation, reportErrors ? arg : undefined, headMessage)) { + if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage)) { return false; } } diff --git a/tests/baselines/reference/assignmentCompatFunctionsWithOptionalArgs.errors.txt b/tests/baselines/reference/assignmentCompatFunctionsWithOptionalArgs.errors.txt index 2316320f480..6686167cf1e 100644 --- a/tests/baselines/reference/assignmentCompatFunctionsWithOptionalArgs.errors.txt +++ b/tests/baselines/reference/assignmentCompatFunctionsWithOptionalArgs.errors.txt @@ -1,7 +1,5 @@ tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration. -tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(4,5): error TS2345: Argument of type '{ id: number; name: boolean; }' is not assignable to parameter of type '{ id: number; name?: string; }'. - Types of property 'name' are incompatible. - Type 'boolean' is not assignable to type 'string'. +tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(4,17): error TS2322: Type 'false' is not assignable to type 'string'. tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(5,5): error TS2345: Argument of type '{ name: string; }' is not assignable to parameter of type '{ id: number; name?: string; }'. Property 'id' is missing in type '{ name: string; }'. @@ -13,10 +11,9 @@ tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(5,5): error TS foo({ id: 1234 }); // Ok foo({ id: 1234, name: "hello" }); // Ok foo({ id: 1234, name: false }); // Error, name of wrong type - ~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ id: number; name: boolean; }' is not assignable to parameter of type '{ id: number; name?: string; }'. -!!! error TS2345: Types of property 'name' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'string'. + ~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts:1:31: The expected type comes from property 'name' which is declared here on type '{ id: number; name?: string; }' foo({ name: "hello" }); // Error, id required but missing ~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '{ name: string; }' is not assignable to parameter of type '{ id: number; name?: string; }'. diff --git a/tests/baselines/reference/declarationsAndAssignments.errors.txt b/tests/baselines/reference/declarationsAndAssignments.errors.txt index 920f995ef32..930d5f0c5b9 100644 --- a/tests/baselines/reference/declarationsAndAssignments.errors.txt +++ b/tests/baselines/reference/declarationsAndAssignments.errors.txt @@ -17,10 +17,8 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,11): tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(73,14): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,11): error TS2459: Type 'undefined[]' has no property 'a' and no string index signature. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(74,14): error TS2459: Type 'undefined[]' has no property 'b' and no string index signature. -tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(106,5): error TS2345: Argument of type '[number, [string, { y: false; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'. - Type '[string, { y: false; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'. - Type '{ y: false; }' is not assignable to type '{ x: any; y?: boolean; }'. - Property 'x' is missing in type '{ y: false; }'. +tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(106,17): error TS2322: Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'. + Property 'x' is missing in type '{ y: boolean; }'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,6): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9): error TS2322: Type 'number' is not assignable to type 'string'. @@ -170,11 +168,9 @@ tests/cases/conformance/es6/destructuring/declarationsAndAssignments.ts(138,9): f14([2, ["abc", { x: 0, y: true }]]); f14([2, ["abc", { x: 0 }]]); f14([2, ["abc", { y: false }]]); // Error, no x - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, [string, { y: false; }]]' is not assignable to parameter of type '[number, [string, { x: any; y?: boolean; }]]'. -!!! error TS2345: Type '[string, { y: false; }]' is not assignable to type '[string, { x: any; y?: boolean; }]'. -!!! error TS2345: Type '{ y: false; }' is not assignable to type '{ x: any; y?: boolean; }'. -!!! error TS2345: Property 'x' is missing in type '{ y: false; }'. + ~~~~~~~~~~~~ +!!! error TS2322: Type '{ y: boolean; }' is not assignable to type '{ x: any; y?: boolean; }'. +!!! error TS2322: Property 'x' is missing in type '{ y: boolean; }'. module M { export var [a, b] = [1, 2]; diff --git a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt index 6e4b3f1ad08..a3ca44020c2 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration2.errors.txt @@ -1,38 +1,21 @@ -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,4): error TS2345: Argument of type '[number, string, string[][]]' is not assignable to parameter of type '[number, number, string[][]]'. - Type 'string' is not assignable to type 'number'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,8): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(7,29): error TS1005: ',' expected. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(8,4): error TS2345: Argument of type '[number, number, string[][], string]' is not assignable to parameter of type '[number, number, string[][]]'. Types of property 'length' are incompatible. Type '4' is not assignable to type '3'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,8): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(16,16): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(23,14): error TS2345: Argument of type '{ x: string; y: boolean; }' is not assignable to parameter of type '{ x: number; y: any; }'. - Types of property 'x' are incompatible. - Type 'string' is not assignable to type 'number'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(23,16): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(30,14): error TS2300: Duplicate identifier 'z'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(30,18): error TS2300: Duplicate identifier 'z'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(34,4): error TS2345: Argument of type '{ z: number; }' is not assignable to parameter of type '{ z: { x: any; y: { j: any; }; }; }'. - Types of property 'z' are incompatible. - Type 'number' is not assignable to type '{ x: any; y: { j: any; }; }'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(34,6): error TS2322: Type 'number' is not assignable to type '{ x: any; y: { j: any; }; }'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(35,4): error TS2345: Argument of type '{}' is not assignable to parameter of type '{ z: number; }'. Property 'z' is missing in type '{}'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(36,4): error TS2345: Argument of type '{ z: boolean; }' is not assignable to parameter of type '{ z: number; }'. - Types of property 'z' are incompatible. - Type 'boolean' is not assignable to type 'number'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(37,4): error TS2345: Argument of type '{ z: boolean; }' is not assignable to parameter of type '{ z?: number; }'. - Types of property 'z' are incompatible. - Type 'boolean' is not assignable to type 'number'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(38,4): error TS2345: Argument of type '{ b: boolean; }' is not assignable to parameter of type '{ b: string | number; }'. - Types of property 'b' are incompatible. - Type 'boolean' is not assignable to type 'string | number'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(39,4): error TS2345: Argument of type '[number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. - Types of property '2' are incompatible. - Type 'boolean' is not assignable to type '[[any]]'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(40,4): error TS2345: Argument of type '[number, number, [[string]]]' is not assignable to parameter of type '[any, any, [[number?]]]'. - Type '[[string]]' is not assignable to type '[[number?]]'. - Type '[string]' is not assignable to type '[number?]'. - Types of property '0' are incompatible. - Type 'string' is not assignable to type 'number'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(36,6): error TS2322: Type 'true' is not assignable to type 'number'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(37,6): error TS2322: Type 'false' is not assignable to type 'number'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(38,6): error TS2322: Type 'true' is not assignable to type 'string | number'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(39,11): error TS2322: Type 'false' is not assignable to type '[[any]]'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(40,13): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(46,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(47,13): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts(56,8): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. @@ -54,9 +37,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( // If the declaration includes a type annotation, the parameter is of that type function a0([a, b, [[c]]]: [number, number, string[][]]) { } a0([1, "string", [["world"]]); // Error - ~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, string, string[][]]' is not assignable to parameter of type '[number, number, string[][]]'. -!!! error TS2345: Type 'string' is not assignable to type 'number'. + ~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. ~ !!! error TS1005: ',' expected. a0([1, 2, [["world"]], "string"]); // Error @@ -83,10 +65,9 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( function b3([[a], b, [[c, d]]] = [[undefined], undefined, [[undefined, undefined]]]) { } b1("string", { x: "string", y: true }); // Error - ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: string; y: boolean; }' is not assignable to parameter of type '{ x: number; y: any; }'. -!!! error TS2345: Types of property 'x' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:19:29: The expected type comes from property 'x' which is declared here on type '{ x: number; y: any; }' // If the declaration specifies a binding pattern, the parameter type is the implied type of that binding pattern (section 5.1.3) function c0({z: {x, y: {j}}}) { } @@ -102,41 +83,29 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts( function c6([a, b, [[c = 1]]]) { } c0({ z: 1 }); // Error, implied type is { z: {x: any, y: {j: any}} } - ~~~~~~~~ -!!! error TS2345: Argument of type '{ z: number; }' is not assignable to parameter of type '{ z: { x: any; y: { j: any; }; }; }'. -!!! error TS2345: Types of property 'z' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type '{ x: any; y: { j: any; }; }'. + ~ +!!! error TS2322: Type 'number' is not assignable to type '{ x: any; y: { j: any; }; }'. c1({}); // Error, implied type is {z:number}? ~~ !!! error TS2345: Argument of type '{}' is not assignable to parameter of type '{ z: number; }'. !!! error TS2345: Property 'z' is missing in type '{}'. c1({ z: true }); // Error, implied type is {z:number}? - ~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ z: boolean; }' is not assignable to parameter of type '{ z: number; }'. -!!! error TS2345: Types of property 'z' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'number'. + ~ +!!! error TS2322: Type 'true' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:27:21: The expected type comes from property 'z' which is declared here on type '{ z: number; }' c2({ z: false }); // Error, implied type is {z?: number} - ~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ z: boolean; }' is not assignable to parameter of type '{ z?: number; }'. -!!! error TS2345: Types of property 'z' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'number'. + ~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. c3({ b: true }); // Error, implied type is { b: number|string }. - ~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ b: boolean; }' is not assignable to parameter of type '{ b: string | number; }'. -!!! error TS2345: Types of property 'b' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'string | number'. + ~ +!!! error TS2322: Type 'true' is not assignable to type 'string | number'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration2.ts:29:20: The expected type comes from property 'b' which is declared here on type '{ b: string | number; }' c5([1, 2, false, true]); // Error, implied type is [any, any, [[any]]] - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Types of property '2' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type '[[any]]'. + ~~~~~ +!!! error TS2322: Type 'false' is not assignable to type '[[any]]'. c6([1, 2, [["string"]]]); // Error, implied type is [any, any, [[number]]] // Use initializer - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, number, [[string]]]' is not assignable to parameter of type '[any, any, [[number?]]]'. -!!! error TS2345: Type '[[string]]' is not assignable to type '[[number?]]'. -!!! error TS2345: Type '[string]' is not assignable to type '[number?]'. -!!! error TS2345: Types of property '0' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'number'. + ~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. // A parameter can be marked optional by following its name or binding pattern with a question mark (?) // or by including an initializer. Initializers (including binding property or element initializers) are diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt index d3d7cc97b51..89c0cad0d3a 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5.errors.txt @@ -1,9 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. Types of property 'length' are incompatible. Type '5' is not assignable to type '3'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(29,5): error TS2345: Argument of type '[number, number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. - Types of property '2' are incompatible. - Type 'number' is not assignable to type '[[any]]'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(29,12): error TS2322: Type 'number' is not assignable to type '[[any]]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5.ts(30,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. Property '2' is missing in type '[number, number]'. @@ -42,10 +40,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5. a10([1, 2, [["string"]], false, true]); // Parameter type is any[] a10([1, 2, 3, false, true]); // Parameter type is any[] - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. -!!! error TS2345: Types of property '2' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type '[[any]]'. + ~ +!!! error TS2322: Type 'number' is not assignable to type '[[any]]'. a10([1, 2]); // Parameter type is any[] ~~~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt index fa08518279e..047ee9e191c 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES5iterable.errors.txt @@ -1,9 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. Types of property 'length' are incompatible. Type '5' is not assignable to type '3'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(29,5): error TS2345: Argument of type '[number, number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. - Types of property '2' are incompatible. - Type 'number' is not assignable to type '[[any]]'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(29,12): error TS2322: Type 'number' is not assignable to type '[[any]]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5iterable.ts(30,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. Property '2' is missing in type '[number, number]'. @@ -42,10 +40,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES5i a10([1, 2, [["string"]], false, true]); // Parameter type is any[] a10([1, 2, 3, false, true]); // Parameter type is any[] - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. -!!! error TS2345: Types of property '2' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type '[[any]]'. + ~ +!!! error TS2322: Type 'number' is not assignable to type '[[any]]'. a10([1, 2]); // Parameter type is any[] ~~~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. diff --git a/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt index 238e155e954..38b56187a28 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration3ES6.errors.txt @@ -1,9 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(26,4): error TS2345: Argument of type '[number, number, [[string]], boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. Types of property 'length' are incompatible. Type '5' is not assignable to type '3'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(29,5): error TS2345: Argument of type '[number, number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. - Types of property '2' are incompatible. - Type 'number' is not assignable to type '[[any]]'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(29,12): error TS2322: Type 'number' is not assignable to type '[[any]]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6.ts(30,5): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. Property '2' is missing in type '[number, number]'. @@ -42,10 +40,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration3ES6. a10([1, 2, [["string"]], false, true]); // Parameter type is any[] a10([1, 2, 3, false, true]); // Parameter type is any[] - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, number, number, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. -!!! error TS2345: Types of property '2' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type '[[any]]'. + ~ +!!! error TS2322: Type 'number' is not assignable to type '[[any]]'. a10([1, 2]); // Parameter type is any[] ~~~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]], ...any[]]'. diff --git a/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt index 2af931d352d..46e4f597c21 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration4.errors.txt @@ -2,9 +2,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts( tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(15,16): error TS1048: A rest parameter cannot have an initializer. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(20,19): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(21,7): error TS2552: Cannot find name 'array2'. Did you mean 'Array'? -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(22,4): error TS2345: Argument of type '[number, number, string, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. - Types of property '2' are incompatible. - Type 'string' is not assignable to type '[[any]]'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(22,11): error TS2322: Type 'string' is not assignable to type '[[any]]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(23,4): error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]]]'. Property '2' is missing in type '[number, number]'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(24,4): error TS2345: Argument of type '(string | number)[]' is not assignable to parameter of type 'number[]'. @@ -47,10 +45,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts( !!! error TS2552: Cannot find name 'array2'. Did you mean 'Array'? !!! related TS2728 /.ts/lib.es5.d.ts:1298:15: 'Array' is declared here. a5([1, 2, "string", false, true]); // Error, parameter type is [any, any, [[any]]] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, number, string, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'. -!!! error TS2345: Types of property '2' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type '[[any]]'. + ~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type '[[any]]'. a5([1, 2]); // Error, parameter type is [any, any, [[any]]] ~~~~~~ !!! error TS2345: Argument of type '[number, number]' is not assignable to parameter of type '[any, any, [[any]]]'. diff --git a/tests/baselines/reference/destructuringParameterDeclaration5.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration5.errors.txt index 2afb25502c7..be65d7c37aa 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration5.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration5.errors.txt @@ -1,15 +1,9 @@ -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts(47,4): error TS2345: Argument of type '{ y: Class; }' is not assignable to parameter of type '{ y: D; }'. - Types of property 'y' are incompatible. - Type 'Class' is not assignable to type 'D'. - Property 'foo' is missing in type 'Class'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts(47,6): error TS2322: Type 'Class' is not assignable to type 'D'. + Property 'foo' is missing in type 'Class'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts(48,4): error TS2345: Argument of type '{}' is not assignable to parameter of type '{ y: D; }'. Property 'y' is missing in type '{}'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts(49,4): error TS2345: Argument of type '{ y: number; }' is not assignable to parameter of type '{ y: D; }'. - Types of property 'y' are incompatible. - Type 'number' is not assignable to type 'D'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts(50,4): error TS2345: Argument of type '{ y: string; }' is not assignable to parameter of type '{ y: D; }'. - Types of property 'y' are incompatible. - Type 'string' is not assignable to type 'D'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts(49,6): error TS2322: Type 'number' is not assignable to type 'D'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts(50,6): error TS2322: Type 'string' is not assignable to type 'D'. ==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts (4 errors) ==== @@ -60,22 +54,19 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts( d3({ y: new SubClass() }); // Error d3({ y: new Class() }); - ~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ y: Class; }' is not assignable to parameter of type '{ y: D; }'. -!!! error TS2345: Types of property 'y' are incompatible. -!!! error TS2345: Type 'Class' is not assignable to type 'D'. -!!! error TS2345: Property 'foo' is missing in type 'Class'. + ~ +!!! error TS2322: Type 'Class' is not assignable to type 'D'. +!!! error TS2322: Property 'foo' is missing in type 'Class'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts:29:33: The expected type comes from property 'y' which is declared here on type '{ y: D; }' d3({}); ~~ !!! error TS2345: Argument of type '{}' is not assignable to parameter of type '{ y: D; }'. !!! error TS2345: Property 'y' is missing in type '{}'. d3({ y: 1 }); - ~~~~~~~~ -!!! error TS2345: Argument of type '{ y: number; }' is not assignable to parameter of type '{ y: D; }'. -!!! error TS2345: Types of property 'y' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type 'D'. + ~ +!!! error TS2322: Type 'number' is not assignable to type 'D'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts:29:33: The expected type comes from property 'y' which is declared here on type '{ y: D; }' d3({ y: "world" }); - ~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ y: string; }' is not assignable to parameter of type '{ y: D; }'. -!!! error TS2345: Types of property 'y' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'D'. \ No newline at end of file + ~ +!!! error TS2322: Type 'string' is not assignable to type 'D'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration5.ts:29:33: The expected type comes from property 'y' which is declared here on type '{ y: D; }' \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterDeclaration8.errors.txt b/tests/baselines/reference/destructuringParameterDeclaration8.errors.txt index 0b333efe901..bb6b1686fc2 100644 --- a/tests/baselines/reference/destructuringParameterDeclaration8.errors.txt +++ b/tests/baselines/reference/destructuringParameterDeclaration8.errors.txt @@ -1,11 +1,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts(4,5): error TS2322: Type '"z"' is not assignable to type '"x" | "y"'. tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts(5,15): error TS2322: Type '"c"' is not assignable to type '"a" | "b"'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts(17,6): error TS2345: Argument of type '{ method: "z"; nested: { p: "b"; }; }' is not assignable to parameter of type '{ method?: "x" | "y"; nested?: { p: "a" | "b"; }; }'. - Types of property 'method' are incompatible. - Type '"z"' is not assignable to type '"x" | "y"'. -tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts(18,6): error TS2345: Argument of type '{ method: "one"; nested: { p: "a"; }; }' is not assignable to parameter of type '{ method?: "x" | "y"; nested?: { p: "a" | "b"; }; }'. - Types of property 'method' are incompatible. - Type '"one"' is not assignable to type '"x" | "y"'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts(17,8): error TS2322: Type '"z"' is not assignable to type '"x" | "y"'. +tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts(18,8): error TS2322: Type '"one"' is not assignable to type '"x" | "y"'. ==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts (4 errors) ==== @@ -30,13 +26,11 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts( test({}); test({ method: 'x', nested: { p: 'a' } }) test({ method: 'z', nested: { p: 'b' } }) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ method: "z"; nested: { p: "b"; }; }' is not assignable to parameter of type '{ method?: "x" | "y"; nested?: { p: "a" | "b"; }; }'. -!!! error TS2345: Types of property 'method' are incompatible. -!!! error TS2345: Type '"z"' is not assignable to type '"x" | "y"'. + ~~~~~~ +!!! error TS2322: Type '"z"' is not assignable to type '"x" | "y"'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts:7:5: The expected type comes from property 'method' which is declared here on type '{ method?: "x" | "y"; nested?: { p: "a" | "b"; }; }' test({ method: 'one', nested: { p: 'a' } }) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ method: "one"; nested: { p: "a"; }; }' is not assignable to parameter of type '{ method?: "x" | "y"; nested?: { p: "a" | "b"; }; }'. -!!! error TS2345: Types of property 'method' are incompatible. -!!! error TS2345: Type '"one"' is not assignable to type '"x" | "y"'. + ~~~~~~ +!!! error TS2322: Type '"one"' is not assignable to type '"x" | "y"'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration8.ts:7:5: The expected type comes from property 'method' which is declared here on type '{ method?: "x" | "y"; nested?: { p: "a" | "b"; }; }' \ No newline at end of file diff --git a/tests/baselines/reference/destructuringParameterProperties2.errors.txt b/tests/baselines/reference/destructuringParameterProperties2.errors.txt index deb039aa67d..da8ecee52b6 100644 --- a/tests/baselines/reference/destructuringParameterProperties2.errors.txt +++ b/tests/baselines/reference/destructuringParameterProperties2.errors.txt @@ -5,8 +5,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(4 tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(9,21): error TS2339: Property 'a' does not exist on type 'C1'. tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(13,21): error TS2339: Property 'b' does not exist on type 'C1'. tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(17,21): error TS2339: Property 'c' does not exist on type 'C1'. -tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(21,27): error TS2345: Argument of type '[number, undefined, string]' is not assignable to parameter of type '[number, string, boolean]'. - Type 'string' is not assignable to type 'boolean'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(21,42): error TS2322: Type 'string' is not assignable to type 'boolean'. ==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts (8 errors) ==== @@ -45,9 +44,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties2.ts(2 } var x = new C1(undefined, [0, undefined, ""]); - ~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[number, undefined, string]' is not assignable to parameter of type '[number, string, boolean]'. -!!! error TS2345: Type 'string' is not assignable to type 'boolean'. + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. var [x_a, x_b, x_c] = [x.getA(), x.getB(), x.getC()]; var y = new C1(10, [0, "", true]); diff --git a/tests/baselines/reference/destructuringParameterProperties5.errors.txt b/tests/baselines/reference/destructuringParameterProperties5.errors.txt index e0540240b61..44e013fad0b 100644 --- a/tests/baselines/reference/destructuringParameterProperties5.errors.txt +++ b/tests/baselines/reference/destructuringParameterProperties5.errors.txt @@ -7,12 +7,13 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7 tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,51): error TS2339: Property 'x3' does not exist on type 'C1'. tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,62): error TS2339: Property 'y' does not exist on type 'C1'. tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(7,72): error TS2339: Property 'z' does not exist on type 'C1'. -tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(11,19): error TS2345: Argument of type '[{ x1: number; x2: string; x3: boolean; }, string, boolean]' is not assignable to parameter of type '[ObjType1, number, string]'. - Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type 'ObjType1'. - Object literal may only specify known properties, and 'x1' does not exist in type 'ObjType1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(11,19): error TS2322: Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type 'ObjType1'. + Object literal may only specify known properties, and 'x1' does not exist in type 'ObjType1'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(11,47): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(11,51): error TS2322: Type 'false' is not assignable to type 'string'. -==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts (10 errors) ==== +==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts (12 errors) ==== type ObjType1 = { x: number; y: string; z: boolean } type TupleType1 = [ObjType1, number, string] @@ -43,7 +44,10 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(1 var a = new C1([{ x1: 10, x2: "", x3: true }, "", false]); ~~~~~~ -!!! error TS2345: Argument of type '[{ x1: number; x2: string; x3: boolean; }, string, boolean]' is not assignable to parameter of type '[ObjType1, number, string]'. -!!! error TS2345: Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type 'ObjType1'. -!!! error TS2345: Object literal may only specify known properties, and 'x1' does not exist in type 'ObjType1'. +!!! error TS2322: Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type 'ObjType1'. +!!! error TS2322: Object literal may only specify known properties, and 'x1' does not exist in type 'ObjType1'. + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + ~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'string'. var [a_x1, a_x2, a_x3, a_y, a_z] = [a.x1, a.x2, a.x3, a.y, a.z]; \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithFunctionTypedArguments5.errors.txt b/tests/baselines/reference/genericCallWithFunctionTypedArguments5.errors.txt index 75ae76b1dbc..ee15ac0597c 100644 --- a/tests/baselines/reference/genericCallWithFunctionTypedArguments5.errors.txt +++ b/tests/baselines/reference/genericCallWithFunctionTypedArguments5.errors.txt @@ -1,9 +1,5 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments5.ts(10,14): error TS2345: Argument of type '{ cb: (x: T, y: T) => string; }' is not assignable to parameter of type '{ cb: (t: {}) => string; }'. - Types of property 'cb' are incompatible. - Type '(x: T, y: T) => string' is not assignable to type '(t: {}) => string'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments5.ts(11,14): error TS2345: Argument of type '{ cb: (x: string, y: number) => string; }' is not assignable to parameter of type '{ cb: (t: string) => string; }'. - Types of property 'cb' are incompatible. - Type '(x: string, y: number) => string' is not assignable to type '(t: string) => string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments5.ts(10,16): error TS2322: Type '(x: T, y: T) => string' is not assignable to type '(t: {}) => string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments5.ts(11,16): error TS2322: Type '(x: string, y: number) => string' is not assignable to type '(t: string) => string'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments5.ts (2 errors) ==== @@ -17,15 +13,13 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFun var r = foo(arg); // {} // more args not allowed var r2 = foo({ cb: (x: T, y: T) => '' }); // error - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ cb: (x: T, y: T) => string; }' is not assignable to parameter of type '{ cb: (t: {}) => string; }'. -!!! error TS2345: Types of property 'cb' are incompatible. -!!! error TS2345: Type '(x: T, y: T) => string' is not assignable to type '(t: {}) => string'. + ~~ +!!! error TS2322: Type '(x: T, y: T) => string' is not assignable to type '(t: {}) => string'. +!!! related TS6500 tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments5.ts:3:27: The expected type comes from property 'cb' which is declared here on type '{ cb: (t: {}) => string; }' var r3 = foo({ cb: (x: string, y: number) => '' }); // error - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ cb: (x: string, y: number) => string; }' is not assignable to parameter of type '{ cb: (t: string) => string; }'. -!!! error TS2345: Types of property 'cb' are incompatible. -!!! error TS2345: Type '(x: string, y: number) => string' is not assignable to type '(t: string) => string'. + ~~ +!!! error TS2322: Type '(x: string, y: number) => string' is not assignable to type '(t: string) => string'. +!!! related TS6500 tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments5.ts:3:27: The expected type comes from property 'cb' which is declared here on type '{ cb: (t: string) => string; }' function foo2(arg: { cb: (t: T, t2: T) => U }) { return arg.cb(null, null); diff --git a/tests/baselines/reference/genericCallWithObjectLiteralArgs.errors.txt b/tests/baselines/reference/genericCallWithObjectLiteralArgs.errors.txt index c1724a8f698..22e19e10d80 100644 --- a/tests/baselines/reference/genericCallWithObjectLiteralArgs.errors.txt +++ b/tests/baselines/reference/genericCallWithObjectLiteralArgs.errors.txt @@ -1,6 +1,4 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectLiteralArgs.ts(5,13): error TS2345: Argument of type '{ bar: number; baz: string; }' is not assignable to parameter of type '{ bar: number; baz: number; }'. - Types of property 'baz' are incompatible. - Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectLiteralArgs.ts(5,23): error TS2322: Type 'string' is not assignable to type 'number'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectLiteralArgs.ts (1 errors) ==== @@ -9,10 +7,9 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObj } var r = foo({ bar: 1, baz: '' }); // error - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ bar: number; baz: string; }' is not assignable to parameter of type '{ bar: number; baz: number; }'. -!!! error TS2345: Types of property 'baz' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'number'. + ~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectLiteralArgs.ts:1:30: The expected type comes from property 'baz' which is declared here on type '{ bar: number; baz: number; }' var r2 = foo({ bar: 1, baz: 1 }); // T = number var r3 = foo({ bar: foo, baz: foo }); // T = typeof foo var r4 = foo({ bar: 1, baz: '' }); // T = Object \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithObjectLiteralArguments1.errors.txt b/tests/baselines/reference/genericCallWithObjectLiteralArguments1.errors.txt index cbc57364155..3537744ad39 100644 --- a/tests/baselines/reference/genericCallWithObjectLiteralArguments1.errors.txt +++ b/tests/baselines/reference/genericCallWithObjectLiteralArguments1.errors.txt @@ -1,45 +1,30 @@ -tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(3,13): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; y: number; }'. - Types of property 'y' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(4,22): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; y: number; }'. - Types of property 'y' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(5,22): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: string; y: string; }'. - Types of property 'x' are incompatible. - Type 'number' is not assignable to type 'string'. -tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(6,22): error TS2345: Argument of type '{ x: string; y: number; }' is not assignable to parameter of type '{ x: number; y: number; }'. - Types of property 'x' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(7,22): error TS2345: Argument of type '{ x: string; y: number; }' is not assignable to parameter of type '{ x: string; y: string; }'. - Types of property 'y' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(3,21): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(4,30): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(5,24): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(6,24): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(7,31): error TS2322: Type 'number' is not assignable to type 'string'. ==== tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts (5 errors) ==== function foo(n: { x: T; y: T }, m: T) { return m; } // these are all errors var x = foo({ x: 3, y: "" }, 4); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; y: number; }'. -!!! error TS2345: Types of property 'y' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts:1:28: The expected type comes from property 'y' which is declared here on type '{ x: number; y: number; }' var x2 = foo({ x: 3, y: "" }, 4); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; y: number; }'. -!!! error TS2345: Types of property 'y' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts:1:28: The expected type comes from property 'y' which is declared here on type '{ x: number; y: number; }' var x3 = foo({ x: 3, y: "" }, 4); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: string; y: string; }'. -!!! error TS2345: Types of property 'x' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type 'string'. + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts:1:22: The expected type comes from property 'x' which is declared here on type '{ x: string; y: string; }' var x4 = foo({ x: "", y: 4 }, ""); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: string; y: number; }' is not assignable to parameter of type '{ x: number; y: number; }'. -!!! error TS2345: Types of property 'x' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'number'. + ~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts:1:22: The expected type comes from property 'x' which is declared here on type '{ x: number; y: number; }' var x5 = foo({ x: "", y: 4 }, ""); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: string; y: number; }' is not assignable to parameter of type '{ x: string; y: string; }'. -!!! error TS2345: Types of property 'y' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type 'string'. \ No newline at end of file + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts:1:28: The expected type comes from property 'y' which is declared here on type '{ x: string; y: string; }' \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints3.errors.txt b/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints3.errors.txt index ad07374b810..d6cbc5d17b7 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints3.errors.txt +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints3.errors.txt @@ -1,7 +1,5 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndConstraints3.ts(18,12): error TS2345: Argument of type '{ x: Derived; y: Derived2; }' is not assignable to parameter of type '{ x: Derived; y: Derived; }'. - Types of property 'y' are incompatible. - Type 'Derived2' is not assignable to type 'Derived'. - Property 'y' is missing in type 'Derived2'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndConstraints3.ts(18,32): error TS2322: Type 'Derived2' is not assignable to type 'Derived'. + Property 'y' is missing in type 'Derived2'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndConstraints3.ts (1 errors) ==== @@ -23,11 +21,10 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObj } var r1 = f({ x: new Derived(), y: new Derived2() }); // error because neither is supertype of the other - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: Derived; y: Derived2; }' is not assignable to parameter of type '{ x: Derived; y: Derived; }'. -!!! error TS2345: Types of property 'y' are incompatible. -!!! error TS2345: Type 'Derived2' is not assignable to type 'Derived'. -!!! error TS2345: Property 'y' is missing in type 'Derived2'. + ~ +!!! error TS2322: Type 'Derived2' is not assignable to type 'Derived'. +!!! error TS2322: Property 'y' is missing in type 'Derived2'. +!!! related TS6500 tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndConstraints3.ts:13:39: The expected type comes from property 'y' which is declared here on type '{ x: Derived; y: Derived; }' function f2(a: U) { var r: T; diff --git a/tests/baselines/reference/genericConstraintSatisfaction1.errors.txt b/tests/baselines/reference/genericConstraintSatisfaction1.errors.txt index ade053d9344..735900e3ef3 100644 --- a/tests/baselines/reference/genericConstraintSatisfaction1.errors.txt +++ b/tests/baselines/reference/genericConstraintSatisfaction1.errors.txt @@ -1,6 +1,4 @@ -tests/cases/compiler/genericConstraintSatisfaction1.ts(6,5): error TS2345: Argument of type '{ s: number; }' is not assignable to parameter of type '{ s: string; }'. - Types of property 's' are incompatible. - Type 'number' is not assignable to type 'string'. +tests/cases/compiler/genericConstraintSatisfaction1.ts(6,6): error TS2322: Type 'number' is not assignable to type 'string'. ==== tests/cases/compiler/genericConstraintSatisfaction1.ts (1 errors) ==== @@ -10,8 +8,7 @@ tests/cases/compiler/genericConstraintSatisfaction1.ts(6,5): error TS2345: Argum var x: I<{s: string}> x.f({s: 1}) - ~~~~~~ -!!! error TS2345: Argument of type '{ s: number; }' is not assignable to parameter of type '{ s: string; }'. -!!! error TS2345: Types of property 's' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type 'string'. + ~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/genericConstraintSatisfaction1.ts:5:11: The expected type comes from property 's' which is declared here on type '{ s: string; }' \ No newline at end of file diff --git a/tests/baselines/reference/indexedAccessRelation.errors.txt b/tests/baselines/reference/indexedAccessRelation.errors.txt index 84e65df856d..14dbee4d4c1 100644 --- a/tests/baselines/reference/indexedAccessRelation.errors.txt +++ b/tests/baselines/reference/indexedAccessRelation.errors.txt @@ -1,10 +1,8 @@ -tests/cases/compiler/indexedAccessRelation.ts(16,23): error TS2345: Argument of type '{ a: T; }' is not assignable to parameter of type 'Pick, "a">'. - Types of property 'a' are incompatible. - Type 'T' is not assignable to type 'S["a"] & T'. - Type 'Foo' is not assignable to type 'S["a"] & T'. +tests/cases/compiler/indexedAccessRelation.ts(16,25): error TS2322: Type 'T' is not assignable to type 'S["a"] & T'. + Type 'Foo' is not assignable to type 'S["a"] & T'. + Type 'Foo' is not assignable to type 'S["a"]'. + Type 'T' is not assignable to type 'S["a"]'. Type 'Foo' is not assignable to type 'S["a"]'. - Type 'T' is not assignable to type 'S["a"]'. - Type 'Foo' is not assignable to type 'S["a"]'. ==== tests/cases/compiler/indexedAccessRelation.ts (1 errors) ==== @@ -24,14 +22,13 @@ tests/cases/compiler/indexedAccessRelation.ts(16,23): error TS2345: Argument of { foo(a: T) { this.setState({ a: a }); - ~~~~~~~~ -!!! error TS2345: Argument of type '{ a: T; }' is not assignable to parameter of type 'Pick, "a">'. -!!! error TS2345: Types of property 'a' are incompatible. -!!! error TS2345: Type 'T' is not assignable to type 'S["a"] & T'. -!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"] & T'. -!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"]'. -!!! error TS2345: Type 'T' is not assignable to type 'S["a"]'. -!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"]'. + ~ +!!! error TS2322: Type 'T' is not assignable to type 'S["a"] & T'. +!!! error TS2322: Type 'Foo' is not assignable to type 'S["a"] & T'. +!!! error TS2322: Type 'Foo' is not assignable to type 'S["a"]'. +!!! error TS2322: Type 'T' is not assignable to type 'S["a"]'. +!!! error TS2322: Type 'Foo' is not assignable to type 'S["a"]'. +!!! related TS6500 tests/cases/compiler/indexedAccessRelation.ts:8:5: The expected type comes from property 'a' which is declared here on type 'Pick, "a">' } } \ No newline at end of file diff --git a/tests/baselines/reference/infiniteConstraints.errors.txt b/tests/baselines/reference/infiniteConstraints.errors.txt index 387b0daac68..685b18932c1 100644 --- a/tests/baselines/reference/infiniteConstraints.errors.txt +++ b/tests/baselines/reference/infiniteConstraints.errors.txt @@ -1,11 +1,10 @@ tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' cannot be used to index type 'B[Exclude]'. -tests/cases/compiler/infiniteConstraints.ts(31,42): error TS2345: Argument of type '{ main: Record<"val", "dup">; alternate: Record<"val", "dup">; }' is not assignable to parameter of type '{ main: never; alternate: never; }'. - Types of property 'main' are incompatible. - Type 'Record<"val", "dup">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(31,43): error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(31,63): error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'. -==== tests/cases/compiler/infiniteConstraints.ts (3 errors) ==== +==== tests/cases/compiler/infiniteConstraints.ts (4 errors) ==== // Both of the following types trigger the recursion limiter in getImmediateBaseConstraint type T1], { val: string }>["val"] }> = B; @@ -39,10 +38,12 @@ tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' c const shouldBeNoError = ensureNoDuplicates({main: value("test")}); const shouldBeError = ensureNoDuplicates({main: value("dup"), alternate: value("dup")}); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ main: Record<"val", "dup">; alternate: Record<"val", "dup">; }' is not assignable to parameter of type '{ main: never; alternate: never; }'. -!!! error TS2345: Types of property 'main' are incompatible. -!!! error TS2345: Type 'Record<"val", "dup">' is not assignable to type 'never'. + ~~~~ +!!! error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'. +!!! related TS6500 tests/cases/compiler/infiniteConstraints.ts:31:43: The expected type comes from property 'main' which is declared here on type '{ main: never; alternate: never; }' + ~~~~~~~~~ +!!! error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'. +!!! related TS6500 tests/cases/compiler/infiniteConstraints.ts:31:63: The expected type comes from property 'alternate' which is declared here on type '{ main: never; alternate: never; }' // Repro from #26448 diff --git a/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt b/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt index 5142b665d71..bf9c8065cea 100644 --- a/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt +++ b/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt @@ -8,9 +8,7 @@ tests/cases/compiler/invariantGenericErrorElaboration.ts(3,7): error TS2322: Typ Type 'Constraint>>' is not assignable to type 'Constraint>'. Types of property 'underlying' are incompatible. Type 'Constraint>' is not assignable to type 'Constraint'. -tests/cases/compiler/invariantGenericErrorElaboration.ts(4,17): error TS2345: Argument of type '{ foo: Num; }' is not assignable to parameter of type '{ [_: string]: Runtype; }'. - Property 'foo' is incompatible with index signature. - Type 'Num' is not assignable to type 'Runtype'. +tests/cases/compiler/invariantGenericErrorElaboration.ts(4,19): error TS2322: Type 'Num' is not assignable to type 'Runtype'. ==== tests/cases/compiler/invariantGenericErrorElaboration.ts (2 errors) ==== @@ -29,10 +27,9 @@ tests/cases/compiler/invariantGenericErrorElaboration.ts(4,17): error TS2345: Ar !!! error TS2322: Types of property 'underlying' are incompatible. !!! error TS2322: Type 'Constraint>' is not assignable to type 'Constraint'. const Foo = Obj({ foo: Num }) - ~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ foo: Num; }' is not assignable to parameter of type '{ [_: string]: Runtype; }'. -!!! error TS2345: Property 'foo' is incompatible with index signature. -!!! error TS2345: Type 'Num' is not assignable to type 'Runtype'. + ~~~ +!!! error TS2322: Type 'Num' is not assignable to type 'Runtype'. +!!! related TS6501 tests/cases/compiler/invariantGenericErrorElaboration.ts:17:34: The expected type comes from this index signature. interface Runtype { constraint: Constraint diff --git a/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt b/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt index 2b4a694975b..5e12521ad60 100644 --- a/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt +++ b/tests/baselines/reference/lastPropertyInLiteralWins.errors.txt @@ -1,13 +1,12 @@ -tests/cases/compiler/lastPropertyInLiteralWins.ts(7,6): error TS2345: Argument of type '{ thunk: (num: number) => void; }' is not assignable to parameter of type 'Thing'. - Types of property 'thunk' are incompatible. - Type '(num: number) => void' is not assignable to type '(str: string) => void'. - Types of parameters 'num' and 'str' are incompatible. - Type 'string' is not assignable to type 'number'. +tests/cases/compiler/lastPropertyInLiteralWins.ts(8,5): error TS2322: Type '(num: number) => void' is not assignable to type '(str: string) => void'. + Types of parameters 'num' and 'str' are incompatible. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/lastPropertyInLiteralWins.ts(9,5): error TS2300: Duplicate identifier 'thunk'. +tests/cases/compiler/lastPropertyInLiteralWins.ts(9,5): error TS2322: Type '(num: number) => void' is not assignable to type '(str: string) => void'. tests/cases/compiler/lastPropertyInLiteralWins.ts(14,5): error TS2300: Duplicate identifier 'thunk'. -==== tests/cases/compiler/lastPropertyInLiteralWins.ts (3 errors) ==== +==== tests/cases/compiler/lastPropertyInLiteralWins.ts (4 errors) ==== interface Thing { thunk: (str: string) => void; } @@ -15,20 +14,19 @@ tests/cases/compiler/lastPropertyInLiteralWins.ts(14,5): error TS2300: Duplicate thing.thunk("str"); } test({ // Should error, as last one wins, and is wrong type - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ thunk: (str: string) => {}, - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~ +!!! error TS2322: Type '(num: number) => void' is not assignable to type '(str: string) => void'. +!!! error TS2322: Types of parameters 'num' and 'str' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 tests/cases/compiler/lastPropertyInLiteralWins.ts:2:5: The expected type comes from property 'thunk' which is declared here on type 'Thing' thunk: (num: number) => {} - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~ !!! error TS2300: Duplicate identifier 'thunk'. + ~~~~~ +!!! error TS2322: Type '(num: number) => void' is not assignable to type '(str: string) => void'. +!!! related TS6500 tests/cases/compiler/lastPropertyInLiteralWins.ts:2:5: The expected type comes from property 'thunk' which is declared here on type 'Thing' }); - ~ -!!! error TS2345: Argument of type '{ thunk: (num: number) => void; }' is not assignable to parameter of type 'Thing'. -!!! error TS2345: Types of property 'thunk' are incompatible. -!!! error TS2345: Type '(num: number) => void' is not assignable to type '(str: string) => void'. -!!! error TS2345: Types of parameters 'num' and 'str' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'number'. test({ // Should be OK. Last 'thunk' is of correct type thunk: (num: number) => {}, diff --git a/tests/baselines/reference/mappedTypeErrors.errors.txt b/tests/baselines/reference/mappedTypeErrors.errors.txt index 99d8f9c7ad1..6d78b229fa4 100644 --- a/tests/baselines/reference/mappedTypeErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeErrors.errors.txt @@ -27,14 +27,10 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(77,59): error TS2345: A Object literal may only specify known properties, and 'z' does not exist in type 'Readonly<{ x: number; y: number; }>'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(83,58): error TS2345: Argument of type '{ x: number; y: number; z: number; }' is not assignable to parameter of type 'Partial<{ x: number; y: number; }>'. Object literal may only specify known properties, and 'z' does not exist in type 'Partial<{ x: number; y: number; }>'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(105,15): error TS2345: Argument of type '{ a: undefined; }' is not assignable to parameter of type 'Pick'. - Types of property 'a' are incompatible. - Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(105,17): error TS2322: Type 'undefined' is not assignable to type 'string'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(106,17): error TS2345: Argument of type '{ c: boolean; }' is not assignable to parameter of type 'Pick'. Object literal may only specify known properties, and 'c' does not exist in type 'Pick'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(123,12): error TS2345: Argument of type '{ a: undefined; }' is not assignable to parameter of type 'Pick'. - Types of property 'a' are incompatible. - Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(123,14): error TS2322: Type 'undefined' is not assignable to type 'string'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(124,14): error TS2345: Argument of type '{ c: boolean; }' is not assignable to parameter of type 'Pick'. Object literal may only specify known properties, and 'c' does not exist in type 'Pick'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(128,16): error TS2322: Type 'string' is not assignable to type 'number | undefined'. @@ -196,10 +192,9 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,21): error TS2536: setState(foo, { }); setState(foo, foo); setState(foo, { a: undefined }); // Error - ~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ a: undefined; }' is not assignable to parameter of type 'Pick'. -!!! error TS2345: Types of property 'a' are incompatible. -!!! error TS2345: Type 'undefined' is not assignable to type 'string'. + ~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/types/mapped/mappedTypeErrors.ts:89:5: The expected type comes from property 'a' which is declared here on type 'Pick' setState(foo, { c: true }); // Error ~~~~~~~ !!! error TS2345: Argument of type '{ c: boolean; }' is not assignable to parameter of type 'Pick'. @@ -221,10 +216,9 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,21): error TS2536: c.setState({ }); c.setState(foo); c.setState({ a: undefined }); // Error - ~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ a: undefined; }' is not assignable to parameter of type 'Pick'. -!!! error TS2345: Types of property 'a' are incompatible. -!!! error TS2345: Type 'undefined' is not assignable to type 'string'. + ~ +!!! error TS2322: Type 'undefined' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/types/mapped/mappedTypeErrors.ts:89:5: The expected type comes from property 'a' which is declared here on type 'Pick' c.setState({ c: true }); // Error ~~~~~~~ !!! error TS2345: Argument of type '{ c: boolean; }' is not assignable to parameter of type 'Pick'. diff --git a/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt b/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt index 28bc188f7b6..41edb0f6924 100644 --- a/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeInferenceErrors.errors.txt @@ -1,9 +1,4 @@ -tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: number; baz: {}; }>'. - Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; }'. - Types of property 'computed' are incompatible. - Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: number; baz: {}; }>'. - Types of property 'baz' are incompatible. - Type 'number' is not assignable to type '() => {}'. +tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(16,9): error TS2322: Type 'number' is not assignable to type '() => {}'. ==== tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts (1 errors) ==== @@ -16,29 +11,16 @@ tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS declare function foo(options: { props: P, computed: ComputedOf } & ThisType

): void; foo({ - ~ props: { x: 10, y: 20 }, - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ computed: { - ~~~~~~~~~~~~~~~ bar(): number { - ~~~~~~~~~~~~~~~~~~~~~~~ let z = this.bar; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return 42; - ~~~~~~~~~~~~~~~~~~~~~~ }, - ~~~~~~~~~~ baz: 42 - ~~~~~~~~~~~~~~~ + ~~~ +!!! error TS2322: Type 'number' is not assignable to type '() => {}'. +!!! related TS6500 tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts:16:9: The expected type comes from property 'baz' which is declared here on type 'ComputedOf<{ bar: number; baz: {}; }>' } - ~~~~~ }); - ~ -!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: number; baz: {}; }>'. -!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; }'. -!!! error TS2345: Types of property 'computed' are incompatible. -!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: number; baz: {}; }>'. -!!! error TS2345: Types of property 'baz' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type '() => {}'. \ No newline at end of file diff --git a/tests/baselines/reference/objectLitTargetTypeCallSite.errors.txt b/tests/baselines/reference/objectLitTargetTypeCallSite.errors.txt index 0d064af3935..6ced1a767de 100644 --- a/tests/baselines/reference/objectLitTargetTypeCallSite.errors.txt +++ b/tests/baselines/reference/objectLitTargetTypeCallSite.errors.txt @@ -1,6 +1,4 @@ -tests/cases/compiler/objectLitTargetTypeCallSite.ts(5,9): error TS2345: Argument of type '{ a: boolean; b: string; }' is not assignable to parameter of type '{ a: number; b: string; }'. - Types of property 'a' are incompatible. - Type 'boolean' is not assignable to type 'number'. +tests/cases/compiler/objectLitTargetTypeCallSite.ts(5,10): error TS2322: Type 'true' is not assignable to type 'number'. ==== tests/cases/compiler/objectLitTargetTypeCallSite.ts (1 errors) ==== @@ -9,7 +7,6 @@ tests/cases/compiler/objectLitTargetTypeCallSite.ts(5,9): error TS2345: Argument } process({a:true,b:"y"}); - ~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ a: boolean; b: string; }' is not assignable to parameter of type '{ a: number; b: string; }'. -!!! error TS2345: Types of property 'a' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file + ~ +!!! error TS2322: Type 'true' is not assignable to type 'number'. +!!! related TS6500 tests/cases/compiler/objectLitTargetTypeCallSite.ts:1:23: The expected type comes from property 'a' which is declared here on type '{ a: number; b: string; }' \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralFunctionArgContextualTyping2.errors.txt b/tests/baselines/reference/objectLiteralFunctionArgContextualTyping2.errors.txt index 0117d2c0c8c..9fa7176779f 100644 --- a/tests/baselines/reference/objectLiteralFunctionArgContextualTyping2.errors.txt +++ b/tests/baselines/reference/objectLiteralFunctionArgContextualTyping2.errors.txt @@ -4,12 +4,9 @@ tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(9,4): error TS Property 'doStuff' is missing in type '{ value: string; }'. tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(10,17): error TS2345: Argument of type '{ value: string; what: number; }' is not assignable to parameter of type 'I2'. Object literal may only specify known properties, and 'what' does not exist in type 'I2'. -tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(11,6): error TS2345: Argument of type '{ toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. - Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. -tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(12,6): error TS2345: Argument of type '{ toString: (s: string) => string; }' is not assignable to parameter of type 'I2'. - Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. -tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,17): error TS2345: Argument of type '{ value: string; toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. - Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. +tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(11,6): error TS2322: Type '(s: any) => any' is not assignable to type '() => string'. +tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(12,6): error TS2322: Type '(s: string) => string' is not assignable to type '() => string'. +tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,17): error TS2322: Type '(s: any) => any' is not assignable to type '() => string'. ==== tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts (6 errors) ==== @@ -33,14 +30,14 @@ tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,17): error !!! error TS2345: Argument of type '{ value: string; what: number; }' is not assignable to parameter of type 'I2'. !!! error TS2345: Object literal may only specify known properties, and 'what' does not exist in type 'I2'. f2({ toString: (s) => s }) - ~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. -!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. + ~~~~~~~~ +!!! error TS2322: Type '(s: any) => any' is not assignable to type '() => string'. +!!! related TS6500 /.ts/lib.es5.d.ts:125:5: The expected type comes from property 'toString' which is declared here on type 'I2' f2({ toString: (s: string) => s }) - ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ toString: (s: string) => string; }' is not assignable to parameter of type 'I2'. -!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. + ~~~~~~~~ +!!! error TS2322: Type '(s: string) => string' is not assignable to type '() => string'. +!!! related TS6500 /.ts/lib.es5.d.ts:125:5: The expected type comes from property 'toString' which is declared here on type 'I2' f2({ value: '', toString: (s) => s.uhhh }) - ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ value: string; toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. -!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. \ No newline at end of file + ~~~~~~~~ +!!! error TS2322: Type '(s: any) => any' is not assignable to type '() => string'. +!!! related TS6500 /.ts/lib.es5.d.ts:125:5: The expected type comes from property 'toString' which is declared here on type 'I2' \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentError.errors.txt b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentError.errors.txt index e36842e4f69..7a425857bd6 100644 --- a/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentError.errors.txt +++ b/tests/baselines/reference/objectLiteralShorthandPropertiesAssignmentError.errors.txt @@ -2,9 +2,7 @@ tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPr Object literal may only specify known properties, and 'name' does not exist in type '{ b: string; id: number; }'. tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(6,81): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(6,87): error TS2322: Type 'number' is not assignable to type 'string'. -tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(8,5): error TS2345: Argument of type '{ name: string; id: number; }' is not assignable to parameter of type '{ name: string; id: boolean; }'. - Types of property 'id' are incompatible. - Type 'number' is not assignable to type 'boolean'. +tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts(8,13): error TS2322: Type 'number' is not assignable to type 'boolean'. ==== tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts (4 errors) ==== @@ -25,9 +23,8 @@ tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPr !!! related TS6500 tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts:6:43: The expected type comes from property 'id' which is declared here on type '{ id: string; name: number; }' function bar(obj: { name: string; id: boolean }) { } bar({ name, id }); // error - ~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ name: string; id: number; }' is not assignable to parameter of type '{ name: string; id: boolean; }'. -!!! error TS2345: Types of property 'id' are incompatible. -!!! error TS2345: Type 'number' is not assignable to type 'boolean'. + ~~ +!!! error TS2322: Type 'number' is not assignable to type 'boolean'. +!!! related TS6500 tests/cases/conformance/es6/shorthandPropertyAssignment/objectLiteralShorthandPropertiesAssignmentError.ts:7:35: The expected type comes from property 'id' which is declared here on type '{ name: string; id: boolean; }' \ No newline at end of file diff --git a/tests/baselines/reference/optionalBindingParameters1.errors.txt b/tests/baselines/reference/optionalBindingParameters1.errors.txt index f78f691d6eb..9ecf802f043 100644 --- a/tests/baselines/reference/optionalBindingParameters1.errors.txt +++ b/tests/baselines/reference/optionalBindingParameters1.errors.txt @@ -1,9 +1,9 @@ tests/cases/conformance/es6/destructuring/optionalBindingParameters1.ts(1,14): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. -tests/cases/conformance/es6/destructuring/optionalBindingParameters1.ts(7,5): error TS2345: Argument of type '[boolean, number, string]' is not assignable to parameter of type '[string, number, boolean]'. - Type 'boolean' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/optionalBindingParameters1.ts(7,6): error TS2322: Type 'false' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/optionalBindingParameters1.ts(7,16): error TS2322: Type 'string' is not assignable to type 'boolean'. -==== tests/cases/conformance/es6/destructuring/optionalBindingParameters1.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/optionalBindingParameters1.ts (3 errors) ==== function foo([x,y,z]?: [string, number, boolean]) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2463: A binding pattern parameter cannot be optional in an implementation signature. @@ -13,6 +13,7 @@ tests/cases/conformance/es6/destructuring/optionalBindingParameters1.ts(7,5): er foo(["", 0, false]); foo([false, 0, ""]); - ~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[boolean, number, string]' is not assignable to parameter of type '[string, number, boolean]'. -!!! error TS2345: Type 'boolean' is not assignable to type 'string'. \ No newline at end of file + ~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'string'. + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. \ No newline at end of file diff --git a/tests/baselines/reference/optionalBindingParameters2.errors.txt b/tests/baselines/reference/optionalBindingParameters2.errors.txt index f8b1aa73b2a..80f93ca8b64 100644 --- a/tests/baselines/reference/optionalBindingParameters2.errors.txt +++ b/tests/baselines/reference/optionalBindingParameters2.errors.txt @@ -1,10 +1,9 @@ tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts(1,14): error TS2463: A binding pattern parameter cannot be optional in an implementation signature. -tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts(7,5): error TS2345: Argument of type '{ x: boolean; y: number; z: string; }' is not assignable to parameter of type '{ x: string; y: number; z: boolean; }'. - Types of property 'x' are incompatible. - Type 'boolean' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts(7,7): error TS2322: Type 'false' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts(7,23): error TS2322: Type 'string' is not assignable to type 'boolean'. -==== tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts (2 errors) ==== +==== tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts (3 errors) ==== function foo({ x, y, z }?: { x: string; y: number; z: boolean }) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2463: A binding pattern parameter cannot be optional in an implementation signature. @@ -14,7 +13,9 @@ tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts(7,5): er foo({ x: "", y: 0, z: false }); foo({ x: false, y: 0, z: "" }); - ~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: boolean; y: number; z: string; }' is not assignable to parameter of type '{ x: string; y: number; z: boolean; }'. -!!! error TS2345: Types of property 'x' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'string'. \ No newline at end of file + ~ +!!! error TS2322: Type 'false' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts:1:30: The expected type comes from property 'x' which is declared here on type '{ x: string; y: number; z: boolean; }' + ~ +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/optionalBindingParameters2.ts:1:52: The expected type comes from property 'z' which is declared here on type '{ x: string; y: number; z: boolean; }' \ No newline at end of file diff --git a/tests/baselines/reference/optionalBindingParametersInOverloads1.errors.txt b/tests/baselines/reference/optionalBindingParametersInOverloads1.errors.txt index d8e1c3c4aa6..5401ef79f2b 100644 --- a/tests/baselines/reference/optionalBindingParametersInOverloads1.errors.txt +++ b/tests/baselines/reference/optionalBindingParametersInOverloads1.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads1.ts(8,5): error TS2345: Argument of type '[boolean, number, string]' is not assignable to parameter of type '[string, number, boolean]'. - Type 'boolean' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads1.ts(8,6): error TS2322: Type 'false' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads1.ts(8,16): error TS2322: Type 'string' is not assignable to type 'boolean'. -==== tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads1.ts (1 errors) ==== +==== tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads1.ts (2 errors) ==== function foo([x, y, z] ?: [string, number, boolean]); function foo(...rest: any[]) { @@ -11,6 +11,7 @@ tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads1. foo(["", 0, false]); foo([false, 0, ""]); - ~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[boolean, number, string]' is not assignable to parameter of type '[string, number, boolean]'. -!!! error TS2345: Type 'boolean' is not assignable to type 'string'. \ No newline at end of file + ~~~~~ +!!! error TS2322: Type 'false' is not assignable to type 'string'. + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. \ No newline at end of file diff --git a/tests/baselines/reference/optionalBindingParametersInOverloads2.errors.txt b/tests/baselines/reference/optionalBindingParametersInOverloads2.errors.txt index acc5c3721bb..86913394da6 100644 --- a/tests/baselines/reference/optionalBindingParametersInOverloads2.errors.txt +++ b/tests/baselines/reference/optionalBindingParametersInOverloads2.errors.txt @@ -1,9 +1,8 @@ -tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads2.ts(8,5): error TS2345: Argument of type '{ x: boolean; y: number; z: string; }' is not assignable to parameter of type '{ x: string; y: number; z: boolean; }'. - Types of property 'x' are incompatible. - Type 'boolean' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads2.ts(8,7): error TS2322: Type 'false' is not assignable to type 'string'. +tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads2.ts(8,23): error TS2322: Type 'string' is not assignable to type 'boolean'. -==== tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads2.ts (1 errors) ==== +==== tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads2.ts (2 errors) ==== function foo({ x, y, z }?: { x: string; y: number; z: boolean }); function foo(...rest: any[]) { @@ -12,7 +11,9 @@ tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads2. foo({ x: "", y: 0, z: false }); foo({ x: false, y: 0, z: "" }); - ~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ x: boolean; y: number; z: string; }' is not assignable to parameter of type '{ x: string; y: number; z: boolean; }'. -!!! error TS2345: Types of property 'x' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'string'. \ No newline at end of file + ~ +!!! error TS2322: Type 'false' is not assignable to type 'string'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads2.ts:1:30: The expected type comes from property 'x' which is declared here on type '{ x: string; y: number; z: boolean; }' + ~ +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. +!!! related TS6500 tests/cases/conformance/es6/destructuring/optionalBindingParametersInOverloads2.ts:1:52: The expected type comes from property 'z' which is declared here on type '{ x: string; y: number; z: boolean; }' \ No newline at end of file diff --git a/tests/baselines/reference/overloadResolutionTest1.errors.txt b/tests/baselines/reference/overloadResolutionTest1.errors.txt index b36684db501..53ee7873472 100644 --- a/tests/baselines/reference/overloadResolutionTest1.errors.txt +++ b/tests/baselines/reference/overloadResolutionTest1.errors.txt @@ -2,12 +2,8 @@ tests/cases/compiler/overloadResolutionTest1.ts(7,16): error TS2345: Argument of Type '{ a: string; }' is not assignable to type '{ a: boolean; }'. Types of property 'a' are incompatible. Type 'string' is not assignable to type 'boolean'. -tests/cases/compiler/overloadResolutionTest1.ts(18,15): error TS2345: Argument of type '{ a: string; }' is not assignable to parameter of type '{ a: boolean; }'. - Types of property 'a' are incompatible. - Type 'string' is not assignable to type 'boolean'. -tests/cases/compiler/overloadResolutionTest1.ts(24,14): error TS2345: Argument of type '{ a: boolean; }' is not assignable to parameter of type '{ a: string; }'. - Types of property 'a' are incompatible. - Type 'boolean' is not assignable to type 'string'. +tests/cases/compiler/overloadResolutionTest1.ts(18,16): error TS2322: Type 'string' is not assignable to type 'boolean'. +tests/cases/compiler/overloadResolutionTest1.ts(24,15): error TS2322: Type 'true' is not assignable to type 'string'. ==== tests/cases/compiler/overloadResolutionTest1.ts (3 errors) ==== @@ -34,17 +30,15 @@ tests/cases/compiler/overloadResolutionTest1.ts(24,14): error TS2345: Argument o var x2 = foo2({a:0}); // works var x3 = foo2({a:true}); // works var x4 = foo2({a:"s"}); // error - ~~~~~~~ -!!! error TS2345: Argument of type '{ a: string; }' is not assignable to parameter of type '{ a: boolean; }'. -!!! error TS2345: Types of property 'a' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'boolean'. + ~ +!!! error TS2322: Type 'string' is not assignable to type 'boolean'. +!!! related TS6500 tests/cases/compiler/overloadResolutionTest1.ts:13:20: The expected type comes from property 'a' which is declared here on type '{ a: boolean; }' function foo4(bar:{a:number;}):number; function foo4(bar:{a:string;}):string; function foo4(bar:{a:any;}):any{ return bar }; var x = foo4({a:true}); // error - ~~~~~~~~ -!!! error TS2345: Argument of type '{ a: boolean; }' is not assignable to parameter of type '{ a: string; }'. -!!! error TS2345: Types of property 'a' are incompatible. -!!! error TS2345: Type 'boolean' is not assignable to type 'string'. \ No newline at end of file + ~ +!!! error TS2322: Type 'true' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/overloadResolutionTest1.ts:22:20: The expected type comes from property 'a' which is declared here on type '{ a: string; }' \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterAsTypeParameterConstraint2.errors.txt b/tests/baselines/reference/typeParameterAsTypeParameterConstraint2.errors.txt index 08706d095b2..8f286e39863 100644 --- a/tests/baselines/reference/typeParameterAsTypeParameterConstraint2.errors.txt +++ b/tests/baselines/reference/typeParameterAsTypeParameterConstraint2.errors.txt @@ -1,12 +1,8 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts(6,8): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'. tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts(7,8): error TS2345: Argument of type '{}' is not assignable to parameter of type 'number'. tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts(13,17): error TS2345: Argument of type 'NumberVariant' is not assignable to parameter of type 'number'. -tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts(16,9): error TS2345: Argument of type '{ length: string; }' is not assignable to parameter of type '{ length: number; }'. - Types of property 'length' are incompatible. - Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts(17,9): error TS2345: Argument of type '{ length: {}; }' is not assignable to parameter of type '{ length: number; }'. - Types of property 'length' are incompatible. - Type '{}' is not assignable to type 'number'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts(16,11): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts(17,11): error TS2322: Type '{}' is not assignable to type 'number'. tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts(18,10): error TS2345: Argument of type 'string[]' is not assignable to parameter of type '{ length: any[]; }'. Types of property 'length' are incompatible. Type 'number' is not assignable to type 'any[]'. @@ -35,15 +31,13 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTy function foo2(x: T, y: U) { return y; } // this is now an error foo2(1, { length: '' }); - ~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ length: string; }' is not assignable to parameter of type '{ length: number; }'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type 'string' is not assignable to type 'number'. + ~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts:15:30: The expected type comes from property 'length' which is declared here on type '{ length: number; }' foo2(1, { length: {} }); - ~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ length: {}; }' is not assignable to parameter of type '{ length: number; }'. -!!! error TS2345: Types of property 'length' are incompatible. -!!! error TS2345: Type '{}' is not assignable to type 'number'. + ~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'number'. +!!! related TS6500 tests/cases/conformance/types/typeParameters/typeArgumentLists/typeParameterAsTypeParameterConstraint2.ts:15:30: The expected type comes from property 'length' which is declared here on type '{ length: number; }' foo2([], ['']); ~~~~ !!! error TS2345: Argument of type 'string[]' is not assignable to parameter of type '{ length: any[]; }'. diff --git a/tests/baselines/reference/wrappedAndRecursiveConstraints4.errors.txt b/tests/baselines/reference/wrappedAndRecursiveConstraints4.errors.txt index 47e8e6ff4f2..65bfc5b20d5 100644 --- a/tests/baselines/reference/wrappedAndRecursiveConstraints4.errors.txt +++ b/tests/baselines/reference/wrappedAndRecursiveConstraints4.errors.txt @@ -1,4 +1,5 @@ -tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints4.ts(13,12): error TS2345: Argument of type '{ length: number; charAt: (x: number) => void; }' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints4.ts(13,25): error TS2322: Type '(x: number) => void' is not assignable to type '(pos: number) => string'. + Type 'void' is not assignable to type 'string'. ==== tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursiveConstraints4.ts (1 errors) ==== @@ -15,5 +16,7 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/wrappedAndRecursi var c = new C({ length: 2 }); var r = c.foo(''); var r2 = r({ length: 3, charAt: (x: number) => { '' } }); // error - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ length: number; charAt: (x: number) => void; }' is not assignable to parameter of type 'string'. \ No newline at end of file + ~~~~~~ +!!! error TS2322: Type '(x: number) => void' is not assignable to type '(pos: number) => string'. +!!! error TS2322: Type 'void' is not assignable to type 'string'. +!!! related TS6500 /.ts/lib.es5.d.ts:332:5: The expected type comes from property 'charAt' which is declared here on type 'string' \ No newline at end of file From b687caf3ebf34fc8b42580d3eacdc0daf4fcd0f9 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 30 Aug 2018 16:16:58 -0700 Subject: [PATCH 125/163] No excess property error for spread properties (#26798) That is, properties in an object literal type that came from a spread assignment never cause an excess property error. --- src/compiler/checker.ts | 6 +- .../reference/objectSpreadNegative.errors.txt | 27 +-------- .../reference/objectSpreadNegative.js | 16 ------ .../reference/objectSpreadNegative.symbols | 47 --------------- .../reference/objectSpreadNegative.types | 57 ------------------- .../reference/spreadExcessProperty.js | 20 +++++++ .../reference/spreadExcessProperty.symbols | 17 ++++++ .../reference/spreadExcessProperty.types | 21 +++++++ .../types/spread/objectSpreadNegative.ts | 10 ---- .../types/spread/spreadExcessProperty.ts | 3 + 10 files changed, 67 insertions(+), 157 deletions(-) create mode 100644 tests/baselines/reference/spreadExcessProperty.js create mode 100644 tests/baselines/reference/spreadExcessProperty.symbols create mode 100644 tests/baselines/reference/spreadExcessProperty.types create mode 100644 tests/cases/conformance/types/spread/spreadExcessProperty.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bf268984a18..ad09d843248 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11328,7 +11328,7 @@ namespace ts { return hasExcessProperties(source, discriminant, /*discriminant*/ undefined, reportErrors); } for (const prop of getPropertiesOfObjectType(source)) { - if (!isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { + if (!isPropertyFromSpread(prop, source.symbol) && !isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { if (reportErrors) { // We know *exactly* where things went wrong when comparing the types. // Use this property as the error node as this will be more helpful in @@ -11372,6 +11372,10 @@ namespace ts { return false; } + function isPropertyFromSpread(prop: Symbol, container: Symbol) { + return prop.valueDeclaration && container.valueDeclaration && prop.valueDeclaration.parent !== container.valueDeclaration; + } + function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType): Ternary { let result = Ternary.True; const sourceTypes = source.types; diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index 92225755c71..1af05906873 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -18,15 +18,9 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(53,9): error TS2339 tests/cases/conformance/types/spread/objectSpreadNegative.ts(58,11): error TS2339: Property 'a' does not exist on type '{}'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(62,14): error TS2698: Spread types may only be created from object types. tests/cases/conformance/types/spread/objectSpreadNegative.ts(65,14): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(79,37): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. - Object literal may only specify known properties, and 'extra' does not exist in type 'A'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(82,7): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. - Object literal may only specify known properties, and 'extra' does not exist in type 'A'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(84,7): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. - Object literal may only specify known properties, and 'extra' does not exist in type 'A'. -==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (20 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (17 errors) ==== let o = { a: 1, b: 'no' } /// private propagates @@ -138,23 +132,4 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(84,7): error TS2322 f({ a: 1 }, { a: 'mismatch' }) let overwriteId: { id: string, a: number, c: number, d: string } = f({ a: 1, id: true }, { c: 1, d: 'no' }) - - // excess property checks - type A = { a: string, b: string }; - type Extra = { a: string, b: string, extra: string }; - const extra1: A = { a: "a", b: "b", extra: "extra" }; - ~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. -!!! error TS2322: Object literal may only specify known properties, and 'extra' does not exist in type 'A'. - const extra2 = { a: "a", b: "b", extra: "extra" }; - const a1: A = { ...extra1 }; // error spans should be here - const a2: A = { ...extra2 }; // not on the symbol declarations above - ~~ -!!! error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. -!!! error TS2322: Object literal may only specify known properties, and 'extra' does not exist in type 'A'. - const extra3: Extra = { a: "a", b: "b", extra: "extra" }; - const a3: A = { ...extra3 }; // same here - ~~ -!!! error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. -!!! error TS2322: Object literal may only specify known properties, and 'extra' does not exist in type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index 63ae8914385..35d8cdf9830 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -73,16 +73,6 @@ let overlapConflict: { id:string, a: string } = f({ a: 1 }, { a: 'mismatch' }) let overwriteId: { id: string, a: number, c: number, d: string } = f({ a: 1, id: true }, { c: 1, d: 'no' }) - -// excess property checks -type A = { a: string, b: string }; -type Extra = { a: string, b: string, extra: string }; -const extra1: A = { a: "a", b: "b", extra: "extra" }; -const extra2 = { a: "a", b: "b", extra: "extra" }; -const a1: A = { ...extra1 }; // error spans should be here -const a2: A = { ...extra2 }; // not on the symbol declarations above -const extra3: Extra = { a: "a", b: "b", extra: "extra" }; -const a3: A = { ...extra3 }; // same here //// [objectSpreadNegative.js] @@ -167,9 +157,3 @@ var exclusive = f({ a: 1, b: 'yes' }, { c: 'no', d: false }); var overlap = f({ a: 1 }, { a: 2, b: 'extra' }); var overlapConflict = f({ a: 1 }, { a: 'mismatch' }); var overwriteId = f({ a: 1, id: true }, { c: 1, d: 'no' }); -var extra1 = { a: "a", b: "b", extra: "extra" }; -var extra2 = { a: "a", b: "b", extra: "extra" }; -var a1 = __assign({}, extra1); // error spans should be here -var a2 = __assign({}, extra2); // not on the symbol declarations above -var extra3 = { a: "a", b: "b", extra: "extra" }; -var a3 = __assign({}, extra3); // same here diff --git a/tests/baselines/reference/objectSpreadNegative.symbols b/tests/baselines/reference/objectSpreadNegative.symbols index 21af20facbb..4bff16d9be6 100644 --- a/tests/baselines/reference/objectSpreadNegative.symbols +++ b/tests/baselines/reference/objectSpreadNegative.symbols @@ -243,50 +243,3 @@ let overwriteId: { id: string, a: number, c: number, d: string } = >c : Symbol(c, Decl(objectSpreadNegative.ts, 73, 27)) >d : Symbol(d, Decl(objectSpreadNegative.ts, 73, 33)) -// excess property checks -type A = { a: string, b: string }; ->A : Symbol(A, Decl(objectSpreadNegative.ts, 73, 44)) ->a : Symbol(a, Decl(objectSpreadNegative.ts, 76, 10)) ->b : Symbol(b, Decl(objectSpreadNegative.ts, 76, 21)) - -type Extra = { a: string, b: string, extra: string }; ->Extra : Symbol(Extra, Decl(objectSpreadNegative.ts, 76, 34)) ->a : Symbol(a, Decl(objectSpreadNegative.ts, 77, 14)) ->b : Symbol(b, Decl(objectSpreadNegative.ts, 77, 25)) ->extra : Symbol(extra, Decl(objectSpreadNegative.ts, 77, 36)) - -const extra1: A = { a: "a", b: "b", extra: "extra" }; ->extra1 : Symbol(extra1, Decl(objectSpreadNegative.ts, 78, 5)) ->A : Symbol(A, Decl(objectSpreadNegative.ts, 73, 44)) ->a : Symbol(a, Decl(objectSpreadNegative.ts, 78, 19)) ->b : Symbol(b, Decl(objectSpreadNegative.ts, 78, 27)) ->extra : Symbol(extra, Decl(objectSpreadNegative.ts, 78, 35)) - -const extra2 = { a: "a", b: "b", extra: "extra" }; ->extra2 : Symbol(extra2, Decl(objectSpreadNegative.ts, 79, 5)) ->a : Symbol(a, Decl(objectSpreadNegative.ts, 79, 16)) ->b : Symbol(b, Decl(objectSpreadNegative.ts, 79, 24)) ->extra : Symbol(extra, Decl(objectSpreadNegative.ts, 79, 32)) - -const a1: A = { ...extra1 }; // error spans should be here ->a1 : Symbol(a1, Decl(objectSpreadNegative.ts, 80, 5)) ->A : Symbol(A, Decl(objectSpreadNegative.ts, 73, 44)) ->extra1 : Symbol(extra1, Decl(objectSpreadNegative.ts, 78, 5)) - -const a2: A = { ...extra2 }; // not on the symbol declarations above ->a2 : Symbol(a2, Decl(objectSpreadNegative.ts, 81, 5)) ->A : Symbol(A, Decl(objectSpreadNegative.ts, 73, 44)) ->extra2 : Symbol(extra2, Decl(objectSpreadNegative.ts, 79, 5)) - -const extra3: Extra = { a: "a", b: "b", extra: "extra" }; ->extra3 : Symbol(extra3, Decl(objectSpreadNegative.ts, 82, 5)) ->Extra : Symbol(Extra, Decl(objectSpreadNegative.ts, 76, 34)) ->a : Symbol(a, Decl(objectSpreadNegative.ts, 82, 23)) ->b : Symbol(b, Decl(objectSpreadNegative.ts, 82, 31)) ->extra : Symbol(extra, Decl(objectSpreadNegative.ts, 82, 39)) - -const a3: A = { ...extra3 }; // same here ->a3 : Symbol(a3, Decl(objectSpreadNegative.ts, 83, 5)) ->A : Symbol(A, Decl(objectSpreadNegative.ts, 73, 44)) ->extra3 : Symbol(extra3, Decl(objectSpreadNegative.ts, 82, 5)) - diff --git a/tests/baselines/reference/objectSpreadNegative.types b/tests/baselines/reference/objectSpreadNegative.types index 0d0eab1c35d..26fd5642d23 100644 --- a/tests/baselines/reference/objectSpreadNegative.types +++ b/tests/baselines/reference/objectSpreadNegative.types @@ -325,60 +325,3 @@ let overwriteId: { id: string, a: number, c: number, d: string } = >d : string >'no' : "no" -// excess property checks -type A = { a: string, b: string }; ->A : A ->a : string ->b : string - -type Extra = { a: string, b: string, extra: string }; ->Extra : Extra ->a : string ->b : string ->extra : string - -const extra1: A = { a: "a", b: "b", extra: "extra" }; ->extra1 : A ->{ a: "a", b: "b", extra: "extra" } : { a: string; b: string; extra: string; } ->a : string ->"a" : "a" ->b : string ->"b" : "b" ->extra : string ->"extra" : "extra" - -const extra2 = { a: "a", b: "b", extra: "extra" }; ->extra2 : { a: string; b: string; extra: string; } ->{ a: "a", b: "b", extra: "extra" } : { a: string; b: string; extra: string; } ->a : string ->"a" : "a" ->b : string ->"b" : "b" ->extra : string ->"extra" : "extra" - -const a1: A = { ...extra1 }; // error spans should be here ->a1 : A ->{ ...extra1 } : { a: string; b: string; } ->extra1 : A - -const a2: A = { ...extra2 }; // not on the symbol declarations above ->a2 : A ->{ ...extra2 } : { a: string; b: string; extra: string; } ->extra2 : { a: string; b: string; extra: string; } - -const extra3: Extra = { a: "a", b: "b", extra: "extra" }; ->extra3 : Extra ->{ a: "a", b: "b", extra: "extra" } : { a: string; b: string; extra: string; } ->a : string ->"a" : "a" ->b : string ->"b" : "b" ->extra : string ->"extra" : "extra" - -const a3: A = { ...extra3 }; // same here ->a3 : A ->{ ...extra3 } : { a: string; b: string; extra: string; } ->extra3 : Extra - diff --git a/tests/baselines/reference/spreadExcessProperty.js b/tests/baselines/reference/spreadExcessProperty.js new file mode 100644 index 00000000000..c5bf845224c --- /dev/null +++ b/tests/baselines/reference/spreadExcessProperty.js @@ -0,0 +1,20 @@ +//// [spreadExcessProperty.ts] +type A = { a: string, b: string }; +const extra1 = { a: "a", b: "b", extra: "extra" }; +const a1: A = { ...extra1 }; // spread should not give excess property errors + + +//// [spreadExcessProperty.js] +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +var extra1 = { a: "a", b: "b", extra: "extra" }; +var a1 = __assign({}, extra1); // spread should not give excess property errors diff --git a/tests/baselines/reference/spreadExcessProperty.symbols b/tests/baselines/reference/spreadExcessProperty.symbols new file mode 100644 index 00000000000..bc4ef206643 --- /dev/null +++ b/tests/baselines/reference/spreadExcessProperty.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/types/spread/spreadExcessProperty.ts === +type A = { a: string, b: string }; +>A : Symbol(A, Decl(spreadExcessProperty.ts, 0, 0)) +>a : Symbol(a, Decl(spreadExcessProperty.ts, 0, 10)) +>b : Symbol(b, Decl(spreadExcessProperty.ts, 0, 21)) + +const extra1 = { a: "a", b: "b", extra: "extra" }; +>extra1 : Symbol(extra1, Decl(spreadExcessProperty.ts, 1, 5)) +>a : Symbol(a, Decl(spreadExcessProperty.ts, 1, 16)) +>b : Symbol(b, Decl(spreadExcessProperty.ts, 1, 24)) +>extra : Symbol(extra, Decl(spreadExcessProperty.ts, 1, 32)) + +const a1: A = { ...extra1 }; // spread should not give excess property errors +>a1 : Symbol(a1, Decl(spreadExcessProperty.ts, 2, 5)) +>A : Symbol(A, Decl(spreadExcessProperty.ts, 0, 0)) +>extra1 : Symbol(extra1, Decl(spreadExcessProperty.ts, 1, 5)) + diff --git a/tests/baselines/reference/spreadExcessProperty.types b/tests/baselines/reference/spreadExcessProperty.types new file mode 100644 index 00000000000..015c7cc85aa --- /dev/null +++ b/tests/baselines/reference/spreadExcessProperty.types @@ -0,0 +1,21 @@ +=== tests/cases/conformance/types/spread/spreadExcessProperty.ts === +type A = { a: string, b: string }; +>A : A +>a : string +>b : string + +const extra1 = { a: "a", b: "b", extra: "extra" }; +>extra1 : { a: string; b: string; extra: string; } +>{ a: "a", b: "b", extra: "extra" } : { a: string; b: string; extra: string; } +>a : string +>"a" : "a" +>b : string +>"b" : "b" +>extra : string +>"extra" : "extra" + +const a1: A = { ...extra1 }; // spread should not give excess property errors +>a1 : A +>{ ...extra1 } : { a: string; b: string; extra: string; } +>extra1 : { a: string; b: string; extra: string; } + diff --git a/tests/cases/conformance/types/spread/objectSpreadNegative.ts b/tests/cases/conformance/types/spread/objectSpreadNegative.ts index b6e7c5b88c9..789016762da 100644 --- a/tests/cases/conformance/types/spread/objectSpreadNegative.ts +++ b/tests/cases/conformance/types/spread/objectSpreadNegative.ts @@ -73,13 +73,3 @@ let overlapConflict: { id:string, a: string } = f({ a: 1 }, { a: 'mismatch' }) let overwriteId: { id: string, a: number, c: number, d: string } = f({ a: 1, id: true }, { c: 1, d: 'no' }) - -// excess property checks -type A = { a: string, b: string }; -type Extra = { a: string, b: string, extra: string }; -const extra1: A = { a: "a", b: "b", extra: "extra" }; -const extra2 = { a: "a", b: "b", extra: "extra" }; -const a1: A = { ...extra1 }; // error spans should be here -const a2: A = { ...extra2 }; // not on the symbol declarations above -const extra3: Extra = { a: "a", b: "b", extra: "extra" }; -const a3: A = { ...extra3 }; // same here diff --git a/tests/cases/conformance/types/spread/spreadExcessProperty.ts b/tests/cases/conformance/types/spread/spreadExcessProperty.ts new file mode 100644 index 00000000000..b5b304e2ff7 --- /dev/null +++ b/tests/cases/conformance/types/spread/spreadExcessProperty.ts @@ -0,0 +1,3 @@ +type A = { a: string, b: string }; +const extra1 = { a: "a", b: "b", extra: "extra" }; +const a1: A = { ...extra1 }; // spread should not give excess property errors From 64bbf8925cc91e4fd528584ab9984b7a13f014f0 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Thu, 30 Aug 2018 16:53:46 -0700 Subject: [PATCH 126/163] Allow for undefined in type --- src/services/codefixes/convertToAsyncFunction.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 6162e311266..76cdf471466 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -43,7 +43,7 @@ namespace ts.codefix { function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void { // get the function declaration - returns a promise const tokenAtPosition = getTokenAtPosition(sourceFile, position); - let functionToConvert: FunctionLikeDeclaration; + let functionToConvert: FunctionLikeDeclaration | undefined; // if the parent of a FunctionLikeDeclaration is a variable declaration, the convertToAsync diagnostic will be reported on the variable name if (isIdentifier(tokenAtPosition) && isVariableDeclaration(tokenAtPosition.parent) && @@ -51,7 +51,7 @@ namespace ts.codefix { functionToConvert = tokenAtPosition.parent.initializer; } else { - functionToConvert = getContainingFunction(getTokenAtPosition(sourceFile, position)) as FunctionLikeDeclaration; + functionToConvert = tryCast(getContainingFunction(getTokenAtPosition(sourceFile, position)), isFunctionLikeDeclaration); } if (!functionToConvert) { From f597e2e40929a3f5505367a8e9180aa20250d579 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 30 Aug 2018 17:33:57 -0700 Subject: [PATCH 127/163] Accept new baselines --- .../reference/infiniteConstraints.errors.txt | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tests/baselines/reference/infiniteConstraints.errors.txt b/tests/baselines/reference/infiniteConstraints.errors.txt index cc420675872..71034e87edf 100644 --- a/tests/baselines/reference/infiniteConstraints.errors.txt +++ b/tests/baselines/reference/infiniteConstraints.errors.txt @@ -1,19 +1,15 @@ error TS2321: Excessive stack depth comparing types 'Extract], Record<"val", string>>["val"]' and 'Extract>], Record<"val", string>>["val"]'. tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' cannot be used to index type 'B[Exclude]'. -tests/cases/compiler/infiniteConstraints.ts(27,36): error TS2345: Argument of type '{ main: Record<"val", "test">; alternate: Record<"val", "test2">; }' is not assignable to parameter of type '{ main: never; alternate: never; }'. - Types of property 'main' are incompatible. - Type 'Record<"val", "test">' is not assignable to type 'never'. -tests/cases/compiler/infiniteConstraints.ts(29,44): error TS2345: Argument of type '{ main: Record<"val", "test">; }' is not assignable to parameter of type '{ main: never; }'. - Types of property 'main' are incompatible. - Type 'Record<"val", "test">' is not assignable to type 'never'. -tests/cases/compiler/infiniteConstraints.ts(31,42): error TS2345: Argument of type '{ main: Record<"val", "dup">; alternate: Record<"val", "dup">; }' is not assignable to parameter of type '{ main: never; alternate: never; }'. - Types of property 'main' are incompatible. - Type 'Record<"val", "dup">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(27,37): error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(27,58): error TS2322: Type 'Record<"val", "test2">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(29,45): error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(31,43): error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'. +tests/cases/compiler/infiniteConstraints.ts(31,63): error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'. tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'. !!! error TS2321: Excessive stack depth comparing types 'Extract], Record<"val", string>>["val"]' and 'Extract>], Record<"val", string>>["val"]'. -==== tests/cases/compiler/infiniteConstraints.ts (5 errors) ==== +==== tests/cases/compiler/infiniteConstraints.ts (7 errors) ==== // Both of the following types trigger the recursion limiter in getImmediateBaseConstraint type T1], { val: string }>["val"] }> = B; @@ -43,16 +39,17 @@ tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' c >(vals: T): void; const noError = ensureNoDuplicates({main: value("test"), alternate: value("test2")}); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ main: Record<"val", "test">; alternate: Record<"val", "test2">; }' is not assignable to parameter of type '{ main: never; alternate: never; }'. -!!! error TS2345: Types of property 'main' are incompatible. -!!! error TS2345: Type 'Record<"val", "test">' is not assignable to type 'never'. + ~~~~ +!!! error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'. +!!! related TS6500 tests/cases/compiler/infiniteConstraints.ts:27:37: The expected type comes from property 'main' which is declared here on type '{ main: never; alternate: never; }' + ~~~~~~~~~ +!!! error TS2322: Type 'Record<"val", "test2">' is not assignable to type 'never'. +!!! related TS6500 tests/cases/compiler/infiniteConstraints.ts:27:58: The expected type comes from property 'alternate' which is declared here on type '{ main: never; alternate: never; }' const shouldBeNoError = ensureNoDuplicates({main: value("test")}); - ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ main: Record<"val", "test">; }' is not assignable to parameter of type '{ main: never; }'. -!!! error TS2345: Types of property 'main' are incompatible. -!!! error TS2345: Type 'Record<"val", "test">' is not assignable to type 'never'. + ~~~~ +!!! error TS2322: Type 'Record<"val", "test">' is not assignable to type 'never'. +!!! related TS6500 tests/cases/compiler/infiniteConstraints.ts:29:45: The expected type comes from property 'main' which is declared here on type '{ main: never; }' const shouldBeError = ensureNoDuplicates({main: value("dup"), alternate: value("dup")}); ~~~~ From cc3d0113332793625e5f60a705944b778af48c40 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 31 Aug 2018 07:45:34 -0700 Subject: [PATCH 128/163] Infer this parameters (#26800) Previously we didn't. I can't remember why, probably because I overlooked it in the initial PR. --- src/compiler/checker.ts | 8 ++++ tests/baselines/reference/inferThisType.js | 15 +++++++ .../baselines/reference/inferThisType.symbols | 45 +++++++++++++++++++ tests/baselines/reference/inferThisType.types | 34 ++++++++++++++ .../types/thisType/inferThisType.ts | 10 +++++ 5 files changed, 112 insertions(+) create mode 100644 tests/baselines/reference/inferThisType.js create mode 100644 tests/baselines/reference/inferThisType.symbols create mode 100644 tests/baselines/reference/inferThisType.types create mode 100644 tests/cases/conformance/types/thisType/inferThisType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ebd849a7844..25f8483a40a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13074,6 +13074,14 @@ namespace ts { const paramCount = targetRestType ? Math.min(targetCount - 1, sourceCount) : sourceRestType ? targetCount : Math.min(sourceCount, targetCount); + + const sourceThisType = getThisTypeOfSignature(source); + if (sourceThisType) { + const targetThisType = getThisTypeOfSignature(target); + if (targetThisType) { + callback(sourceThisType, targetThisType); + } + } for (let i = 0; i < paramCount; i++) { callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } diff --git a/tests/baselines/reference/inferThisType.js b/tests/baselines/reference/inferThisType.js new file mode 100644 index 00000000000..68018970847 --- /dev/null +++ b/tests/baselines/reference/inferThisType.js @@ -0,0 +1,15 @@ +//// [inferThisType.ts] +declare function f(g: (this: T) => void): T +declare function h(this: number): void; +f(h) + +// works with infer types as well +type Check = T extends (this: infer U, ...args: any[]) => any ? string : unknown; +type r1 = Check<(this: number) => void>; // should be string + +type This = T extends (this: infer U, ...args: any[]) => any ? U : unknown; +type r2 = This<(this: number) => void>; // should be number + + +//// [inferThisType.js] +f(h); diff --git a/tests/baselines/reference/inferThisType.symbols b/tests/baselines/reference/inferThisType.symbols new file mode 100644 index 00000000000..8e4b56c67a0 --- /dev/null +++ b/tests/baselines/reference/inferThisType.symbols @@ -0,0 +1,45 @@ +=== tests/cases/conformance/types/thisType/inferThisType.ts === +declare function f(g: (this: T) => void): T +>f : Symbol(f, Decl(inferThisType.ts, 0, 0)) +>T : Symbol(T, Decl(inferThisType.ts, 0, 19)) +>g : Symbol(g, Decl(inferThisType.ts, 0, 22)) +>this : Symbol(this, Decl(inferThisType.ts, 0, 26)) +>T : Symbol(T, Decl(inferThisType.ts, 0, 19)) +>T : Symbol(T, Decl(inferThisType.ts, 0, 19)) + +declare function h(this: number): void; +>h : Symbol(h, Decl(inferThisType.ts, 0, 46)) +>this : Symbol(this, Decl(inferThisType.ts, 1, 19)) + +f(h) +>f : Symbol(f, Decl(inferThisType.ts, 0, 0)) +>h : Symbol(h, Decl(inferThisType.ts, 0, 46)) + +// works with infer types as well +type Check = T extends (this: infer U, ...args: any[]) => any ? string : unknown; +>Check : Symbol(Check, Decl(inferThisType.ts, 2, 4)) +>T : Symbol(T, Decl(inferThisType.ts, 5, 11)) +>T : Symbol(T, Decl(inferThisType.ts, 5, 11)) +>this : Symbol(this, Decl(inferThisType.ts, 5, 27)) +>U : Symbol(U, Decl(inferThisType.ts, 5, 38)) +>args : Symbol(args, Decl(inferThisType.ts, 5, 41)) + +type r1 = Check<(this: number) => void>; // should be string +>r1 : Symbol(r1, Decl(inferThisType.ts, 5, 84)) +>Check : Symbol(Check, Decl(inferThisType.ts, 2, 4)) +>this : Symbol(this, Decl(inferThisType.ts, 6, 17)) + +type This = T extends (this: infer U, ...args: any[]) => any ? U : unknown; +>This : Symbol(This, Decl(inferThisType.ts, 6, 40)) +>T : Symbol(T, Decl(inferThisType.ts, 8, 10)) +>T : Symbol(T, Decl(inferThisType.ts, 8, 10)) +>this : Symbol(this, Decl(inferThisType.ts, 8, 27)) +>U : Symbol(U, Decl(inferThisType.ts, 8, 38)) +>args : Symbol(args, Decl(inferThisType.ts, 8, 41)) +>U : Symbol(U, Decl(inferThisType.ts, 8, 38)) + +type r2 = This<(this: number) => void>; // should be number +>r2 : Symbol(r2, Decl(inferThisType.ts, 8, 79)) +>This : Symbol(This, Decl(inferThisType.ts, 6, 40)) +>this : Symbol(this, Decl(inferThisType.ts, 9, 16)) + diff --git a/tests/baselines/reference/inferThisType.types b/tests/baselines/reference/inferThisType.types new file mode 100644 index 00000000000..3676c7bf3da --- /dev/null +++ b/tests/baselines/reference/inferThisType.types @@ -0,0 +1,34 @@ +=== tests/cases/conformance/types/thisType/inferThisType.ts === +declare function f(g: (this: T) => void): T +>f : (g: (this: T) => void) => T +>g : (this: T) => void +>this : T + +declare function h(this: number): void; +>h : (this: number) => void +>this : number + +f(h) +>f(h) : number +>f : (g: (this: T) => void) => T +>h : (this: number) => void + +// works with infer types as well +type Check = T extends (this: infer U, ...args: any[]) => any ? string : unknown; +>Check : Check +>this : U +>args : any[] + +type r1 = Check<(this: number) => void>; // should be string +>r1 : string +>this : number + +type This = T extends (this: infer U, ...args: any[]) => any ? U : unknown; +>This : This +>this : U +>args : any[] + +type r2 = This<(this: number) => void>; // should be number +>r2 : number +>this : number + diff --git a/tests/cases/conformance/types/thisType/inferThisType.ts b/tests/cases/conformance/types/thisType/inferThisType.ts new file mode 100644 index 00000000000..7dc0c1e941a --- /dev/null +++ b/tests/cases/conformance/types/thisType/inferThisType.ts @@ -0,0 +1,10 @@ +declare function f(g: (this: T) => void): T +declare function h(this: number): void; +f(h) + +// works with infer types as well +type Check = T extends (this: infer U, ...args: any[]) => any ? string : unknown; +type r1 = Check<(this: number) => void>; // should be string + +type This = T extends (this: infer U, ...args: any[]) => any ? U : unknown; +type r2 = This<(this: number) => void>; // should be number From c929e7431080803b66119bb80423dbcc84cdaac6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 31 Aug 2018 07:46:16 -0700 Subject: [PATCH 129/163] Add [Constructor]Parameter types to lib.d.ts (#26243) --- src/lib/es5.d.ts | 10 + .../genericRestParameters1.errors.txt | 25 ++- .../reference/genericRestParameters1.js | 19 +- .../reference/genericRestParameters1.symbols | 189 +++++++++--------- .../reference/genericRestParameters1.types | 15 +- .../genericRestParameters2.errors.txt | 85 ++++++++ .../reference/genericRestParameters2.js | 11 +- .../reference/genericRestParameters2.symbols | 109 +++++----- .../reference/genericRestParameters2.types | 9 +- tests/baselines/reference/genericRestTypes.js | 1 - .../reference/genericRestTypes.symbols | 67 +++---- .../reference/genericRestTypes.types | 5 - .../parameterListAsTupleType.errors.txt | 35 ++++ .../reference/parameterListAsTupleType.js | 52 +++++ .../parameterListAsTupleType.symbols | 63 ++++++ .../reference/parameterListAsTupleType.types | 61 ++++++ tests/cases/compiler/genericRestTypes.ts | 1 - .../compiler/parameterListAsTupleType.ts | 23 +++ .../types/rest/genericRestParameters1.ts | 10 +- .../types/rest/genericRestParameters2.ts | 6 +- 20 files changed, 538 insertions(+), 258 deletions(-) create mode 100644 tests/baselines/reference/genericRestParameters2.errors.txt create mode 100644 tests/baselines/reference/parameterListAsTupleType.errors.txt create mode 100644 tests/baselines/reference/parameterListAsTupleType.js create mode 100644 tests/baselines/reference/parameterListAsTupleType.symbols create mode 100644 tests/baselines/reference/parameterListAsTupleType.types create mode 100644 tests/cases/compiler/parameterListAsTupleType.ts diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index c00f37c260d..015eec5c3e0 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1378,6 +1378,16 @@ type Extract = T extends U ? T : never; */ type NonNullable = T extends null | undefined ? never : T; +/** + * Obtain the parameters of a function type in a tuple + */ +type Parameters any> = T extends (...args: infer P) => any ? P : never; + +/** + * Obtain the parameters of a constructor function type in a tuple + */ +type ConstructorParameters any> = T extends new (...args: infer P) => any ? P : never; + /** * Obtain the return type of a function type */ diff --git a/tests/baselines/reference/genericRestParameters1.errors.txt b/tests/baselines/reference/genericRestParameters1.errors.txt index 2f314387424..fe45ef518ed 100644 --- a/tests/baselines/reference/genericRestParameters1.errors.txt +++ b/tests/baselines/reference/genericRestParameters1.errors.txt @@ -1,11 +1,15 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(22,1): error TS2556: Expected 3 arguments, but got 1 or more. tests/cases/conformance/types/rest/genericRestParameters1.ts(31,1): error TS2556: Expected 3 arguments, but got 1 or more. -tests/cases/conformance/types/rest/genericRestParameters1.ts(166,1): error TS2322: Type '(a: never) => void' is not assignable to type '(...args: any[]) => void'. +tests/cases/conformance/types/rest/genericRestParameters1.ts(133,40): error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. +tests/cases/conformance/types/rest/genericRestParameters1.ts(134,51): error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. +tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. + Type 'Function' provides no match for the signature '(...args: any[]): any'. +tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS2322: Type '(a: never) => void' is not assignable to type '(...args: any[]) => void'. Types of parameters 'a' and 'args' are incompatible. Type 'any' is not assignable to type 'never'. -==== tests/cases/conformance/types/rest/genericRestParameters1.ts (3 errors) ==== +==== tests/cases/conformance/types/rest/genericRestParameters1.ts (6 errors) ==== declare let f1: (...x: [number, string, boolean]) => void; declare let f2: (x0: number, x1: string, x2: boolean) => void; @@ -136,17 +140,22 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(166,1): error TS232 const c30 = f30(42, x => "" + x, x => x + 1); // [(x: number) => string, (x: number) => number] - type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; - type T01 = Parameters<(x: number, y: string, z: boolean) => void>; type T02 = Parameters<(...args: [number, string, boolean]) => void>; - type T03 = Parameters void>; - type T04 = Parameters void>; + type T03 = ConstructorParameters void>; + type T04 = ConstructorParameters void>; type T05 = Parameters<(...args: T[]) => void>; - type T06 = Parameters void>; + type T06 = ConstructorParameters void>; type T07 = Parameters<(...args: T) => void>; - type T08 = Parameters void>; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + type T08 = ConstructorParameters void>; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. type T09 = Parameters; + ~~~~~~~~ +!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any[]): any'. type Record1 = { move: [number, 'left' | 'right']; diff --git a/tests/baselines/reference/genericRestParameters1.js b/tests/baselines/reference/genericRestParameters1.js index d41565e4c6a..3d8703213ac 100644 --- a/tests/baselines/reference/genericRestParameters1.js +++ b/tests/baselines/reference/genericRestParameters1.js @@ -125,16 +125,14 @@ declare function f30 any)[]>(x: T, ...args: U): U; const c30 = f30(42, x => "" + x, x => x + 1); // [(x: number) => string, (x: number) => number] -type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; - type T01 = Parameters<(x: number, y: string, z: boolean) => void>; type T02 = Parameters<(...args: [number, string, boolean]) => void>; -type T03 = Parameters void>; -type T04 = Parameters void>; +type T03 = ConstructorParameters void>; +type T04 = ConstructorParameters void>; type T05 = Parameters<(...args: T[]) => void>; -type T06 = Parameters void>; +type T06 = ConstructorParameters void>; type T07 = Parameters<(...args: T) => void>; -type T08 = Parameters void>; +type T08 = ConstructorParameters void>; type T09 = Parameters; type Record1 = { @@ -327,15 +325,14 @@ declare const g22: (z?: boolean | undefined) => string[]; declare const g23: () => string[]; declare function f30 any)[]>(x: T, ...args: U): U; declare const c30: [(x: number) => string, (x: number) => number]; -declare type Parameters = T extends ((...args: infer U) => any) | (new (...args: infer U) => any) ? U : any[]; declare type T01 = Parameters<(x: number, y: string, z: boolean) => void>; declare type T02 = Parameters<(...args: [number, string, boolean]) => void>; -declare type T03 = Parameters void>; -declare type T04 = Parameters void>; +declare type T03 = ConstructorParameters void>; +declare type T04 = ConstructorParameters void>; declare type T05 = Parameters<(...args: T[]) => void>; -declare type T06 = Parameters void>; +declare type T06 = ConstructorParameters void>; declare type T07 = Parameters<(...args: T) => void>; -declare type T08 = Parameters void>; +declare type T08 = ConstructorParameters void>; declare type T09 = Parameters; declare type Record1 = { move: [number, 'left' | 'right']; diff --git a/tests/baselines/reference/genericRestParameters1.symbols b/tests/baselines/reference/genericRestParameters1.symbols index 87ddbfcf6fe..4b0dae51150 100644 --- a/tests/baselines/reference/genericRestParameters1.symbols +++ b/tests/baselines/reference/genericRestParameters1.symbols @@ -494,160 +494,149 @@ const c30 = f30(42, x => "" + x, x => x + 1); // [(x: number) => string, (x: nu >x : Symbol(x, Decl(genericRestParameters1.ts, 124, 32)) >x : Symbol(x, Decl(genericRestParameters1.ts, 124, 32)) -type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 126, 16)) ->Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 126, 16)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 126, 50)) ->U : Symbol(U, Decl(genericRestParameters1.ts, 126, 64), Decl(genericRestParameters1.ts, 126, 97)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 126, 83)) ->U : Symbol(U, Decl(genericRestParameters1.ts, 126, 64), Decl(genericRestParameters1.ts, 126, 97)) ->U : Symbol(U, Decl(genericRestParameters1.ts, 126, 64), Decl(genericRestParameters1.ts, 126, 97)) - type T01 = Parameters<(x: number, y: string, z: boolean) => void>; ->T01 : Symbol(T01, Decl(genericRestParameters1.ts, 126, 121)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->x : Symbol(x, Decl(genericRestParameters1.ts, 128, 23)) ->y : Symbol(y, Decl(genericRestParameters1.ts, 128, 33)) ->z : Symbol(z, Decl(genericRestParameters1.ts, 128, 44)) +>T01 : Symbol(T01, Decl(genericRestParameters1.ts, 124, 45)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(genericRestParameters1.ts, 126, 23)) +>y : Symbol(y, Decl(genericRestParameters1.ts, 126, 33)) +>z : Symbol(z, Decl(genericRestParameters1.ts, 126, 44)) type T02 = Parameters<(...args: [number, string, boolean]) => void>; ->T02 : Symbol(T02, Decl(genericRestParameters1.ts, 128, 66)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 129, 23)) +>T02 : Symbol(T02, Decl(genericRestParameters1.ts, 126, 66)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(genericRestParameters1.ts, 127, 23)) -type T03 = Parameters void>; ->T03 : Symbol(T03, Decl(genericRestParameters1.ts, 129, 68)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->x : Symbol(x, Decl(genericRestParameters1.ts, 130, 27)) ->y : Symbol(y, Decl(genericRestParameters1.ts, 130, 37)) ->z : Symbol(z, Decl(genericRestParameters1.ts, 130, 48)) +type T03 = ConstructorParameters void>; +>T03 : Symbol(T03, Decl(genericRestParameters1.ts, 127, 68)) +>ConstructorParameters : Symbol(ConstructorParameters, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(genericRestParameters1.ts, 128, 38)) +>y : Symbol(y, Decl(genericRestParameters1.ts, 128, 48)) +>z : Symbol(z, Decl(genericRestParameters1.ts, 128, 59)) -type T04 = Parameters void>; ->T04 : Symbol(T04, Decl(genericRestParameters1.ts, 130, 70)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 131, 27)) +type T04 = ConstructorParameters void>; +>T04 : Symbol(T04, Decl(genericRestParameters1.ts, 128, 81)) +>ConstructorParameters : Symbol(ConstructorParameters, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(genericRestParameters1.ts, 129, 38)) type T05 = Parameters<(...args: T[]) => void>; ->T05 : Symbol(T05, Decl(genericRestParameters1.ts, 131, 72)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 132, 9)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 132, 26)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 132, 9)) +>T05 : Symbol(T05, Decl(genericRestParameters1.ts, 129, 83)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 130, 9)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(genericRestParameters1.ts, 130, 26)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 130, 9)) -type T06 = Parameters void>; ->T06 : Symbol(T06, Decl(genericRestParameters1.ts, 132, 49)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 133, 9)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 133, 30)) +type T06 = ConstructorParameters void>; +>T06 : Symbol(T06, Decl(genericRestParameters1.ts, 130, 49)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 131, 9)) +>ConstructorParameters : Symbol(ConstructorParameters, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(genericRestParameters1.ts, 131, 41)) type T07 = Parameters<(...args: T) => void>; ->T07 : Symbol(T07, Decl(genericRestParameters1.ts, 133, 52)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 134, 9)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 134, 40)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 134, 9)) +>T07 : Symbol(T07, Decl(genericRestParameters1.ts, 131, 63)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 132, 9)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(genericRestParameters1.ts, 132, 40)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 132, 9)) -type T08 = Parameters void>; ->T08 : Symbol(T08, Decl(genericRestParameters1.ts, 134, 61)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 135, 9)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 135, 44)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 135, 9)) +type T08 = ConstructorParameters void>; +>T08 : Symbol(T08, Decl(genericRestParameters1.ts, 132, 61)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 133, 9)) +>ConstructorParameters : Symbol(ConstructorParameters, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(genericRestParameters1.ts, 133, 55)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 133, 9)) type T09 = Parameters; ->T09 : Symbol(T09, Decl(genericRestParameters1.ts, 135, 65)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters1.ts, 124, 45)) +>T09 : Symbol(T09, Decl(genericRestParameters1.ts, 133, 76)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) type Record1 = { ->Record1 : Symbol(Record1, Decl(genericRestParameters1.ts, 136, 32)) +>Record1 : Symbol(Record1, Decl(genericRestParameters1.ts, 134, 32)) move: [number, 'left' | 'right']; ->move : Symbol(move, Decl(genericRestParameters1.ts, 138, 16)) +>move : Symbol(move, Decl(genericRestParameters1.ts, 136, 16)) jump: [number, 'up' | 'down']; ->jump : Symbol(jump, Decl(genericRestParameters1.ts, 139, 35)) +>jump : Symbol(jump, Decl(genericRestParameters1.ts, 137, 35)) stop: string; ->stop : Symbol(stop, Decl(genericRestParameters1.ts, 140, 32)) +>stop : Symbol(stop, Decl(genericRestParameters1.ts, 138, 32)) done: []; ->done : Symbol(done, Decl(genericRestParameters1.ts, 141, 15)) +>done : Symbol(done, Decl(genericRestParameters1.ts, 139, 15)) } type EventType = { ->EventType : Symbol(EventType, Decl(genericRestParameters1.ts, 143, 1)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 145, 15)) +>EventType : Symbol(EventType, Decl(genericRestParameters1.ts, 141, 1)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 143, 15)) emit(e: K, ...payload: T[K] extends any[] ? T[K] : [T[K]]): void; ->emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) ->K : Symbol(K, Decl(genericRestParameters1.ts, 146, 7)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 145, 15)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 145, 15)) ->e : Symbol(e, Decl(genericRestParameters1.ts, 146, 36)) ->K : Symbol(K, Decl(genericRestParameters1.ts, 146, 7)) ->payload : Symbol(payload, Decl(genericRestParameters1.ts, 146, 41)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 145, 15)) ->K : Symbol(K, Decl(genericRestParameters1.ts, 146, 7)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 145, 15)) ->K : Symbol(K, Decl(genericRestParameters1.ts, 146, 7)) ->T : Symbol(T, Decl(genericRestParameters1.ts, 145, 15)) ->K : Symbol(K, Decl(genericRestParameters1.ts, 146, 7)) +>emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) +>K : Symbol(K, Decl(genericRestParameters1.ts, 144, 7)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 143, 15)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 143, 15)) +>e : Symbol(e, Decl(genericRestParameters1.ts, 144, 36)) +>K : Symbol(K, Decl(genericRestParameters1.ts, 144, 7)) +>payload : Symbol(payload, Decl(genericRestParameters1.ts, 144, 41)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 143, 15)) +>K : Symbol(K, Decl(genericRestParameters1.ts, 144, 7)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 143, 15)) +>K : Symbol(K, Decl(genericRestParameters1.ts, 144, 7)) +>T : Symbol(T, Decl(genericRestParameters1.ts, 143, 15)) +>K : Symbol(K, Decl(genericRestParameters1.ts, 144, 7)) } declare var events: EventType; ->events : Symbol(events, Decl(genericRestParameters1.ts, 149, 11)) ->EventType : Symbol(EventType, Decl(genericRestParameters1.ts, 143, 1)) ->Record1 : Symbol(Record1, Decl(genericRestParameters1.ts, 136, 32)) +>events : Symbol(events, Decl(genericRestParameters1.ts, 147, 11)) +>EventType : Symbol(EventType, Decl(genericRestParameters1.ts, 141, 1)) +>Record1 : Symbol(Record1, Decl(genericRestParameters1.ts, 134, 32)) events.emit('move', 10, 'left'); ->events.emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) ->events : Symbol(events, Decl(genericRestParameters1.ts, 149, 11)) ->emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) +>events.emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) +>events : Symbol(events, Decl(genericRestParameters1.ts, 147, 11)) +>emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) events.emit('jump', 20, 'up'); ->events.emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) ->events : Symbol(events, Decl(genericRestParameters1.ts, 149, 11)) ->emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) +>events.emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) +>events : Symbol(events, Decl(genericRestParameters1.ts, 147, 11)) +>emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) events.emit('stop', 'Bye!'); ->events.emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) ->events : Symbol(events, Decl(genericRestParameters1.ts, 149, 11)) ->emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) +>events.emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) +>events : Symbol(events, Decl(genericRestParameters1.ts, 147, 11)) +>emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) events.emit('done'); ->events.emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) ->events : Symbol(events, Decl(genericRestParameters1.ts, 149, 11)) ->emit : Symbol(emit, Decl(genericRestParameters1.ts, 145, 21)) +>events.emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) +>events : Symbol(events, Decl(genericRestParameters1.ts, 147, 11)) +>emit : Symbol(emit, Decl(genericRestParameters1.ts, 143, 21)) // Repro from #25871 declare var ff1: (... args: any[]) => void; ->ff1 : Symbol(ff1, Decl(genericRestParameters1.ts, 157, 11)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 157, 18)) +>ff1 : Symbol(ff1, Decl(genericRestParameters1.ts, 155, 11)) +>args : Symbol(args, Decl(genericRestParameters1.ts, 155, 18)) declare var ff2: () => void; ->ff2 : Symbol(ff2, Decl(genericRestParameters1.ts, 159, 11)) +>ff2 : Symbol(ff2, Decl(genericRestParameters1.ts, 157, 11)) declare var ff3: (...args: []) => void; ->ff3 : Symbol(ff3, Decl(genericRestParameters1.ts, 160, 11)) ->args : Symbol(args, Decl(genericRestParameters1.ts, 160, 18)) +>ff3 : Symbol(ff3, Decl(genericRestParameters1.ts, 158, 11)) +>args : Symbol(args, Decl(genericRestParameters1.ts, 158, 18)) declare var ff4: (a: never) => void; ->ff4 : Symbol(ff4, Decl(genericRestParameters1.ts, 161, 11)) ->a : Symbol(a, Decl(genericRestParameters1.ts, 161, 18)) +>ff4 : Symbol(ff4, Decl(genericRestParameters1.ts, 159, 11)) +>a : Symbol(a, Decl(genericRestParameters1.ts, 159, 18)) ff1 = ff2; ->ff1 : Symbol(ff1, Decl(genericRestParameters1.ts, 157, 11)) ->ff2 : Symbol(ff2, Decl(genericRestParameters1.ts, 159, 11)) +>ff1 : Symbol(ff1, Decl(genericRestParameters1.ts, 155, 11)) +>ff2 : Symbol(ff2, Decl(genericRestParameters1.ts, 157, 11)) ff1 = ff3; ->ff1 : Symbol(ff1, Decl(genericRestParameters1.ts, 157, 11)) ->ff3 : Symbol(ff3, Decl(genericRestParameters1.ts, 160, 11)) +>ff1 : Symbol(ff1, Decl(genericRestParameters1.ts, 155, 11)) +>ff3 : Symbol(ff3, Decl(genericRestParameters1.ts, 158, 11)) ff1 = ff4; // Error ->ff1 : Symbol(ff1, Decl(genericRestParameters1.ts, 157, 11)) ->ff4 : Symbol(ff4, Decl(genericRestParameters1.ts, 161, 11)) +>ff1 : Symbol(ff1, Decl(genericRestParameters1.ts, 155, 11)) +>ff4 : Symbol(ff4, Decl(genericRestParameters1.ts, 159, 11)) diff --git a/tests/baselines/reference/genericRestParameters1.types b/tests/baselines/reference/genericRestParameters1.types index 625edcc4d84..497561c8a98 100644 --- a/tests/baselines/reference/genericRestParameters1.types +++ b/tests/baselines/reference/genericRestParameters1.types @@ -664,11 +664,6 @@ const c30 = f30(42, x => "" + x, x => x + 1); // [(x: number) => string, (x: nu >x : number >1 : 1 -type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; ->Parameters : Parameters ->args : U ->args : U - type T01 = Parameters<(x: number, y: string, z: boolean) => void>; >T01 : [number, string, boolean] >x : number @@ -679,13 +674,13 @@ type T02 = Parameters<(...args: [number, string, boolean]) => void>; >T02 : [number, string, boolean] >args : [number, string, boolean] -type T03 = Parameters void>; +type T03 = ConstructorParameters void>; >T03 : [number, string, boolean] >x : number >y : string >z : boolean -type T04 = Parameters void>; +type T04 = ConstructorParameters void>; >T04 : [number, string, boolean] >args : [number, string, boolean] @@ -693,7 +688,7 @@ type T05 = Parameters<(...args: T[]) => void>; >T05 : T[] >args : T[] -type T06 = Parameters void>; +type T06 = ConstructorParameters void>; >T06 : [] >args : [] @@ -701,12 +696,12 @@ type T07 = Parameters<(...args: T) => void>; >T07 : T >args : T -type T08 = Parameters void>; +type T08 = ConstructorParameters void>; >T08 : T >args : T type T09 = Parameters; ->T09 : any[] +>T09 : never type Record1 = { >Record1 : Record1 diff --git a/tests/baselines/reference/genericRestParameters2.errors.txt b/tests/baselines/reference/genericRestParameters2.errors.txt new file mode 100644 index 00000000000..5035544c51f --- /dev/null +++ b/tests/baselines/reference/genericRestParameters2.errors.txt @@ -0,0 +1,85 @@ +tests/cases/conformance/types/rest/genericRestParameters2.ts(71,40): error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + + +==== tests/cases/conformance/types/rest/genericRestParameters2.ts (1 errors) ==== + declare const t1: [number, string, ...boolean[]]; + declare const t2: [string, ...boolean[]]; + declare const t3: [...boolean[]]; + declare const t4: []; + + declare let f00: (...x: [number, string, boolean]) => void; + declare let f01: (a: number, ...x: [string, boolean]) => void; + declare let f02: (a: number, b: string, ...x: [boolean]) => void; + declare let f03: (a: number, b: string, c: boolean) => void; + declare let f04: (a: number, b: string, c: boolean, ...x: []) => void; + + declare let f10: (...x: [number, string, ...boolean[]]) => void; + declare let f11: (a: number, ...x: [string, ...boolean[]]) => void; + declare let f12: (a: number, b: string, ...x: [...boolean[]]) => void; + declare let f13: (a: number, b: string, ...c: boolean[]) => void; + + declare const ns: [number, string]; + declare const sn: [string, number]; + + f10(42, "hello"); + f10(42, "hello", true); + f10(42, "hello", true, false); + f10(t1[0], t1[1], t1[2], t1[3]); + f10(...t1); + f10(42, ...t2); + f10(42, "hello", ...t3); + f10(42, "hello", true, ...t4); + f10(42, "hello", true, ...t4, false, ...t3); + + f11(42, "hello"); + f11(42, "hello", true); + f11(42, "hello", true, false); + f11(t1[0], t1[1], t1[2], t1[3]); + f11(...t1); + f11(42, ...t2); + f11(42, "hello", ...t3); + f11(42, "hello", true, ...t4); + f11(42, "hello", true, ...t4, false, ...t3); + + f12(42, "hello"); + f12(42, "hello", true); + f12(42, "hello", true, false); + f12(t1[0], t1[1], t1[2], t1[3]); + f12(...t1); + f12(42, ...t2); + f12(42, "hello", ...t3); + f12(42, "hello", true, ...t4); + f12(42, "hello", true, ...t4, false, ...t3); + + f13(42, "hello"); + f13(42, "hello", true); + f13(42, "hello", true, false); + f13(t1[0], t1[1], t1[2], t1[3]); + f13(...t1); + f13(42, ...t2); + f13(42, "hello", ...t3); + f13(42, "hello", true, ...t4); + f13(42, "hello", true, ...t4, false, ...t3); + + declare const f20: (...args: T) => T; + + f20(...t1); + f20(42, ...t2); + f20(42, "hello", ...t3); + f20(42, "hello", ...t2, true); + + type T01 = Parameters<(x: number, y: string, ...z: boolean[]) => void>; + type T02 = Parameters<(...args: [number, string, ...boolean[]]) => void>; + type T03 = ConstructorParameters void>; + type T04 = ConstructorParameters void>; + type T05 = Parameters<(x: string, ...args: T) => void>; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + type T06 = T05<[number, ...boolean[]]>; + + type P1 = T extends (head: infer A, ...tail: infer B) => any ? { head: A, tail: B } : any[]; + + type T10 = P1<(x: number, y: string, ...z: boolean[]) => void>; + type T11 = P1<(...z: number[]) => void>; + type T12 = P1<(x: number, y: number) => void>; + \ No newline at end of file diff --git a/tests/baselines/reference/genericRestParameters2.js b/tests/baselines/reference/genericRestParameters2.js index 143a4a62f52..3c00a7c2a3a 100644 --- a/tests/baselines/reference/genericRestParameters2.js +++ b/tests/baselines/reference/genericRestParameters2.js @@ -65,12 +65,10 @@ f20(42, ...t2); f20(42, "hello", ...t3); f20(42, "hello", ...t2, true); -type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; - type T01 = Parameters<(x: number, y: string, ...z: boolean[]) => void>; type T02 = Parameters<(...args: [number, string, ...boolean[]]) => void>; -type T03 = Parameters void>; -type T04 = Parameters void>; +type T03 = ConstructorParameters void>; +type T04 = ConstructorParameters void>; type T05 = Parameters<(x: string, ...args: T) => void>; type T06 = T05<[number, ...boolean[]]>; @@ -142,11 +140,10 @@ declare let f13: (a: number, b: string, ...c: boolean[]) => void; declare const ns: [number, string]; declare const sn: [string, number]; declare const f20: (...args: T) => T; -declare type Parameters = T extends ((...args: infer U) => any) | (new (...args: infer U) => any) ? U : any[]; declare type T01 = Parameters<(x: number, y: string, ...z: boolean[]) => void>; declare type T02 = Parameters<(...args: [number, string, ...boolean[]]) => void>; -declare type T03 = Parameters void>; -declare type T04 = Parameters void>; +declare type T03 = ConstructorParameters void>; +declare type T04 = ConstructorParameters void>; declare type T05 = Parameters<(x: string, ...args: T) => void>; declare type T06 = T05<[number, ...boolean[]]>; declare type P1 = T extends (head: infer A, ...tail: infer B) => any ? { diff --git a/tests/baselines/reference/genericRestParameters2.symbols b/tests/baselines/reference/genericRestParameters2.symbols index 164d08d132e..1dd27d4f890 100644 --- a/tests/baselines/reference/genericRestParameters2.symbols +++ b/tests/baselines/reference/genericRestParameters2.symbols @@ -245,82 +245,71 @@ f20(42, "hello", ...t2, true); >f20 : Symbol(f20, Decl(genericRestParameters2.ts, 59, 13)) >t2 : Symbol(t2, Decl(genericRestParameters2.ts, 1, 13)) -type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; ->Parameters : Symbol(Parameters, Decl(genericRestParameters2.ts, 64, 30)) ->T : Symbol(T, Decl(genericRestParameters2.ts, 66, 16)) ->Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(genericRestParameters2.ts, 66, 16)) ->args : Symbol(args, Decl(genericRestParameters2.ts, 66, 50)) ->U : Symbol(U, Decl(genericRestParameters2.ts, 66, 64), Decl(genericRestParameters2.ts, 66, 97)) ->args : Symbol(args, Decl(genericRestParameters2.ts, 66, 83)) ->U : Symbol(U, Decl(genericRestParameters2.ts, 66, 64), Decl(genericRestParameters2.ts, 66, 97)) ->U : Symbol(U, Decl(genericRestParameters2.ts, 66, 64), Decl(genericRestParameters2.ts, 66, 97)) - type T01 = Parameters<(x: number, y: string, ...z: boolean[]) => void>; ->T01 : Symbol(T01, Decl(genericRestParameters2.ts, 66, 121)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters2.ts, 64, 30)) ->x : Symbol(x, Decl(genericRestParameters2.ts, 68, 23)) ->y : Symbol(y, Decl(genericRestParameters2.ts, 68, 33)) ->z : Symbol(z, Decl(genericRestParameters2.ts, 68, 44)) +>T01 : Symbol(T01, Decl(genericRestParameters2.ts, 64, 30)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(genericRestParameters2.ts, 66, 23)) +>y : Symbol(y, Decl(genericRestParameters2.ts, 66, 33)) +>z : Symbol(z, Decl(genericRestParameters2.ts, 66, 44)) type T02 = Parameters<(...args: [number, string, ...boolean[]]) => void>; ->T02 : Symbol(T02, Decl(genericRestParameters2.ts, 68, 71)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters2.ts, 64, 30)) ->args : Symbol(args, Decl(genericRestParameters2.ts, 69, 23)) +>T02 : Symbol(T02, Decl(genericRestParameters2.ts, 66, 71)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(genericRestParameters2.ts, 67, 23)) -type T03 = Parameters void>; ->T03 : Symbol(T03, Decl(genericRestParameters2.ts, 69, 73)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters2.ts, 64, 30)) ->x : Symbol(x, Decl(genericRestParameters2.ts, 70, 27)) ->y : Symbol(y, Decl(genericRestParameters2.ts, 70, 37)) ->z : Symbol(z, Decl(genericRestParameters2.ts, 70, 48)) +type T03 = ConstructorParameters void>; +>T03 : Symbol(T03, Decl(genericRestParameters2.ts, 67, 73)) +>ConstructorParameters : Symbol(ConstructorParameters, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(genericRestParameters2.ts, 68, 38)) +>y : Symbol(y, Decl(genericRestParameters2.ts, 68, 48)) +>z : Symbol(z, Decl(genericRestParameters2.ts, 68, 59)) -type T04 = Parameters void>; ->T04 : Symbol(T04, Decl(genericRestParameters2.ts, 70, 75)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters2.ts, 64, 30)) ->args : Symbol(args, Decl(genericRestParameters2.ts, 71, 27)) +type T04 = ConstructorParameters void>; +>T04 : Symbol(T04, Decl(genericRestParameters2.ts, 68, 86)) +>ConstructorParameters : Symbol(ConstructorParameters, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(genericRestParameters2.ts, 69, 38)) type T05 = Parameters<(x: string, ...args: T) => void>; ->T05 : Symbol(T05, Decl(genericRestParameters2.ts, 71, 77)) ->T : Symbol(T, Decl(genericRestParameters2.ts, 72, 9)) ->Parameters : Symbol(Parameters, Decl(genericRestParameters2.ts, 64, 30)) ->x : Symbol(x, Decl(genericRestParameters2.ts, 72, 40)) ->args : Symbol(args, Decl(genericRestParameters2.ts, 72, 50)) ->T : Symbol(T, Decl(genericRestParameters2.ts, 72, 9)) +>T05 : Symbol(T05, Decl(genericRestParameters2.ts, 69, 88)) +>T : Symbol(T, Decl(genericRestParameters2.ts, 70, 9)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(genericRestParameters2.ts, 70, 40)) +>args : Symbol(args, Decl(genericRestParameters2.ts, 70, 50)) +>T : Symbol(T, Decl(genericRestParameters2.ts, 70, 9)) type T06 = T05<[number, ...boolean[]]>; ->T06 : Symbol(T06, Decl(genericRestParameters2.ts, 72, 72)) ->T05 : Symbol(T05, Decl(genericRestParameters2.ts, 71, 77)) +>T06 : Symbol(T06, Decl(genericRestParameters2.ts, 70, 72)) +>T05 : Symbol(T05, Decl(genericRestParameters2.ts, 69, 88)) type P1 = T extends (head: infer A, ...tail: infer B) => any ? { head: A, tail: B } : any[]; ->P1 : Symbol(P1, Decl(genericRestParameters2.ts, 73, 39)) ->T : Symbol(T, Decl(genericRestParameters2.ts, 75, 8)) +>P1 : Symbol(P1, Decl(genericRestParameters2.ts, 71, 39)) +>T : Symbol(T, Decl(genericRestParameters2.ts, 73, 8)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(genericRestParameters2.ts, 75, 8)) ->head : Symbol(head, Decl(genericRestParameters2.ts, 75, 41)) ->A : Symbol(A, Decl(genericRestParameters2.ts, 75, 52)) ->tail : Symbol(tail, Decl(genericRestParameters2.ts, 75, 55)) ->B : Symbol(B, Decl(genericRestParameters2.ts, 75, 70)) ->head : Symbol(head, Decl(genericRestParameters2.ts, 75, 84)) ->A : Symbol(A, Decl(genericRestParameters2.ts, 75, 52)) ->tail : Symbol(tail, Decl(genericRestParameters2.ts, 75, 93)) ->B : Symbol(B, Decl(genericRestParameters2.ts, 75, 70)) +>T : Symbol(T, Decl(genericRestParameters2.ts, 73, 8)) +>head : Symbol(head, Decl(genericRestParameters2.ts, 73, 41)) +>A : Symbol(A, Decl(genericRestParameters2.ts, 73, 52)) +>tail : Symbol(tail, Decl(genericRestParameters2.ts, 73, 55)) +>B : Symbol(B, Decl(genericRestParameters2.ts, 73, 70)) +>head : Symbol(head, Decl(genericRestParameters2.ts, 73, 84)) +>A : Symbol(A, Decl(genericRestParameters2.ts, 73, 52)) +>tail : Symbol(tail, Decl(genericRestParameters2.ts, 73, 93)) +>B : Symbol(B, Decl(genericRestParameters2.ts, 73, 70)) type T10 = P1<(x: number, y: string, ...z: boolean[]) => void>; ->T10 : Symbol(T10, Decl(genericRestParameters2.ts, 75, 112)) ->P1 : Symbol(P1, Decl(genericRestParameters2.ts, 73, 39)) ->x : Symbol(x, Decl(genericRestParameters2.ts, 77, 15)) ->y : Symbol(y, Decl(genericRestParameters2.ts, 77, 25)) ->z : Symbol(z, Decl(genericRestParameters2.ts, 77, 36)) +>T10 : Symbol(T10, Decl(genericRestParameters2.ts, 73, 112)) +>P1 : Symbol(P1, Decl(genericRestParameters2.ts, 71, 39)) +>x : Symbol(x, Decl(genericRestParameters2.ts, 75, 15)) +>y : Symbol(y, Decl(genericRestParameters2.ts, 75, 25)) +>z : Symbol(z, Decl(genericRestParameters2.ts, 75, 36)) type T11 = P1<(...z: number[]) => void>; ->T11 : Symbol(T11, Decl(genericRestParameters2.ts, 77, 63)) ->P1 : Symbol(P1, Decl(genericRestParameters2.ts, 73, 39)) ->z : Symbol(z, Decl(genericRestParameters2.ts, 78, 15)) +>T11 : Symbol(T11, Decl(genericRestParameters2.ts, 75, 63)) +>P1 : Symbol(P1, Decl(genericRestParameters2.ts, 71, 39)) +>z : Symbol(z, Decl(genericRestParameters2.ts, 76, 15)) type T12 = P1<(x: number, y: number) => void>; ->T12 : Symbol(T12, Decl(genericRestParameters2.ts, 78, 40)) ->P1 : Symbol(P1, Decl(genericRestParameters2.ts, 73, 39)) ->x : Symbol(x, Decl(genericRestParameters2.ts, 79, 15)) ->y : Symbol(y, Decl(genericRestParameters2.ts, 79, 25)) +>T12 : Symbol(T12, Decl(genericRestParameters2.ts, 76, 40)) +>P1 : Symbol(P1, Decl(genericRestParameters2.ts, 71, 39)) +>x : Symbol(x, Decl(genericRestParameters2.ts, 77, 15)) +>y : Symbol(y, Decl(genericRestParameters2.ts, 77, 25)) diff --git a/tests/baselines/reference/genericRestParameters2.types b/tests/baselines/reference/genericRestParameters2.types index 3c0a7c62877..103b0a0a62f 100644 --- a/tests/baselines/reference/genericRestParameters2.types +++ b/tests/baselines/reference/genericRestParameters2.types @@ -416,11 +416,6 @@ f20(42, "hello", ...t2, true); >t2 : [string, ...boolean[]] >true : true -type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; ->Parameters : Parameters ->args : U ->args : U - type T01 = Parameters<(x: number, y: string, ...z: boolean[]) => void>; >T01 : [number, string, ...boolean[]] >x : number @@ -431,13 +426,13 @@ type T02 = Parameters<(...args: [number, string, ...boolean[]]) => void>; >T02 : [number, string, ...boolean[]] >args : [number, string, ...boolean[]] -type T03 = Parameters void>; +type T03 = ConstructorParameters void>; >T03 : [number, string, ...boolean[]] >x : number >y : string >z : boolean[] -type T04 = Parameters void>; +type T04 = ConstructorParameters void>; >T04 : [number, string, ...boolean[]] >args : [number, string, ...boolean[]] diff --git a/tests/baselines/reference/genericRestTypes.js b/tests/baselines/reference/genericRestTypes.js index f932032af56..5abf8113f38 100644 --- a/tests/baselines/reference/genericRestTypes.js +++ b/tests/baselines/reference/genericRestTypes.js @@ -2,7 +2,6 @@ // Repro from #25793 // Gets the parameters of a function type as a tuple -type Parameters any> = T extends (...args: infer U) => any ? U : never; // Removes the first element from a tuple type Tail = ((...args: T) => any) extends ((head: any, ...tail: infer U) => any) ? U : never; diff --git a/tests/baselines/reference/genericRestTypes.symbols b/tests/baselines/reference/genericRestTypes.symbols index 77bc400b5db..c8ab347609c 100644 --- a/tests/baselines/reference/genericRestTypes.symbols +++ b/tests/baselines/reference/genericRestTypes.symbols @@ -2,54 +2,45 @@ // Repro from #25793 // Gets the parameters of a function type as a tuple -type Parameters any> = T extends (...args: infer U) => any ? U : never; ->Parameters : Symbol(Parameters, Decl(genericRestTypes.ts, 0, 0)) ->T : Symbol(T, Decl(genericRestTypes.ts, 3, 16)) ->args : Symbol(args, Decl(genericRestTypes.ts, 3, 27)) ->T : Symbol(T, Decl(genericRestTypes.ts, 3, 16)) ->args : Symbol(args, Decl(genericRestTypes.ts, 3, 64)) ->U : Symbol(U, Decl(genericRestTypes.ts, 3, 78)) ->U : Symbol(U, Decl(genericRestTypes.ts, 3, 78)) - // Removes the first element from a tuple type Tail = ((...args: T) => any) extends ((head: any, ...tail: infer U) => any) ? U : never; ->Tail : Symbol(Tail, Decl(genericRestTypes.ts, 3, 101)) ->T : Symbol(T, Decl(genericRestTypes.ts, 5, 10)) ->args : Symbol(args, Decl(genericRestTypes.ts, 5, 31)) ->T : Symbol(T, Decl(genericRestTypes.ts, 5, 10)) ->head : Symbol(head, Decl(genericRestTypes.ts, 5, 61)) ->tail : Symbol(tail, Decl(genericRestTypes.ts, 5, 71)) ->U : Symbol(U, Decl(genericRestTypes.ts, 5, 86)) ->U : Symbol(U, Decl(genericRestTypes.ts, 5, 86)) +>Tail : Symbol(Tail, Decl(genericRestTypes.ts, 0, 0)) +>T : Symbol(T, Decl(genericRestTypes.ts, 4, 10)) +>args : Symbol(args, Decl(genericRestTypes.ts, 4, 31)) +>T : Symbol(T, Decl(genericRestTypes.ts, 4, 10)) +>head : Symbol(head, Decl(genericRestTypes.ts, 4, 61)) +>tail : Symbol(tail, Decl(genericRestTypes.ts, 4, 71)) +>U : Symbol(U, Decl(genericRestTypes.ts, 4, 86)) +>U : Symbol(U, Decl(genericRestTypes.ts, 4, 86)) type MyFunctionType = (foo: number, bar: string) => boolean; ->MyFunctionType : Symbol(MyFunctionType, Decl(genericRestTypes.ts, 5, 110)) ->foo : Symbol(foo, Decl(genericRestTypes.ts, 7, 23)) ->bar : Symbol(bar, Decl(genericRestTypes.ts, 7, 35)) +>MyFunctionType : Symbol(MyFunctionType, Decl(genericRestTypes.ts, 4, 110)) +>foo : Symbol(foo, Decl(genericRestTypes.ts, 6, 23)) +>bar : Symbol(bar, Decl(genericRestTypes.ts, 6, 35)) type Explicit = (...args: Tail>) => ReturnType; // (bar: string) => boolean ->Explicit : Symbol(Explicit, Decl(genericRestTypes.ts, 7, 60)) ->args : Symbol(args, Decl(genericRestTypes.ts, 9, 17)) ->Tail : Symbol(Tail, Decl(genericRestTypes.ts, 3, 101)) ->Parameters : Symbol(Parameters, Decl(genericRestTypes.ts, 0, 0)) ->MyFunctionType : Symbol(MyFunctionType, Decl(genericRestTypes.ts, 5, 110)) +>Explicit : Symbol(Explicit, Decl(genericRestTypes.ts, 6, 60)) +>args : Symbol(args, Decl(genericRestTypes.ts, 8, 17)) +>Tail : Symbol(Tail, Decl(genericRestTypes.ts, 0, 0)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>MyFunctionType : Symbol(MyFunctionType, Decl(genericRestTypes.ts, 4, 110)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->MyFunctionType : Symbol(MyFunctionType, Decl(genericRestTypes.ts, 5, 110)) +>MyFunctionType : Symbol(MyFunctionType, Decl(genericRestTypes.ts, 4, 110)) type Bind1 any> = (...args: Tail>) => ReturnType; ->Bind1 : Symbol(Bind1, Decl(genericRestTypes.ts, 9, 90)) ->T : Symbol(T, Decl(genericRestTypes.ts, 11, 11)) ->head : Symbol(head, Decl(genericRestTypes.ts, 11, 22)) ->tail : Symbol(tail, Decl(genericRestTypes.ts, 11, 32)) ->args : Symbol(args, Decl(genericRestTypes.ts, 11, 60)) ->Tail : Symbol(Tail, Decl(genericRestTypes.ts, 3, 101)) ->Parameters : Symbol(Parameters, Decl(genericRestTypes.ts, 0, 0)) ->T : Symbol(T, Decl(genericRestTypes.ts, 11, 11)) +>Bind1 : Symbol(Bind1, Decl(genericRestTypes.ts, 8, 90)) +>T : Symbol(T, Decl(genericRestTypes.ts, 10, 11)) +>head : Symbol(head, Decl(genericRestTypes.ts, 10, 22)) +>tail : Symbol(tail, Decl(genericRestTypes.ts, 10, 32)) +>args : Symbol(args, Decl(genericRestTypes.ts, 10, 60)) +>Tail : Symbol(Tail, Decl(genericRestTypes.ts, 0, 0)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(genericRestTypes.ts, 10, 11)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(genericRestTypes.ts, 11, 11)) +>T : Symbol(T, Decl(genericRestTypes.ts, 10, 11)) type Generic = Bind1; // (bar: string) => boolean ->Generic : Symbol(Generic, Decl(genericRestTypes.ts, 11, 107)) ->Bind1 : Symbol(Bind1, Decl(genericRestTypes.ts, 9, 90)) ->MyFunctionType : Symbol(MyFunctionType, Decl(genericRestTypes.ts, 5, 110)) +>Generic : Symbol(Generic, Decl(genericRestTypes.ts, 10, 107)) +>Bind1 : Symbol(Bind1, Decl(genericRestTypes.ts, 8, 90)) +>MyFunctionType : Symbol(MyFunctionType, Decl(genericRestTypes.ts, 4, 110)) diff --git a/tests/baselines/reference/genericRestTypes.types b/tests/baselines/reference/genericRestTypes.types index 6fb482799dd..b2fb37871bd 100644 --- a/tests/baselines/reference/genericRestTypes.types +++ b/tests/baselines/reference/genericRestTypes.types @@ -2,11 +2,6 @@ // Repro from #25793 // Gets the parameters of a function type as a tuple -type Parameters any> = T extends (...args: infer U) => any ? U : never; ->Parameters : Parameters ->args : any[] ->args : U - // Removes the first element from a tuple type Tail = ((...args: T) => any) extends ((head: any, ...tail: infer U) => any) ? U : never; >Tail : Tail diff --git a/tests/baselines/reference/parameterListAsTupleType.errors.txt b/tests/baselines/reference/parameterListAsTupleType.errors.txt new file mode 100644 index 00000000000..021138ec2ba --- /dev/null +++ b/tests/baselines/reference/parameterListAsTupleType.errors.txt @@ -0,0 +1,35 @@ +tests/cases/compiler/parameterListAsTupleType.ts(8,17): error TS2322: Type 'string' is not assignable to type 'number'. +tests/cases/compiler/parameterListAsTupleType.ts(16,23): error TS2344: Type 'typeof C' does not satisfy the constraint '(...args: any[]) => any'. + Type 'typeof C' provides no match for the signature '(...args: any[]): any'. + + +==== tests/cases/compiler/parameterListAsTupleType.ts (2 errors) ==== + function foo(a: number, b: string) { + return true; + } + type Foops = Parameters; + + const x = (a: number) => 5; + type Xps = Parameters; + const a: Xps = ['should-not-work']; // works, but shouldn't + ~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. + function t(...args: Xps) {} // should work + + class C { + constructor(a: number, b: string) { + } + } + + type Cps = Parameters; // should not work + ~~~~~~~~ +!!! error TS2344: Type 'typeof C' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Type 'typeof C' provides no match for the signature '(...args: any[]): any'. + type Ccps = ConstructorParameters; // should be [number, string] + + class D { + constructor(a: number, ...rest: string[]) { + } + } + type Dcps = ConstructorParameters; // should be [number, ...string[]] + \ No newline at end of file diff --git a/tests/baselines/reference/parameterListAsTupleType.js b/tests/baselines/reference/parameterListAsTupleType.js new file mode 100644 index 00000000000..0c831e36edb --- /dev/null +++ b/tests/baselines/reference/parameterListAsTupleType.js @@ -0,0 +1,52 @@ +//// [parameterListAsTupleType.ts] +function foo(a: number, b: string) { + return true; +} +type Foops = Parameters; + +const x = (a: number) => 5; +type Xps = Parameters; +const a: Xps = ['should-not-work']; // works, but shouldn't +function t(...args: Xps) {} // should work + +class C { + constructor(a: number, b: string) { + } +} + +type Cps = Parameters; // should not work +type Ccps = ConstructorParameters; // should be [number, string] + +class D { + constructor(a: number, ...rest: string[]) { + } +} +type Dcps = ConstructorParameters; // should be [number, ...string[]] + + +//// [parameterListAsTupleType.js] +function foo(a, b) { + return true; +} +var x = function (a) { return 5; }; +var a = ['should-not-work']; // works, but shouldn't +function t() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } +} // should work +var C = /** @class */ (function () { + function C(a, b) { + } + return C; +}()); +var D = /** @class */ (function () { + function D(a) { + var rest = []; + for (var _i = 1; _i < arguments.length; _i++) { + rest[_i - 1] = arguments[_i]; + } + } + return D; +}()); diff --git a/tests/baselines/reference/parameterListAsTupleType.symbols b/tests/baselines/reference/parameterListAsTupleType.symbols new file mode 100644 index 00000000000..fc09e66c180 --- /dev/null +++ b/tests/baselines/reference/parameterListAsTupleType.symbols @@ -0,0 +1,63 @@ +=== tests/cases/compiler/parameterListAsTupleType.ts === +function foo(a: number, b: string) { +>foo : Symbol(foo, Decl(parameterListAsTupleType.ts, 0, 0)) +>a : Symbol(a, Decl(parameterListAsTupleType.ts, 0, 13)) +>b : Symbol(b, Decl(parameterListAsTupleType.ts, 0, 23)) + + return true; +} +type Foops = Parameters; +>Foops : Symbol(Foops, Decl(parameterListAsTupleType.ts, 2, 1)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>foo : Symbol(foo, Decl(parameterListAsTupleType.ts, 0, 0)) + +const x = (a: number) => 5; +>x : Symbol(x, Decl(parameterListAsTupleType.ts, 5, 5)) +>a : Symbol(a, Decl(parameterListAsTupleType.ts, 5, 11)) + +type Xps = Parameters; +>Xps : Symbol(Xps, Decl(parameterListAsTupleType.ts, 5, 27)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(parameterListAsTupleType.ts, 5, 5)) + +const a: Xps = ['should-not-work']; // works, but shouldn't +>a : Symbol(a, Decl(parameterListAsTupleType.ts, 7, 5)) +>Xps : Symbol(Xps, Decl(parameterListAsTupleType.ts, 5, 27)) + +function t(...args: Xps) {} // should work +>t : Symbol(t, Decl(parameterListAsTupleType.ts, 7, 35)) +>args : Symbol(args, Decl(parameterListAsTupleType.ts, 8, 11)) +>Xps : Symbol(Xps, Decl(parameterListAsTupleType.ts, 5, 27)) + +class C { +>C : Symbol(C, Decl(parameterListAsTupleType.ts, 8, 27)) + + constructor(a: number, b: string) { +>a : Symbol(a, Decl(parameterListAsTupleType.ts, 11, 16)) +>b : Symbol(b, Decl(parameterListAsTupleType.ts, 11, 26)) + } +} + +type Cps = Parameters; // should not work +>Cps : Symbol(Cps, Decl(parameterListAsTupleType.ts, 13, 1)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>C : Symbol(C, Decl(parameterListAsTupleType.ts, 8, 27)) + +type Ccps = ConstructorParameters; // should be [number, string] +>Ccps : Symbol(Ccps, Decl(parameterListAsTupleType.ts, 15, 32)) +>ConstructorParameters : Symbol(ConstructorParameters, Decl(lib.es5.d.ts, --, --)) +>C : Symbol(C, Decl(parameterListAsTupleType.ts, 8, 27)) + +class D { +>D : Symbol(D, Decl(parameterListAsTupleType.ts, 16, 44)) + + constructor(a: number, ...rest: string[]) { +>a : Symbol(a, Decl(parameterListAsTupleType.ts, 19, 16)) +>rest : Symbol(rest, Decl(parameterListAsTupleType.ts, 19, 26)) + } +} +type Dcps = ConstructorParameters; // should be [number, ...string[]] +>Dcps : Symbol(Dcps, Decl(parameterListAsTupleType.ts, 21, 1)) +>ConstructorParameters : Symbol(ConstructorParameters, Decl(lib.es5.d.ts, --, --)) +>D : Symbol(D, Decl(parameterListAsTupleType.ts, 16, 44)) + diff --git a/tests/baselines/reference/parameterListAsTupleType.types b/tests/baselines/reference/parameterListAsTupleType.types new file mode 100644 index 00000000000..3bb861f5a1d --- /dev/null +++ b/tests/baselines/reference/parameterListAsTupleType.types @@ -0,0 +1,61 @@ +=== tests/cases/compiler/parameterListAsTupleType.ts === +function foo(a: number, b: string) { +>foo : (a: number, b: string) => boolean +>a : number +>b : string + + return true; +>true : true +} +type Foops = Parameters; +>Foops : [number, string] +>foo : (a: number, b: string) => boolean + +const x = (a: number) => 5; +>x : (a: number) => number +>(a: number) => 5 : (a: number) => number +>a : number +>5 : 5 + +type Xps = Parameters; +>Xps : [number] +>x : (a: number) => number + +const a: Xps = ['should-not-work']; // works, but shouldn't +>a : [number] +>['should-not-work'] : [string] +>'should-not-work' : "should-not-work" + +function t(...args: Xps) {} // should work +>t : (a: number) => void +>args : [number] + +class C { +>C : C + + constructor(a: number, b: string) { +>a : number +>b : string + } +} + +type Cps = Parameters; // should not work +>Cps : never +>C : typeof C + +type Ccps = ConstructorParameters; // should be [number, string] +>Ccps : [number, string] +>C : typeof C + +class D { +>D : D + + constructor(a: number, ...rest: string[]) { +>a : number +>rest : string[] + } +} +type Dcps = ConstructorParameters; // should be [number, ...string[]] +>Dcps : [number, ...string[]] +>D : typeof D + diff --git a/tests/cases/compiler/genericRestTypes.ts b/tests/cases/compiler/genericRestTypes.ts index cdfbd54f70d..78eb9b53f70 100644 --- a/tests/cases/compiler/genericRestTypes.ts +++ b/tests/cases/compiler/genericRestTypes.ts @@ -3,7 +3,6 @@ // Repro from #25793 // Gets the parameters of a function type as a tuple -type Parameters any> = T extends (...args: infer U) => any ? U : never; // Removes the first element from a tuple type Tail = ((...args: T) => any) extends ((head: any, ...tail: infer U) => any) ? U : never; diff --git a/tests/cases/compiler/parameterListAsTupleType.ts b/tests/cases/compiler/parameterListAsTupleType.ts new file mode 100644 index 00000000000..6bd4579298b --- /dev/null +++ b/tests/cases/compiler/parameterListAsTupleType.ts @@ -0,0 +1,23 @@ +function foo(a: number, b: string) { + return true; +} +type Foops = Parameters; + +const x = (a: number) => 5; +type Xps = Parameters; +const a: Xps = ['should-not-work']; // works, but shouldn't +function t(...args: Xps) {} // should work + +class C { + constructor(a: number, b: string) { + } +} + +type Cps = Parameters; // should not work +type Ccps = ConstructorParameters; // should be [number, string] + +class D { + constructor(a: number, ...rest: string[]) { + } +} +type Dcps = ConstructorParameters; // should be [number, ...string[]] diff --git a/tests/cases/conformance/types/rest/genericRestParameters1.ts b/tests/cases/conformance/types/rest/genericRestParameters1.ts index ac8434dc5b2..6572512cbfb 100644 --- a/tests/cases/conformance/types/rest/genericRestParameters1.ts +++ b/tests/cases/conformance/types/rest/genericRestParameters1.ts @@ -127,16 +127,14 @@ declare function f30 any)[]>(x: T, ...args: U): U; const c30 = f30(42, x => "" + x, x => x + 1); // [(x: number) => string, (x: number) => number] -type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; - type T01 = Parameters<(x: number, y: string, z: boolean) => void>; type T02 = Parameters<(...args: [number, string, boolean]) => void>; -type T03 = Parameters void>; -type T04 = Parameters void>; +type T03 = ConstructorParameters void>; +type T04 = ConstructorParameters void>; type T05 = Parameters<(...args: T[]) => void>; -type T06 = Parameters void>; +type T06 = ConstructorParameters void>; type T07 = Parameters<(...args: T) => void>; -type T08 = Parameters void>; +type T08 = ConstructorParameters void>; type T09 = Parameters; type Record1 = { diff --git a/tests/cases/conformance/types/rest/genericRestParameters2.ts b/tests/cases/conformance/types/rest/genericRestParameters2.ts index 1dc0d231dd2..12b9c4f8f1d 100644 --- a/tests/cases/conformance/types/rest/genericRestParameters2.ts +++ b/tests/cases/conformance/types/rest/genericRestParameters2.ts @@ -67,12 +67,10 @@ f20(42, ...t2); f20(42, "hello", ...t3); f20(42, "hello", ...t2, true); -type Parameters = T extends ((...args: infer U) => any) | (new(...args: infer U) => any) ? U : any[]; - type T01 = Parameters<(x: number, y: string, ...z: boolean[]) => void>; type T02 = Parameters<(...args: [number, string, ...boolean[]]) => void>; -type T03 = Parameters void>; -type T04 = Parameters void>; +type T03 = ConstructorParameters void>; +type T04 = ConstructorParameters void>; type T05 = Parameters<(x: string, ...args: T) => void>; type T06 = T05<[number, ...boolean[]]>; From 718c2cce9a279290cdbd4f0902df8ff94c115845 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 31 Aug 2018 16:10:42 +0000 Subject: [PATCH 130/163] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 20276 ++++++++-------- 1 file changed, 10138 insertions(+), 10138 deletions(-) diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 98bdf52817b..9d03da8d9b3 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1,10139 +1,10139 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - or -. For example '{0}' or '{1}'.]]> - - 또는 - 형식이어야 합니다. 예를 들어 '{0}' 또는 '{1}'입니다.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type.]]> - - 형식이어야 합니다.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ()' instead.]]> - - ()'를 사용하세요.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or -. For example '{0}' or '{1}'.]]> + + 또는 - 형식이어야 합니다. 예를 들어 '{0}' 또는 '{1}'입니다.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type.]]> + + 형식이어야 합니다.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ()' instead.]]> + + ()'를 사용하세요.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 183072b30e9335d3495be8909ccf590ea4457807 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 31 Aug 2018 13:06:22 -0700 Subject: [PATCH 131/163] Revert #26762, #26726, and #26317 in preparation for a clean PR fixing all the issues. --- src/compiler/checker.ts | 18 ++++------ .../genericRestParameters1.errors.txt | 8 +++++ .../genericRestParameters2.errors.txt | 6 ++++ ...ializersForwardReferencing1_es6.errors.txt | 15 +++++++- ...nitializersForwardReferencing1_es6.symbols | 8 ++--- ...rInitializersForwardReferencing1_es6.types | 34 +++++++++---------- 6 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 25f8483a40a..da1af15dfa4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1211,23 +1211,17 @@ namespace ts { // local types not visible outside the function body : false; } - if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.Variable) { - // expression inside parameter will lookup as normal variable scope when targeting es2015+ - if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && !isParameterPropertyDeclaration(lastLocation) && result.valueDeclaration.pos > lastLocation.end) { - useResult = false; - } - else if (result.flags & SymbolFlags.FunctionScopedVariable) { - // parameters are visible only inside function body, parameter list and return type - // technically for parameter list case here we might mix parameters and variables declared in function, - // however it is detected separately when checking initializers of parameters - // to make sure that they reference no variables declared after them. - useResult = + if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) { + // parameters are visible only inside function body, parameter list and return type + // technically for parameter list case here we might mix parameters and variables declared in function, + // however it is detected separately when checking initializers of parameters + // to make sure that they reference no variables declared after them. + useResult = lastLocation.kind === SyntaxKind.Parameter || ( lastLocation === (location).type && !!findAncestor(result.valueDeclaration, isParameter) ); - } } } else if (location.kind === SyntaxKind.ConditionalType) { diff --git a/tests/baselines/reference/genericRestParameters1.errors.txt b/tests/baselines/reference/genericRestParameters1.errors.txt index fe45ef518ed..6b6d7f60845 100644 --- a/tests/baselines/reference/genericRestParameters1.errors.txt +++ b/tests/baselines/reference/genericRestParameters1.errors.txt @@ -1,7 +1,11 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(22,1): error TS2556: Expected 3 arguments, but got 1 or more. tests/cases/conformance/types/rest/genericRestParameters1.ts(31,1): error TS2556: Expected 3 arguments, but got 1 or more. tests/cases/conformance/types/rest/genericRestParameters1.ts(133,40): error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + Types of parameters 'args' and 'args' are incompatible. + Type 'any[]' is not assignable to type 'T'. tests/cases/conformance/types/rest/genericRestParameters1.ts(134,51): error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. + Types of parameters 'args' and 'args' are incompatible. + Type 'any[]' is not assignable to type 'T'. tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. Type 'Function' provides no match for the signature '(...args: any[]): any'. tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS2322: Type '(a: never) => void' is not assignable to type '(...args: any[]) => void'. @@ -149,9 +153,13 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS232 type T07 = Parameters<(...args: T) => void>; ~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Types of parameters 'args' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type 'T'. type T08 = ConstructorParameters void>; ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. +!!! error TS2344: Types of parameters 'args' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type 'T'. type T09 = Parameters; ~~~~~~~~ !!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. diff --git a/tests/baselines/reference/genericRestParameters2.errors.txt b/tests/baselines/reference/genericRestParameters2.errors.txt index 5035544c51f..d6d3de9f322 100644 --- a/tests/baselines/reference/genericRestParameters2.errors.txt +++ b/tests/baselines/reference/genericRestParameters2.errors.txt @@ -1,4 +1,7 @@ tests/cases/conformance/types/rest/genericRestParameters2.ts(71,40): error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + Types of parameters 'x' and 'args' are incompatible. + Type 'any[]' is not assignable to type '[string, ...any[]]'. + Property '0' is missing in type 'any[]'. ==== tests/cases/conformance/types/rest/genericRestParameters2.ts (1 errors) ==== @@ -75,6 +78,9 @@ tests/cases/conformance/types/rest/genericRestParameters2.ts(71,40): error TS234 type T05 = Parameters<(x: string, ...args: T) => void>; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Types of parameters 'x' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type '[string, ...any[]]'. +!!! error TS2344: Property '0' is missing in type 'any[]'. type T06 = T05<[number, ...boolean[]]>; type P1 = T extends (head: infer A, ...tail: infer B) => any ? { head: A, tail: B } : any[]; diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt index 90390fbe3a4..ce4368081f1 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -1,21 +1,31 @@ +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(3,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(8,27): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(29,15): error TS2448: Block-scoped variable 'foo' used before its declaration. -==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (2 errors) ==== +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (6 errors) ==== let foo: string = ""; function f1 (bar = foo) { // unexpected compiler error; works at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. var foo: number = 2; return bar; // returns 1 } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. var foo: number = 2; return bar(); // returns 1 } function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. return bar; } @@ -36,6 +46,9 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t } function f7({[foo]: bar}: any[]) { + ~~~ +!!! error TS2448: Block-scoped variable 'foo' used before its declaration. +!!! related TS2728 tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts:30:9: 'foo' is declared here. let foo: number = 2; } diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols index c0d42ab8b11..b44c91e8afd 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols @@ -5,7 +5,7 @@ let foo: string = ""; function f1 (bar = foo) { // unexpected compiler error; works at runtime >f1 : Symbol(f1, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 21)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 2, 13)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7)) var foo: number = 2; >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7)) @@ -18,7 +18,7 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at >f2 : Symbol(f2, Decl(parameterInitializersForwardReferencing1_es6.ts, 5, 1)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13)) >baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7)) >baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) var foo: number = 2; @@ -31,7 +31,7 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime >f3 : Symbol(f3, Decl(parameterInitializersForwardReferencing1_es6.ts, 10, 1)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 13)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 23)) >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 23)) return bar; @@ -68,7 +68,7 @@ function f6 (async = async) { function f7({[foo]: bar}: any[]) { >f7 : Symbol(f7, Decl(parameterInitializersForwardReferencing1_es6.ts, 26, 1)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 29, 7)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 28, 13)) let foo: number = 2; diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types index 009ec47ddb8..a58d19c5755 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types @@ -4,44 +4,44 @@ let foo: string = ""; >"" : "" function f1 (bar = foo) { // unexpected compiler error; works at runtime ->f1 : (bar?: string) => string ->bar : string ->foo : string +>f1 : (bar?: number) => number +>bar : number +>foo : number var foo: number = 2; >foo : number >2 : 2 return bar; // returns 1 ->bar : string +>bar : number } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime ->f2 : (bar?: (baz?: string) => string) => string ->bar : (baz?: string) => string ->(baz = foo) => baz : (baz?: string) => string ->baz : string ->foo : string ->baz : string +>f2 : (bar?: (baz?: number) => number) => number +>bar : (baz?: number) => number +>(baz = foo) => baz : (baz?: number) => number +>baz : number +>foo : number +>baz : number var foo: number = 2; >foo : number >2 : 2 return bar(); // returns 1 ->bar() : string ->bar : (baz?: string) => string +>bar() : number +>bar : (baz?: number) => number } function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime ->f3 : (bar?: string, foo?: number) => string ->bar : string ->foo : string +>f3 : (bar?: number, foo?: number) => number +>bar : number +>foo : number >foo : number >2 : 2 return bar; ->bar : string +>bar : number } function f4 (foo, bar = foo) { @@ -74,7 +74,7 @@ function f6 (async = async) { function f7({[foo]: bar}: any[]) { >f7 : ({ [foo]: bar }: any[]) => void ->foo : string +>foo : number >bar : any let foo: number = 2; From e6a4e90cae051aafddab85cc868b57a327b3a861 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 31 Aug 2018 13:39:15 -0700 Subject: [PATCH 132/163] Update baselines to fix build (#26822) We started elaborating more errors in the 3 weeks since this PR was opened. --- .../baselines/reference/genericRestParameters1.errors.txt | 8 ++++++++ .../baselines/reference/genericRestParameters2.errors.txt | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/tests/baselines/reference/genericRestParameters1.errors.txt b/tests/baselines/reference/genericRestParameters1.errors.txt index fe45ef518ed..6b6d7f60845 100644 --- a/tests/baselines/reference/genericRestParameters1.errors.txt +++ b/tests/baselines/reference/genericRestParameters1.errors.txt @@ -1,7 +1,11 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(22,1): error TS2556: Expected 3 arguments, but got 1 or more. tests/cases/conformance/types/rest/genericRestParameters1.ts(31,1): error TS2556: Expected 3 arguments, but got 1 or more. tests/cases/conformance/types/rest/genericRestParameters1.ts(133,40): error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + Types of parameters 'args' and 'args' are incompatible. + Type 'any[]' is not assignable to type 'T'. tests/cases/conformance/types/rest/genericRestParameters1.ts(134,51): error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. + Types of parameters 'args' and 'args' are incompatible. + Type 'any[]' is not assignable to type 'T'. tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. Type 'Function' provides no match for the signature '(...args: any[]): any'. tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS2322: Type '(a: never) => void' is not assignable to type '(...args: any[]) => void'. @@ -149,9 +153,13 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS232 type T07 = Parameters<(...args: T) => void>; ~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Types of parameters 'args' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type 'T'. type T08 = ConstructorParameters void>; ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. +!!! error TS2344: Types of parameters 'args' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type 'T'. type T09 = Parameters; ~~~~~~~~ !!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. diff --git a/tests/baselines/reference/genericRestParameters2.errors.txt b/tests/baselines/reference/genericRestParameters2.errors.txt index 5035544c51f..d6d3de9f322 100644 --- a/tests/baselines/reference/genericRestParameters2.errors.txt +++ b/tests/baselines/reference/genericRestParameters2.errors.txt @@ -1,4 +1,7 @@ tests/cases/conformance/types/rest/genericRestParameters2.ts(71,40): error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + Types of parameters 'x' and 'args' are incompatible. + Type 'any[]' is not assignable to type '[string, ...any[]]'. + Property '0' is missing in type 'any[]'. ==== tests/cases/conformance/types/rest/genericRestParameters2.ts (1 errors) ==== @@ -75,6 +78,9 @@ tests/cases/conformance/types/rest/genericRestParameters2.ts(71,40): error TS234 type T05 = Parameters<(x: string, ...args: T) => void>; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Types of parameters 'x' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type '[string, ...any[]]'. +!!! error TS2344: Property '0' is missing in type 'any[]'. type T06 = T05<[number, ...boolean[]]>; type P1 = T extends (head: infer A, ...tail: infer B) => any ? { head: A, tail: B } : any[]; From 50ccd91263b5a3c7f53749e9bde3ca4520e5af0b Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 13 Aug 2018 16:21:37 -0700 Subject: [PATCH 133/163] Baseline the require of json file in js file --- .../requireOfJsonFileInJsFile.errors.txt | 33 ++++++++++ .../requireOfJsonFileInJsFile.symbols | 50 +++++++++++++++ .../reference/requireOfJsonFileInJsFile.types | 63 +++++++++++++++++++ .../compiler/requireOfJsonFileInJsFile.ts | 26 ++++++++ 4 files changed, 172 insertions(+) create mode 100644 tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileInJsFile.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileInJsFile.types create mode 100644 tests/cases/compiler/requireOfJsonFileInJsFile.ts diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt b/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt new file mode 100644 index 00000000000..39236816e57 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt @@ -0,0 +1,33 @@ +/user.js(2,7): error TS2339: Property 'b' does not exist on type '{ "a": number; }'. +/user.js(9,7): error TS2339: Property 'b' does not exist on type '{ "a": number; }'. +/user.js(12,7): error TS2322: Type '{ a: number; }' is not assignable to type '{ b: number; }'. + Property 'b' is missing in type '{ a: number; }'. + + +==== /user.js (3 errors) ==== + const json0 = require("./json.json"); + json0.b; // Error (good) + ~ +!!! error TS2339: Property 'b' does not exist on type '{ "a": number; }'. + + /** @type {{ b: number }} */ + const json1 = require("./json.json"); // No error (bad) + json1.b; // No error (OK since that's the type annotation) + + const js0 = require("./js.js"); + json0.b; // Error (good) + ~ +!!! error TS2339: Property 'b' does not exist on type '{ "a": number; }'. + + /** @type {{ b: number }} */ + const js1 = require("./js.js"); // Error (good) + ~~~ +!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ b: number; }'. +!!! error TS2322: Property 'b' is missing in type '{ a: number; }'. + js1.b; +==== /json.json (0 errors) ==== + { "a": 0 } + +==== /js.js (0 errors) ==== + module.exports = { a: 0 }; + \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.symbols b/tests/baselines/reference/requireOfJsonFileInJsFile.symbols new file mode 100644 index 00000000000..2a1e9b6ebd3 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileInJsFile.symbols @@ -0,0 +1,50 @@ +=== /user.js === +const json0 = require("./json.json"); +>json0 : Symbol(json0, Decl(user.js, 0, 5)) +>require : Symbol(require) +>"./json.json" : Symbol("/json", Decl(json.json, 0, 0)) + +json0.b; // Error (good) +>json0 : Symbol(json0, Decl(user.js, 0, 5)) + +/** @type {{ b: number }} */ +const json1 = require("./json.json"); // No error (bad) +>json1 : Symbol(json1, Decl(user.js, 4, 5)) +>require : Symbol(require) +>"./json.json" : Symbol("/json", Decl(json.json, 0, 0)) + +json1.b; // No error (OK since that's the type annotation) +>json1.b : Symbol(b, Decl(user.js, 3, 12)) +>json1 : Symbol(json1, Decl(user.js, 4, 5)) +>b : Symbol(b, Decl(user.js, 3, 12)) + +const js0 = require("./js.js"); +>js0 : Symbol(js0, Decl(user.js, 7, 5)) +>require : Symbol(require) +>"./js.js" : Symbol("/js", Decl(js.js, 0, 0)) + +json0.b; // Error (good) +>json0 : Symbol(json0, Decl(user.js, 0, 5)) + +/** @type {{ b: number }} */ +const js1 = require("./js.js"); // Error (good) +>js1 : Symbol(js1, Decl(user.js, 11, 5)) +>require : Symbol(require) +>"./js.js" : Symbol("/js", Decl(js.js, 0, 0)) + +js1.b; +>js1.b : Symbol(b, Decl(user.js, 10, 12)) +>js1 : Symbol(js1, Decl(user.js, 11, 5)) +>b : Symbol(b, Decl(user.js, 10, 12)) + +=== /json.json === +{ "a": 0 } +>"a" : Symbol("a", Decl(json.json, 0, 1)) + +=== /js.js === +module.exports = { a: 0 }; +>module.exports : Symbol("/js", Decl(js.js, 0, 0)) +>module : Symbol(export=, Decl(js.js, 0, 0)) +>exports : Symbol(export=, Decl(js.js, 0, 0)) +>a : Symbol(a, Decl(js.js, 0, 18)) + diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.types b/tests/baselines/reference/requireOfJsonFileInJsFile.types new file mode 100644 index 00000000000..b069c87c395 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileInJsFile.types @@ -0,0 +1,63 @@ +=== /user.js === +const json0 = require("./json.json"); +>json0 : { "a": number; } +>require("./json.json") : { "a": number; } +>require : any +>"./json.json" : "./json.json" + +json0.b; // Error (good) +>json0.b : any +>json0 : { "a": number; } +>b : any + +/** @type {{ b: number }} */ +const json1 = require("./json.json"); // No error (bad) +>json1 : { b: number; } +>require("./json.json") : { "a": number; } +>require : any +>"./json.json" : "./json.json" + +json1.b; // No error (OK since that's the type annotation) +>json1.b : number +>json1 : { b: number; } +>b : number + +const js0 = require("./js.js"); +>js0 : { a: number; } +>require("./js.js") : { a: number; } +>require : any +>"./js.js" : "./js.js" + +json0.b; // Error (good) +>json0.b : any +>json0 : { "a": number; } +>b : any + +/** @type {{ b: number }} */ +const js1 = require("./js.js"); // Error (good) +>js1 : { b: number; } +>require("./js.js") : { a: number; } +>require : any +>"./js.js" : "./js.js" + +js1.b; +>js1.b : number +>js1 : { b: number; } +>b : number + +=== /json.json === +{ "a": 0 } +>{ "a": 0 } : { "a": number; } +>"a" : number +>0 : 0 + +=== /js.js === +module.exports = { a: 0 }; +>module.exports = { a: 0 } : { a: number; } +>module.exports : { a: number; } +>module : { "/js": { a: number; }; } +>exports : { a: number; } +>{ a: 0 } : { a: number; } +>a : number +>0 : 0 + diff --git a/tests/cases/compiler/requireOfJsonFileInJsFile.ts b/tests/cases/compiler/requireOfJsonFileInJsFile.ts new file mode 100644 index 00000000000..be8a3b00746 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileInJsFile.ts @@ -0,0 +1,26 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @strict: true +// @resolveJsonModule: true + +// @Filename: /json.json +{ "a": 0 } + +// @Filename: /js.js +module.exports = { a: 0 }; + +// @Filename: /user.js +const json0 = require("./json.json"); +json0.b; // Error (good) + +/** @type {{ b: number }} */ +const json1 = require("./json.json"); // No error (bad) +json1.b; // No error (OK since that's the type annotation) + +const js0 = require("./js.js"); +json0.b; // Error (good) + +/** @type {{ b: number }} */ +const js1 = require("./js.js"); // Error (good) +js1.b; \ No newline at end of file From 9eb0c9a88fa4f1cc5e83a314e6710079f67aa4ca Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 14 Aug 2018 13:24:39 -0700 Subject: [PATCH 134/163] Use widened type (just like importing using module.exports = in js file) Fixes #26429 --- src/compiler/checker.ts | 9 ++++++++- .../reference/requireOfJsonFileInJsFile.errors.txt | 7 ++++++- .../baselines/reference/requireOfJsonFileTypes.types | 12 ++++++------ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da1af15dfa4..83cd2c1fe5c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5092,7 +5092,14 @@ namespace ts { // Handle export default expressions if (isSourceFile(declaration)) { const jsonSourceFile = cast(declaration, isJsonSourceFile); - return jsonSourceFile.statements.length ? checkExpression(jsonSourceFile.statements[0].expression) : emptyObjectType; + if (!jsonSourceFile.statements.length) { + return emptyObjectType; + } + const type = getWidenedLiteralType(checkExpression(jsonSourceFile.statements[0].expression)); + if (type.flags & TypeFlags.Object) { + return getRegularTypeOfObjectLiteral(type); + } + return type; } if (declaration.kind === SyntaxKind.ExportAssignment) { return checkExpression((declaration).expression); diff --git a/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt b/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt index 39236816e57..dcc976a1b5b 100644 --- a/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileInJsFile.errors.txt @@ -1,10 +1,12 @@ /user.js(2,7): error TS2339: Property 'b' does not exist on type '{ "a": number; }'. +/user.js(5,7): error TS2322: Type '{ "a": number; }' is not assignable to type '{ b: number; }'. + Property 'b' is missing in type '{ "a": number; }'. /user.js(9,7): error TS2339: Property 'b' does not exist on type '{ "a": number; }'. /user.js(12,7): error TS2322: Type '{ a: number; }' is not assignable to type '{ b: number; }'. Property 'b' is missing in type '{ a: number; }'. -==== /user.js (3 errors) ==== +==== /user.js (4 errors) ==== const json0 = require("./json.json"); json0.b; // Error (good) ~ @@ -12,6 +14,9 @@ /** @type {{ b: number }} */ const json1 = require("./json.json"); // No error (bad) + ~~~~~ +!!! error TS2322: Type '{ "a": number; }' is not assignable to type '{ b: number; }'. +!!! error TS2322: Property 'b' is missing in type '{ "a": number; }'. json1.b; // No error (OK since that's the type annotation) const js0 = require("./js.js"); diff --git a/tests/baselines/reference/requireOfJsonFileTypes.types b/tests/baselines/reference/requireOfJsonFileTypes.types index d9cd38cd58f..d4587696fc7 100644 --- a/tests/baselines/reference/requireOfJsonFileTypes.types +++ b/tests/baselines/reference/requireOfJsonFileTypes.types @@ -6,10 +6,10 @@ import c = require('./c.json'); >c : (string | null)[] import d = require('./d.json'); ->d : "dConfig" +>d : string import e = require('./e.json'); ->e : -10 +>e : number import f = require('./f.json'); >f : number[] @@ -64,14 +64,14 @@ const stringOrNumberOrNull: string | number | null = c[0]; >0 : 0 stringLiteral = d; ->stringLiteral = d : "dConfig" +>stringLiteral = d : string >stringLiteral : string ->d : "dConfig" +>d : string numberLiteral = e; ->numberLiteral = e : -10 +>numberLiteral = e : number >numberLiteral : number ->e : -10 +>e : number numberLiteral = f[0]; >numberLiteral = f[0] : number From e41dbcdccd9c877c777cf63d2c13e12afc26a629 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 31 Aug 2018 13:05:52 -0700 Subject: [PATCH 135/163] Support json module emit when module emit is commonjs, amd, es2015 or esnext Fixes #25755 and #26020 --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- src/compiler/emitter.ts | 4 +++- src/compiler/program.ts | 6 +++--- src/compiler/transformers/module/module.ts | 12 ++++++++--- src/compiler/utilities.ts | 12 +++++++++++ ...WithModuleNodeResolutionEmitAmd.errors.txt | 12 ----------- ...eWithModuleNodeResolutionEmitAmdOutFile.js | 20 +++++++++++++++++++ ...ModuleNodeResolutionEmitAmdOutFile.symbols | 12 +++++++++++ ...thModuleNodeResolutionEmitAmdOutFile.types | 16 +++++++++++++++ ...hModuleNodeResolutionEmitEs2015.errors.txt | 12 ----------- ...hModuleNodeResolutionEmitEsNext.errors.txt | 12 ----------- ...ithModuleNodeResolutionEmitNone.errors.txt | 4 ++-- ...hModuleNodeResolutionEmitSystem.errors.txt | 4 ++-- ...WithModuleNodeResolutionEmitUmd.errors.txt | 4 ++-- ...eWithModuleNodeResolutionEmitAmdOutFile.ts | 14 +++++++++++++ 16 files changed, 97 insertions(+), 51 deletions(-) delete mode 100644 tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmd.errors.txt create mode 100644 tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.js create mode 100644 tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.symbols create mode 100644 tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.types delete mode 100644 tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.errors.txt delete mode 100644 tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.errors.txt create mode 100644 tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da1af15dfa4..6680c390a0a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2252,7 +2252,7 @@ namespace ts { else if (!compilerOptions.resolveJsonModule && fileExtensionIs(moduleReference, Extension.Json) && getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs && - getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) { + hasJsonModuleEmitEnabled(compilerOptions)) { error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference); } else { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 9ba3c4e8cf1..de61586dcdd 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2892,7 +2892,7 @@ "category": "Error", "code": 5070 }, - "Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.": { + "Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.": { "category": "Error", "code": 5071 }, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 613fe7f5c84..8cb1d4f34a9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1780,7 +1780,9 @@ namespace ts { function emitExpressionStatement(node: ExpressionStatement) { emitExpression(node.expression); - if (!isJsonSourceFile(currentSourceFile)) { + // Emit semicolon in non json files + // or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation) + if (!isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) { writeSemicolon(); } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 2bbf17e6098..16825209e59 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2549,9 +2549,9 @@ namespace ts { if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) { createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule"); } - // Any emit other than common js is error - else if (getEmitModuleKind(options) !== ModuleKind.CommonJS) { - createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs, "resolveJsonModule", "module"); + // Any emit other than common js, amd, es2015 or esnext is error + else if (!hasJsonModuleEmitEnabled(options)) { + createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module"); } } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 09bf1b75b9c..1b3a623c32d 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -53,7 +53,10 @@ namespace ts { * @param node The SourceFile node. */ function transformSourceFile(node: SourceFile) { - if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & TransformFlags.ContainsDynamicImport)) { + if (node.isDeclarationFile || + !(isEffectiveExternalModule(node, compilerOptions) || + node.transformFlags & TransformFlags.ContainsDynamicImport || + (isJsonSourceFile(node) && hasJsonModuleEmitEnabled(compilerOptions) && (compilerOptions.out || compilerOptions.outFile)))) { return node; } @@ -117,6 +120,7 @@ namespace ts { function transformAMDModule(node: SourceFile) { const define = createIdentifier("define"); const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions); + const jsonSourceFile = isJsonSourceFile(node) && node; // An AMD define function has the following shape: // @@ -158,7 +162,7 @@ namespace ts { // Add the dependency array argument: // // ["require", "exports", module1", "module2", ...] - createArrayLiteral([ + createArrayLiteral(jsonSourceFile ? emptyArray : [ createLiteral("require"), createLiteral("exports"), ...aliasedModuleNames, @@ -168,7 +172,9 @@ namespace ts { // Add the module body function argument: // // function (require, exports, module1, module2) ... - createFunctionExpression( + jsonSourceFile ? + jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : createObjectLiteral() : + createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index da13fcb4391..6b8115112e1 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -7004,6 +7004,18 @@ namespace ts { return moduleResolution; } + export function hasJsonModuleEmitEnabled(options: CompilerOptions) { + switch (getEmitModuleKind(options)) { + case ModuleKind.CommonJS: + case ModuleKind.AMD: + case ModuleKind.ES2015: + case ModuleKind.ESNext: + return true; + default: + return false; + } + } + export function unreachableCodeIsError(options: CompilerOptions): boolean { return options.allowUnreachableCode === false; } diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmd.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmd.errors.txt deleted file mode 100644 index eab6745285b..00000000000 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmd.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. - - -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. -==== tests/cases/compiler/file1.ts (0 errors) ==== - import * as b from './b.json'; - -==== tests/cases/compiler/b.json (0 errors) ==== - { - "a": true, - "b": "hello" - } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.js b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.js new file mode 100644 index 00000000000..f6aa6d997be --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.js @@ -0,0 +1,20 @@ +//// [tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts] //// + +//// [file1.ts] +import * as b from './b.json'; + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [out/output.js] +define("b", [], { + "a": true, + "b": "hello" +}); +define("file1", ["require", "exports"], function (require, exports) { + "use strict"; + exports.__esModule = true; +}); diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.symbols b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.symbols new file mode 100644 index 00000000000..827f2e674e6 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/file1.ts === +import * as b from './b.json'; +>b : Symbol(b, Decl(file1.ts, 0, 6)) + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.types b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.types new file mode 100644 index 00000000000..9e5cc29d342 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/file1.ts === +import * as b from './b.json'; +>b : { "a": boolean; "b": string; } + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.errors.txt deleted file mode 100644 index eab6745285b..00000000000 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEs2015.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. - - -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. -==== tests/cases/compiler/file1.ts (0 errors) ==== - import * as b from './b.json'; - -==== tests/cases/compiler/b.json (0 errors) ==== - { - "a": true, - "b": "hello" - } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.errors.txt deleted file mode 100644 index b9c37651205..00000000000 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitEsNext.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. - - -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. -==== tests/cases/compiler/file1.ts (0 errors) ==== - import * as b from './b.json'; - -==== tests/cases/compiler/b.json (0 errors) ==== - { - "a": true, - "b": "hello" - } \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt index 8a40ac52e90..6772461f487 100644 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitNone.errors.txt @@ -1,8 +1,8 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. tests/cases/compiler/file1.ts(1,1): error TS1148: Cannot use imports, exports, or module augmentations when '--module' is 'none'. -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. ==== tests/cases/compiler/file1.ts (1 errors) ==== import * as b from './b.json'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt index eab6745285b..8b570387ce7 100644 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitSystem.errors.txt @@ -1,7 +1,7 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. ==== tests/cases/compiler/file1.ts (0 errors) ==== import * as b from './b.json'; diff --git a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt index eab6745285b..8b570387ce7 100644 --- a/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt +++ b/tests/baselines/reference/requireOfJsonFileWithModuleNodeResolutionEmitUmd.errors.txt @@ -1,7 +1,7 @@ -error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. -!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'. +!!! error TS5071: Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'. ==== tests/cases/compiler/file1.ts (0 errors) ==== import * as b from './b.json'; diff --git a/tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts b/tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts new file mode 100644 index 00000000000..6c73015d222 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithModuleNodeResolutionEmitAmdOutFile.ts @@ -0,0 +1,14 @@ +// @module: amd +// @moduleResolution: node +// @outFile: out/output.js +// @fullEmitPaths: true +// @resolveJsonModule: true + +// @Filename: file1.ts +import * as b from './b.json'; + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file From f1a179a314fdcc4875a90e9f75ee4a18e7354e03 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 31 Aug 2018 15:24:53 -0700 Subject: [PATCH 136/163] Narrowing unknown by typeof object to object | null Fixes #26327 --- src/compiler/checker.ts | 3 +++ .../reference/narrowUnknownByTypeofObject.js | 14 ++++++++++++++ .../narrowUnknownByTypeofObject.symbols | 13 +++++++++++++ .../reference/narrowUnknownByTypeofObject.types | 16 ++++++++++++++++ .../compiler/narrowUnknownByTypeofObject.ts | 6 ++++++ 5 files changed, 52 insertions(+) create mode 100644 tests/baselines/reference/narrowUnknownByTypeofObject.js create mode 100644 tests/baselines/reference/narrowUnknownByTypeofObject.symbols create mode 100644 tests/baselines/reference/narrowUnknownByTypeofObject.types create mode 100644 tests/cases/compiler/narrowUnknownByTypeofObject.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da1af15dfa4..ac5733392e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14925,6 +14925,9 @@ namespace ts { return type; } if (assumeTrue && !(type.flags & TypeFlags.Union)) { + if (type.flags & TypeFlags.Unknown && literal.text === "object") { + return getUnionType([nonPrimitiveType, nullType]); + } // We narrow a non-union type to an exact primitive type if the non-union type // is a supertype of that primitive type. For example, type 'any' can be narrowed // to one of the primitive types. diff --git a/tests/baselines/reference/narrowUnknownByTypeofObject.js b/tests/baselines/reference/narrowUnknownByTypeofObject.js new file mode 100644 index 00000000000..076d91e0df8 --- /dev/null +++ b/tests/baselines/reference/narrowUnknownByTypeofObject.js @@ -0,0 +1,14 @@ +//// [narrowUnknownByTypeofObject.ts] +function foo(x: unknown) { + if (typeof x === "object") { + x + } +} + + +//// [narrowUnknownByTypeofObject.js] +function foo(x) { + if (typeof x === "object") { + x; + } +} diff --git a/tests/baselines/reference/narrowUnknownByTypeofObject.symbols b/tests/baselines/reference/narrowUnknownByTypeofObject.symbols new file mode 100644 index 00000000000..ee3ec77ec04 --- /dev/null +++ b/tests/baselines/reference/narrowUnknownByTypeofObject.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/narrowUnknownByTypeofObject.ts === +function foo(x: unknown) { +>foo : Symbol(foo, Decl(narrowUnknownByTypeofObject.ts, 0, 0)) +>x : Symbol(x, Decl(narrowUnknownByTypeofObject.ts, 0, 13)) + + if (typeof x === "object") { +>x : Symbol(x, Decl(narrowUnknownByTypeofObject.ts, 0, 13)) + + x +>x : Symbol(x, Decl(narrowUnknownByTypeofObject.ts, 0, 13)) + } +} + diff --git a/tests/baselines/reference/narrowUnknownByTypeofObject.types b/tests/baselines/reference/narrowUnknownByTypeofObject.types new file mode 100644 index 00000000000..98225861d1e --- /dev/null +++ b/tests/baselines/reference/narrowUnknownByTypeofObject.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/narrowUnknownByTypeofObject.ts === +function foo(x: unknown) { +>foo : (x: unknown) => void +>x : unknown + + if (typeof x === "object") { +>typeof x === "object" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"object" : "object" + + x +>x : object | null + } +} + diff --git a/tests/cases/compiler/narrowUnknownByTypeofObject.ts b/tests/cases/compiler/narrowUnknownByTypeofObject.ts new file mode 100644 index 00000000000..36e1c18f4f6 --- /dev/null +++ b/tests/cases/compiler/narrowUnknownByTypeofObject.ts @@ -0,0 +1,6 @@ +// @strictNullChecks: true +function foo(x: unknown) { + if (typeof x === "object") { + x + } +} From f2d26fd0bba373bf4a8d2cf2dd8cbfb9abf310af Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Sat, 1 Sep 2018 19:48:47 -0400 Subject: [PATCH 137/163] Argument arity error should only consider signatures with correct type argument arity. Fixes #26835. --- src/compiler/checker.ts | 19 +++++++++++-------- .../reference/functionCall18.errors.txt | 11 +++++++++++ tests/baselines/reference/functionCall18.js | 9 +++++++++ .../reference/functionCall18.symbols | 17 +++++++++++++++++ .../baselines/reference/functionCall18.types | 16 ++++++++++++++++ tests/cases/compiler/functionCall18.ts | 4 ++++ 6 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/functionCall18.errors.txt create mode 100644 tests/baselines/reference/functionCall18.js create mode 100644 tests/baselines/reference/functionCall18.symbols create mode 100644 tests/baselines/reference/functionCall18.types create mode 100644 tests/cases/compiler/functionCall18.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da1af15dfa4..e52f89e9a06 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19174,14 +19174,17 @@ namespace ts { else if (candidateForTypeArgumentError) { checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression).typeArguments!, /*reportErrors*/ true, fallbackError); } - else if (typeArguments && every(signatures, sig => typeArguments!.length < getMinTypeArgumentCount(sig.typeParameters) || typeArguments!.length > length(sig.typeParameters))) { - diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments)); - } - else if (!isDecorator) { - diagnostics.add(getArgumentArityError(node, signatures, args)); - } - else if (fallbackError) { - diagnostics.add(createDiagnosticForNode(node, fallbackError)); + else { + const signaturesWithCorrectTypeArgumentArity = filter(signatures, s => hasCorrectTypeArgumentArity(s, typeArguments)); + if (signaturesWithCorrectTypeArgumentArity.length === 0) { + diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments!)); + } + else if (!isDecorator) { + diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args)); + } + else if (fallbackError) { + diagnostics.add(createDiagnosticForNode(node, fallbackError)); + } } return produceDiagnostics || !args ? resolveErrorCall(node) : getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray); diff --git a/tests/baselines/reference/functionCall18.errors.txt b/tests/baselines/reference/functionCall18.errors.txt new file mode 100644 index 00000000000..99d7415425c --- /dev/null +++ b/tests/baselines/reference/functionCall18.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/functionCall18.ts(4,1): error TS2554: Expected 2 arguments, but got 1. + + +==== tests/cases/compiler/functionCall18.ts (1 errors) ==== + // Repro from #26835 + declare function foo(a: T, b: T); + declare function foo(a: {}); + foo("hello"); + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2554: Expected 2 arguments, but got 1. + \ No newline at end of file diff --git a/tests/baselines/reference/functionCall18.js b/tests/baselines/reference/functionCall18.js new file mode 100644 index 00000000000..6e059205c62 --- /dev/null +++ b/tests/baselines/reference/functionCall18.js @@ -0,0 +1,9 @@ +//// [functionCall18.ts] +// Repro from #26835 +declare function foo(a: T, b: T); +declare function foo(a: {}); +foo("hello"); + + +//// [functionCall18.js] +foo("hello"); diff --git a/tests/baselines/reference/functionCall18.symbols b/tests/baselines/reference/functionCall18.symbols new file mode 100644 index 00000000000..ebf635d91e9 --- /dev/null +++ b/tests/baselines/reference/functionCall18.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/functionCall18.ts === +// Repro from #26835 +declare function foo(a: T, b: T); +>foo : Symbol(foo, Decl(functionCall18.ts, 0, 0), Decl(functionCall18.ts, 1, 36)) +>T : Symbol(T, Decl(functionCall18.ts, 1, 21)) +>a : Symbol(a, Decl(functionCall18.ts, 1, 24)) +>T : Symbol(T, Decl(functionCall18.ts, 1, 21)) +>b : Symbol(b, Decl(functionCall18.ts, 1, 29)) +>T : Symbol(T, Decl(functionCall18.ts, 1, 21)) + +declare function foo(a: {}); +>foo : Symbol(foo, Decl(functionCall18.ts, 0, 0), Decl(functionCall18.ts, 1, 36)) +>a : Symbol(a, Decl(functionCall18.ts, 2, 21)) + +foo("hello"); +>foo : Symbol(foo, Decl(functionCall18.ts, 0, 0), Decl(functionCall18.ts, 1, 36)) + diff --git a/tests/baselines/reference/functionCall18.types b/tests/baselines/reference/functionCall18.types new file mode 100644 index 00000000000..90fa33f0617 --- /dev/null +++ b/tests/baselines/reference/functionCall18.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/functionCall18.ts === +// Repro from #26835 +declare function foo(a: T, b: T); +>foo : { (a: T, b: T): any; (a: {}): any; } +>a : T +>b : T + +declare function foo(a: {}); +>foo : { (a: T, b: T): any; (a: {}): any; } +>a : {} + +foo("hello"); +>foo("hello") : any +>foo : { (a: T, b: T): any; (a: {}): any; } +>"hello" : "hello" + diff --git a/tests/cases/compiler/functionCall18.ts b/tests/cases/compiler/functionCall18.ts new file mode 100644 index 00000000000..848580db729 --- /dev/null +++ b/tests/cases/compiler/functionCall18.ts @@ -0,0 +1,4 @@ +// Repro from #26835 +declare function foo(a: T, b: T); +declare function foo(a: {}); +foo("hello"); From 059fcc9aa95a75019230b8ec30d2ea1bb8447396 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 2 Sep 2018 08:58:00 -0700 Subject: [PATCH 138/163] Defer reduction of identical function types in unions and intersections --- src/compiler/checker.ts | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da1af15dfa4..3b736093e78 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8691,10 +8691,7 @@ namespace ts { const len = typeSet.length; const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); if (index < 0) { - if (!(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && - type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) { - typeSet.splice(~index, 0, type); - } + typeSet.splice(~index, 0, type); } } } @@ -8710,15 +8707,6 @@ namespace ts { return includes; } - function containsIdenticalType(types: ReadonlyArray, type: Type) { - for (const t of types) { - if (isTypeIdenticalTo(t, type)) { - return true; - } - } - return false; - } - function isSubtypeOfAny(source: Type, targets: ReadonlyArray): boolean { for (const target of targets) { if (source !== target && isTypeSubtypeOf(source, target) && ( @@ -8899,10 +8887,7 @@ namespace ts { if (flags & TypeFlags.AnyOrUnknown) { if (type === wildcardType) includes |= TypeFlags.Wildcard; } - else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type) && - !(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && - type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && - containsIdenticalType(typeSet, type))) { + else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { typeSet.push(type); } } From d9e0d6b07f91c19621db4317b33cc1de5fb190b5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 2 Sep 2018 08:58:32 -0700 Subject: [PATCH 139/163] Accept new baselines --- .../checkJsxChildrenProperty4.errors.txt | 12 +++++------ .../overrideBaseIntersectionMethod.types | 4 ++-- .../typeParameterExtendingUnion1.types | 4 ++-- .../typeParameterExtendingUnion2.types | 8 ++++---- .../reference/unionTypeMembers.types | 20 +++++++++---------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/baselines/reference/checkJsxChildrenProperty4.errors.txt b/tests/baselines/reference/checkJsxChildrenProperty4.errors.txt index 4851bc3b466..8e7a3adb518 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty4.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenProperty4.errors.txt @@ -1,8 +1,8 @@ tests/cases/conformance/jsx/file.tsx(24,28): error TS2551: Property 'NAme' does not exist on type 'IUser'. Did you mean 'Name'? -tests/cases/conformance/jsx/file.tsx(32,10): error TS2322: Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IFetchUserProps'. +tests/cases/conformance/jsx/file.tsx(32,10): error TS2322: Type '{ children: (((user: IUser) => Element) | ((user: IUser) => Element))[]; }' is not assignable to type 'IFetchUserProps'. Types of property 'children' are incompatible. - Type '((user: IUser) => Element)[]' is not assignable to type '(user: IUser) => Element'. - Type '((user: IUser) => Element)[]' provides no match for the signature '(user: IUser): Element'. + Type '(((user: IUser) => Element) | ((user: IUser) => Element))[]' is not assignable to type '(user: IUser) => Element'. + Type '(((user: IUser) => Element) | ((user: IUser) => Element))[]' provides no match for the signature '(user: IUser): Element'. ==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== @@ -42,10 +42,10 @@ tests/cases/conformance/jsx/file.tsx(32,10): error TS2322: Type '{ children: ((u return ( ~~~~~~~~~ -!!! error TS2322: Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IFetchUserProps'. +!!! error TS2322: Type '{ children: (((user: IUser) => Element) | ((user: IUser) => Element))[]; }' is not assignable to type 'IFetchUserProps'. !!! error TS2322: Types of property 'children' are incompatible. -!!! error TS2322: Type '((user: IUser) => Element)[]' is not assignable to type '(user: IUser) => Element'. -!!! error TS2322: Type '((user: IUser) => Element)[]' provides no match for the signature '(user: IUser): Element'. +!!! error TS2322: Type '(((user: IUser) => Element) | ((user: IUser) => Element))[]' is not assignable to type '(user: IUser) => Element'. +!!! error TS2322: Type '(((user: IUser) => Element) | ((user: IUser) => Element))[]' provides no match for the signature '(user: IUser): Element'. diff --git a/tests/baselines/reference/overrideBaseIntersectionMethod.types b/tests/baselines/reference/overrideBaseIntersectionMethod.types index 57d06fe648f..3ca80a06a1a 100644 --- a/tests/baselines/reference/overrideBaseIntersectionMethod.types +++ b/tests/baselines/reference/overrideBaseIntersectionMethod.types @@ -78,9 +78,9 @@ class Foo extends WithLocation(Point) { return super.getLocation() >super.getLocation() : [number, number] ->super.getLocation : () => [number, number] +>super.getLocation : (() => [number, number]) & (() => [number, number]) >super : WithLocation.(Anonymous class) & Point ->getLocation : () => [number, number] +>getLocation : (() => [number, number]) & (() => [number, number]) } whereAmI() { >whereAmI : () => [number, number] diff --git a/tests/baselines/reference/typeParameterExtendingUnion1.types b/tests/baselines/reference/typeParameterExtendingUnion1.types index 85c2096823b..e3eb4c14ca0 100644 --- a/tests/baselines/reference/typeParameterExtendingUnion1.types +++ b/tests/baselines/reference/typeParameterExtendingUnion1.types @@ -30,9 +30,9 @@ function f(a: T) { a.run(); >a.run() : void ->a.run : () => void +>a.run : (() => void) | (() => void) >a : T ->run : () => void +>run : (() => void) | (() => void) run(a); >run(a) : void diff --git a/tests/baselines/reference/typeParameterExtendingUnion2.types b/tests/baselines/reference/typeParameterExtendingUnion2.types index c19076ddd68..074ac3b3fff 100644 --- a/tests/baselines/reference/typeParameterExtendingUnion2.types +++ b/tests/baselines/reference/typeParameterExtendingUnion2.types @@ -19,9 +19,9 @@ function run(a: Cat | Dog) { a.run(); >a.run() : void ->a.run : () => void +>a.run : (() => void) | (() => void) >a : Cat | Dog ->run : () => void +>run : (() => void) | (() => void) } function f(a: T) { @@ -30,9 +30,9 @@ function f(a: T) { a.run(); >a.run() : void ->a.run : () => void +>a.run : (() => void) | (() => void) >a : T ->run : () => void +>run : (() => void) | (() => void) run(a); >run(a) : void diff --git a/tests/baselines/reference/unionTypeMembers.types b/tests/baselines/reference/unionTypeMembers.types index 5b19ab5540c..e26d00c45f9 100644 --- a/tests/baselines/reference/unionTypeMembers.types +++ b/tests/baselines/reference/unionTypeMembers.types @@ -95,9 +95,9 @@ str = x.commonMethodType(str); // (a: string) => string so result should be stri >str = x.commonMethodType(str) : string >str : string >x.commonMethodType(str) : string ->x.commonMethodType : (a: string) => string +>x.commonMethodType : ((a: string) => string) | ((a: string) => string) >x : I1 | I2 ->commonMethodType : (a: string) => string +>commonMethodType : ((a: string) => string) | ((a: string) => string) >str : string strOrNum = x.commonPropertyDifferenType; @@ -133,36 +133,36 @@ num = x.commonMethodWithTypeParameter(num); >num = x.commonMethodWithTypeParameter(num) : number >num : number >x.commonMethodWithTypeParameter(num) : number ->x.commonMethodWithTypeParameter : (a: number) => number +>x.commonMethodWithTypeParameter : ((a: number) => number) | ((a: number) => number) >x : I1 | I2 ->commonMethodWithTypeParameter : (a: number) => number +>commonMethodWithTypeParameter : ((a: number) => number) | ((a: number) => number) >num : number num = x.commonMethodWithOwnTypeParameter(num); >num = x.commonMethodWithOwnTypeParameter(num) : number >num : number >x.commonMethodWithOwnTypeParameter(num) : number ->x.commonMethodWithOwnTypeParameter : (a: U) => U +>x.commonMethodWithOwnTypeParameter : ((a: U) => U) | ((a: U) => U) >x : I1 | I2 ->commonMethodWithOwnTypeParameter : (a: U) => U +>commonMethodWithOwnTypeParameter : ((a: U) => U) | ((a: U) => U) >num : number str = x.commonMethodWithOwnTypeParameter(str); >str = x.commonMethodWithOwnTypeParameter(str) : string >str : string >x.commonMethodWithOwnTypeParameter(str) : string ->x.commonMethodWithOwnTypeParameter : (a: U) => U +>x.commonMethodWithOwnTypeParameter : ((a: U) => U) | ((a: U) => U) >x : I1 | I2 ->commonMethodWithOwnTypeParameter : (a: U) => U +>commonMethodWithOwnTypeParameter : ((a: U) => U) | ((a: U) => U) >str : string strOrNum = x.commonMethodWithOwnTypeParameter(strOrNum); >strOrNum = x.commonMethodWithOwnTypeParameter(strOrNum) : string | number >strOrNum : string | number >x.commonMethodWithOwnTypeParameter(strOrNum) : string | number ->x.commonMethodWithOwnTypeParameter : (a: U) => U +>x.commonMethodWithOwnTypeParameter : ((a: U) => U) | ((a: U) => U) >x : I1 | I2 ->commonMethodWithOwnTypeParameter : (a: U) => U +>commonMethodWithOwnTypeParameter : ((a: U) => U) | ((a: U) => U) >strOrNum : string | number x.propertyOnlyInI1; // error From 239a7b9a4f2ca6bc766a4ee0fc0614c3a7ce0b15 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Tue, 4 Sep 2018 13:35:57 +0200 Subject: [PATCH 140/163] better condition for file include exhaustiveness check As `files` always contains declaration files of external libraries, lib files and declaration files from typeRoots, the previous condition evaluated to false for probably all projects out there. This changes the condition to compare array length after filtering out all declaration files. That avoids unnecessary work of path normalization in the common case where everything is ok. --- src/compiler/program.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 2bbf17e6098..c6473f2cb99 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2432,12 +2432,14 @@ namespace ts { } // List of collected files is complete; validate exhautiveness if this is a project with a file list - if (options.composite && rootNames.length < files.length) { - const normalizedRootNames = rootNames.map(r => normalizePath(r).toLowerCase()); - const sourceFiles = files.filter(f => !f.isDeclarationFile).map(f => normalizePath(f.path).toLowerCase()); - for (const file of sourceFiles) { - if (normalizedRootNames.every(r => r !== file)) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file)); + if (options.composite) { + const sourceFiles = files.filter(f => !f.isDeclarationFile); + if (rootNames.length < sourceFiles.length) { + const normalizedRootNames = rootNames.map(r => normalizePath(r).toLowerCase()); + for (const file of sourceFiles.map(f => normalizePath(f.path).toLowerCase())) { + if (normalizedRootNames.indexOf(file) === -1) { + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file)); + } } } } From 540e8b9eb01dd42a7f7860a802e7c5411f41d604 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 4 Sep 2018 09:29:19 -0700 Subject: [PATCH 141/163] Collect jsdoc tags for type parameters (#26824) Before the template tag, there was no reason to do this, but now you can add JSDoc for type parameters in Typescript. --- src/compiler/utilities.ts | 25 +++++++++++-- src/services/signatureHelp.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 16 ++++++-- tests/baselines/reference/api/typescript.d.ts | 16 ++++++-- .../fourslash/signatureHelpTypeArguments2.ts | 37 +++++++++++++++++++ 5 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 tests/cases/fourslash/signatureHelpTypeArguments2.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index da13fcb4391..7c5f2108c1e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2116,6 +2116,10 @@ namespace ts { result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration)); break; } + if (node.kind === SyntaxKind.TypeParameter) { + result = addRange(result, getJSDocTypeParameterTags(node as TypeParameterDeclaration)); + break; + } node = getNextJSDocCommentLocation(node); } return result || emptyArray; @@ -4994,15 +4998,14 @@ namespace ts { /** * Gets the JSDoc parameter tags for the node if present. * - * @remarks Returns any JSDoc param tag that matches the provided + * @remarks Returns any JSDoc param tag whose name matches the provided * parameter, whether a param tag on a containing function * expression, or a param tag on a variable declaration whose * initializer is the containing function. The tags closest to the * node are returned first, so in the previous example, the param * tag on the containing function expression would be first. * - * Does not return tags for binding patterns, because JSDoc matches - * parameters by name and binding patterns do not have a name. + * For binding patterns, parameter tags are matched by position. */ export function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray { if (param.name) { @@ -5023,6 +5026,22 @@ namespace ts { return emptyArray; } + /** + * Gets the JSDoc type parameter tags for the node if present. + * + * @remarks Returns any JSDoc template tag whose names match the provided + * parameter, whether a template tag on a containing function + * expression, or a template tag on a variable declaration whose + * initializer is the containing function. The tags closest to the + * node are returned first, so in the previous example, the template + * tag on the containing function expression would be first. + */ + export function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray { + const name = param.name.escapedText; + return getJSDocTags(param.parent).filter((tag): tag is JSDocTemplateTag => + isJSDocTemplateTag(tag) && tag.typeParameters.some(tp => tp.name.escapedText === name)); + } + /** * Return true if the node has JSDoc parameter tags. * diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 5211b244e21..b6174be75e0 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -591,6 +591,6 @@ namespace ts.SignatureHelp { const param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!; printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer); }); - return { name: typeParameter.symbol.name, documentation: emptyArray, displayParts, isOptional: false }; + return { name: typeParameter.symbol.name, documentation: typeParameter.symbol.getDocumentationComment(checker), displayParts, isOptional: false }; } } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index fd291c5387f..d34298c59d5 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3208,17 +3208,27 @@ declare namespace ts { /** * Gets the JSDoc parameter tags for the node if present. * - * @remarks Returns any JSDoc param tag that matches the provided + * @remarks Returns any JSDoc param tag whose name matches the provided * parameter, whether a param tag on a containing function * expression, or a param tag on a variable declaration whose * initializer is the containing function. The tags closest to the * node are returned first, so in the previous example, the param * tag on the containing function expression would be first. * - * Does not return tags for binding patterns, because JSDoc matches - * parameters by name and binding patterns do not have a name. + * For binding patterns, parameter tags are matched by position. */ function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray; + /** + * Gets the JSDoc type parameter tags for the node if present. + * + * @remarks Returns any JSDoc template tag whose names match the provided + * parameter, whether a template tag on a containing function + * expression, or a template tag on a variable declaration whose + * initializer is the containing function. The tags closest to the + * node are returned first, so in the previous example, the template + * tag on the containing function expression would be first. + */ + function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray; /** * Return true if the node has JSDoc parameter tags. * diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 852ca173b33..2a1a44d54f2 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3208,17 +3208,27 @@ declare namespace ts { /** * Gets the JSDoc parameter tags for the node if present. * - * @remarks Returns any JSDoc param tag that matches the provided + * @remarks Returns any JSDoc param tag whose name matches the provided * parameter, whether a param tag on a containing function * expression, or a param tag on a variable declaration whose * initializer is the containing function. The tags closest to the * node are returned first, so in the previous example, the param * tag on the containing function expression would be first. * - * Does not return tags for binding patterns, because JSDoc matches - * parameters by name and binding patterns do not have a name. + * For binding patterns, parameter tags are matched by position. */ function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray; + /** + * Gets the JSDoc type parameter tags for the node if present. + * + * @remarks Returns any JSDoc template tag whose names match the provided + * parameter, whether a template tag on a containing function + * expression, or a template tag on a variable declaration whose + * initializer is the containing function. The tags closest to the + * node are returned first, so in the previous example, the template + * tag on the containing function expression would be first. + */ + function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray; /** * Return true if the node has JSDoc parameter tags. * diff --git a/tests/cases/fourslash/signatureHelpTypeArguments2.ts b/tests/cases/fourslash/signatureHelpTypeArguments2.ts new file mode 100644 index 00000000000..6d39e6e8870 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpTypeArguments2.ts @@ -0,0 +1,37 @@ +/// + +/////** some documentation +//// * @template T some documentation 2 +//// * @template W +//// * @template U,V others +//// * @param a ok +//// * @param b not ok +//// */ +////function f(a: number, b: string, c: boolean): void { } +////f(a: number, b: string, c: boolean): void", + parameterName, + parameterSpan: parameterName, + docComment: "some documentation", + parameterDocComment, + tags: [{ name: "template", text: "T some documentation 2" }, + { name: "template", text: "W" }, + { name: "template", text: "U, V others" }, + { name: "param", text: "a ok" }, + { name: "param", text: "b not ok" }] + } +} + +verify.signatureHelp( + build("f0", "T", "some documentation 2"), + build("f1", "U", "others"), + build("f2", "V", "others"), + build("f3", "W", ""), +); From 0ac3a0a9375854011326ec6ae90e137fe7b49298 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 4 Sep 2018 11:31:30 -0700 Subject: [PATCH 142/163] Update user baselines (#26861) --- .../user/chrome-devtools-frontend.log | 102 +++++++++--------- tests/baselines/reference/user/jimp.log | 6 +- tests/baselines/reference/user/npm.log | 17 ++- tests/baselines/reference/user/uglify-js.log | 68 ++++++------ 4 files changed, 98 insertions(+), 95 deletions(-) diff --git a/tests/baselines/reference/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index 09fdbcc0b4b..1331e636ac0 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -11,6 +11,7 @@ Standard output: ../../../../built/local/lib.dom.d.ts(11899,13): error TS2300: Duplicate identifier 'Request'. ../../../../built/local/lib.dom.d.ts(16316,11): error TS2300: Duplicate identifier 'Window'. ../../../../built/local/lib.dom.d.ts(16447,13): error TS2300: Duplicate identifier 'Window'. +../../../../built/local/lib.dom.d.ts(17190,15): error TS2451: Cannot redeclare block-scoped variable 'name'. ../../../../built/local/lib.es5.d.ts(1346,11): error TS2300: Duplicate identifier 'ArrayLike'. ../../../../built/local/lib.es5.d.ts(1382,6): error TS2300: Duplicate identifier 'Record'. ../../../../node_modules/@types/node/index.d.ts(150,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type '{}', but here has type 'NodeModule'. @@ -603,26 +604,34 @@ node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/deta node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(285,31): error TS2694: Namespace 'DetailsRenderer' has no exported member 'DetailsJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(298,8): error TS2339: Property 'DetailsRenderer' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(303,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(303,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(307,17): error TS2339: Property 'DetailsJSON' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(311,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(311,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(316,17): error TS2339: Property 'ListDetailsJSON' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(320,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(327,17): error TS2300: Duplicate identifier 'NodeDetailsJSON'. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(320,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(327,17): error TS2339: Property 'NodeDetailsJSON' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(330,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(330,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(335,17): error TS2339: Property 'CardsDetailsJSON' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(339,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(339,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(344,17): error TS2339: Property 'TableHeaderJSON' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(348,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(355,17): error TS2300: Duplicate identifier 'NodeDetailsJSON'. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(348,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(355,17): error TS2339: Property 'NodeDetailsJSON' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(358,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(358,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(364,17): error TS2339: Property 'TableDetailsJSON' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(367,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(367,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(372,17): error TS2339: Property 'ThumbnailDetails' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(375,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(375,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(380,17): error TS2339: Property 'LinkDetailsJSON' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(383,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(383,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(388,17): error TS2339: Property 'FilmstripDetails' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/dom.js(63,67): error TS2339: Property 'querySelector' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/dom.js(76,43): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. @@ -3651,7 +3660,6 @@ node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(20,29): error TS2694: Namespace 'Common.Renderer' has no exported member 'Options'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(27,15): error TS2339: Property 'runtime' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(39,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(40,17): error TS2300: Duplicate identifier 'Options'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(40,17): error TS2339: Property 'Options' does not exist on type '{ (): void; prototype: { render(object: any, options: any): Promise; }; renderPromise(object: any, options?: any): Promise; }'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(63,15): error TS2339: Property 'runtime' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(81,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. @@ -3730,7 +3738,6 @@ node_modules/chrome-devtools-frontend/front_end/components/DOMBreakpointsSidebar node_modules/chrome-devtools-frontend/front_end/components/DOMBreakpointsSidebarPane.js(243,61): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/components/DOMBreakpointsSidebarPane.js(244,63): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/components/DOMBreakpointsSidebarPane.js(245,57): error TS2555: Expected at least 2 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/components/DOMBreakpointsSidebarPane.js(267,52): error TS2694: Namespace 'SDK.DOMDebuggerModel.DOMBreakpoint' has no exported member 'Type'. node_modules/chrome-devtools-frontend/front_end/components/DOMBreakpointsSidebarPane.js(276,72): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/components/DOMPresentationUtils.js(46,35): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/components/DOMPresentationUtils.js(51,35): error TS2339: Property 'createChild' does not exist on type 'Element'. @@ -4386,6 +4393,7 @@ node_modules/chrome-devtools-frontend/front_end/cookie_table/CookiesTable.js(461 node_modules/chrome-devtools-frontend/front_end/cookie_table/CookiesTable.js(470,51): error TS2339: Property 'asParsedURL' does not exist on type 'string'. node_modules/chrome-devtools-frontend/front_end/cookie_table/CookiesTable.js(489,49): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(7,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(7,7): error TS2300: Duplicate identifier 'id'. node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(50,68): error TS2339: Property 'get' does not exist on type 'Multimap'. node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(115,45): error TS2339: Property 'set' does not exist on type 'Multimap'. node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(135,32): error TS2694: Namespace 'Coverage' has no exported member 'RawLocation'. @@ -4635,6 +4643,7 @@ node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1170,23): node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1175,40): error TS2339: Property '__position' does not exist on type 'Element | { __index: number; __position: number; }'. Property '__position' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1200,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1200,6): error TS2300: Duplicate identifier 'id'. node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1214,19): error TS2339: Property 'ColumnDescriptor' does not exist on type 'typeof DataGrid'. node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1324,19): error TS2339: Property '_dataGridNode' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1334,14): error TS2551: Property 'dirty' does not exist on type 'DataGridNode'. Did you mean '_dirty'? @@ -5862,8 +5871,6 @@ node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeToolbar.js(3 node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeToolbar.js(302,71): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeToolbar.js(303,9): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeToolbar.js(305,44): error TS2555: Expected at least 2 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeToolbar.js(338,5): error TS2322: Type 'ToolbarItem' is not assignable to type '{ item(): any & any; } & { item(): any & any; }'. - Type 'ToolbarItem' is not assignable to type '{ item(): any & any; }'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeToolbar.js(338,5): error TS2322: Type 'ToolbarItem' is not assignable to type '{ item(): any & any; } & { item(): any & any; }'. Type 'ToolbarItem' is not assignable to type '{ item(): any & any; }'. Property 'item' is missing in type 'ToolbarItem'. @@ -5896,6 +5903,8 @@ node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(83,9 node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(84,7): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(84,34): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(84,63): error TS2555: Expected at least 2 arguments, but got 1. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(103,12): error TS2339: Property '_model' does not exist on type 'typeof DeviceModeView'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(104,12): error TS2339: Property '_model' does not exist on type 'typeof DeviceModeView'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(105,9): error TS2339: Property 'consume' does not exist on type 'Event'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(132,22): error TS2694: Namespace 'Common' has no exported member 'Event'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(143,22): error TS2694: Namespace 'Common' has no exported member 'Event'. @@ -5920,8 +5929,18 @@ node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(483, node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeView.js(500,22): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(18,22): error TS2339: Property 'singleton' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(33,24): error TS2694: Namespace 'Protocol' has no exported member 'Page'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(38,30): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(39,26): error TS2339: Property 'setNonEmulatedAvailableSize' does not exist on type 'typeof DeviceModeView'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(41,28): error TS2339: Property 'captureFullSizeScreenshot' does not exist on type 'typeof DeviceModeView'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(43,28): error TS2339: Property 'captureAreaScreenshot' does not exist on type 'typeof DeviceModeView'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(45,28): error TS2339: Property 'captureScreenshot' does not exist on type 'typeof DeviceModeView'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(50,22): error TS2694: Namespace 'Common' has no exported member 'Event'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(53,37): error TS2694: Namespace 'Protocol' has no exported member 'Page'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(63,66): error TS2339: Property 'isShowing' does not exist on type 'typeof DeviceModeView'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(70,32): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(71,28): error TS2339: Property 'show' does not exist on type 'typeof DeviceModeView'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(73,64): error TS2339: Property 'element' does not exist on type 'typeof DeviceModeView'. +node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(76,30): error TS2339: Property 'detach' does not exist on type 'typeof DeviceModeView'. node_modules/chrome-devtools-frontend/front_end/emulation/DeviceModeWrapper.js(120,45): error TS2694: Namespace 'Protocol' has no exported member 'Page'. node_modules/chrome-devtools-frontend/front_end/emulation/DevicesSettingsTab.js(15,31): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/emulation/DevicesSettingsTab.js(16,46): error TS2555: Expected at least 2 arguments, but got 1. @@ -6289,9 +6308,8 @@ node_modules/chrome-devtools-frontend/front_end/formatter/ScriptFormatter.js(127 node_modules/chrome-devtools-frontend/front_end/formatter/ScriptFormatter.js(134,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/formatter/ScriptFormatter.js(173,45): error TS2694: Namespace 'Formatter.FormatterWorkerPool' has no exported member 'FormatMapping'. node_modules/chrome-devtools-frontend/front_end/formatter/ScriptFormatter.js(215,28): error TS2339: Property 'upperBound' does not exist on type 'number[]'. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/AcornTokenizer.js(14,54): error TS2345: Argument of type '{ ecmaVersion: number; onComment: any[]; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. - Property 'ecmaVersion' is incompatible with index signature. - Type 'number' is not assignable to type 'boolean'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/AcornTokenizer.js(14,55): error TS2322: Type 'number' is not assignable to type 'boolean'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/AcornTokenizer.js(14,71): error TS2322: Type 'any[]' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/AcornTokenizer.js(15,63): error TS2339: Property 'computeLineEndings' does not exist on type 'string'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/AcornTokenizer.js(22,21): error TS2694: Namespace 'Acorn' has no exported member 'TokenOrComment'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/AcornTokenizer.js(33,21): error TS2694: Namespace 'Acorn' has no exported member 'TokenOrComment'. @@ -6319,18 +6337,12 @@ node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(46,69): error TS2339: Property 'length' does not exist on type 'void'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(58,26): error TS1110: Type expected. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(96,3): error TS2554: Expected 2-3 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(103,44): error TS2345: Argument of type '{ ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. - Property 'ecmaVersion' is incompatible with index signature. - Type 'number' is not assignable to type 'boolean'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(103,45): error TS2322: Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(138,3): error TS2554: Expected 2-3 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(146,35): error TS2345: Argument of type '{ ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. - Property 'ecmaVersion' is incompatible with index signature. - Type 'number' is not assignable to type 'boolean'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(146,36): error TS2322: Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(208,5): error TS2554: Expected 2-3 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(223,3): error TS2554: Expected 2-3 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(230,35): error TS2345: Argument of type '{ ranges: false; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. - Property 'ecmaVersion' is incompatible with index signature. - Type 'number' is not assignable to type 'boolean'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(230,51): error TS2322: Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(258,14): error TS2339: Property 'parent' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(258,29): error TS2339: Property 'parent' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/FormatterWorker.js(258,72): error TS2339: Property 'parent' does not exist on type 'Node'. @@ -6354,9 +6366,7 @@ node_modules/chrome-devtools-frontend/front_end/formatter_worker/HTMLFormatter.j node_modules/chrome-devtools-frontend/front_end/formatter_worker/HTMLFormatter.js(301,50): error TS2339: Property 'peekLast' does not exist on type 'Element[]'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/HTMLFormatter.js(302,49): error TS2339: Property 'peekLast' does not exist on type 'Element[]'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/HTMLFormatter.js(329,34): error TS2339: Property 'peekLast' does not exist on type 'Element[]'. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(54,42): error TS2345: Argument of type '{ ranges: false; ecmaVersion: number; preserveParens: true; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. - Property 'ecmaVersion' is incompatible with index signature. - Type 'number' is not assignable to type 'boolean'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(54,58): error TS2322: Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(60,21): error TS2694: Namespace 'Acorn' has no exported member 'TokenOrComment'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(88,15): error TS2339: Property 'parent' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(91,37): error TS2694: Namespace 'Acorn' has no exported member 'TokenOrComment'. @@ -6405,12 +6415,8 @@ node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptForma node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(304,62): error TS2339: Property 'alternate' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(306,23): error TS2339: Property 'consequent' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptFormatter.js(307,18): error TS2339: Property 'consequent' does not exist on type 'Node'. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(14,32): error TS2345: Argument of type '{ ranges: false; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. - Property 'ecmaVersion' is incompatible with index signature. - Type 'number' is not assignable to type 'boolean'. -node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(16,39): error TS2345: Argument of type '{ ranges: false; ecmaVersion: number; }' is not assignable to parameter of type '{ [x: string]: boolean; }'. - Property 'ecmaVersion' is incompatible with index signature. - Type 'number' is not assignable to type 'boolean'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(14,48): error TS2322: Type 'number' is not assignable to type 'boolean'. +node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(16,55): error TS2322: Type 'number' is not assignable to type 'boolean'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(19,53): error TS2339: Property 'computeLineEndings' does not exist on type 'string'. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(22,3): error TS2554: Expected 2-3 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/formatter_worker/JavaScriptOutline.js(34,60): error TS2339: Property 'key' does not exist on type 'Node'. @@ -6656,7 +6662,6 @@ node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(27 Index signature is missing in type '{}'. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(407,19): error TS2694: Namespace 'Adb' has no exported member 'Config'. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(445,48): error TS2694: Namespace 'InspectorFrontendHostAPI' has no exported member 'ContextMenuDescriptor'. -node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(471,12): error TS2538: Type 'string[]' cannot be used as an index type. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(521,8): error TS2339: Property 'InspectorFrontendHost' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(527,14): error TS2339: Property 'InspectorFrontendHost' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(557,10): error TS2339: Property 'InspectorFrontendAPI' does not exist on type 'Window'. @@ -6920,11 +6925,8 @@ node_modules/chrome-devtools-frontend/front_end/layer_viewer/Layers3DView.js(858 node_modules/chrome-devtools-frontend/front_end/layer_viewer/Layers3DView.js(861,81): error TS2339: Property 'image' does not exist on type 'WebGLTexture'. node_modules/chrome-devtools-frontend/front_end/layer_viewer/Layers3DView.js(928,26): error TS2694: Namespace 'SDK' has no exported member 'SnapshotWithRect'. node_modules/chrome-devtools-frontend/front_end/layer_viewer/Layers3DView.js(932,39): error TS2345: Argument of type 'any[][]' is not assignable to parameter of type 'ReadonlyArray<[any, any]>'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray[]): any[][]; (...items: (any[] | ConcatArray)[]): any[][]; }' is not assignable to type '{ (...items: ConcatArray<[any, any]>[]): [any, any][]; (...items: ([any, any] | ConcatArray<[any, any]>)[]): [any, any][]; }'. - Type 'any[][]' is not assignable to type '[any, any][]'. - Type 'any[]' is not assignable to type '[any, any]'. - Property '0' is missing in type 'any[]'. + Type 'any[]' is not assignable to type '[any, any]'. + Property '0' is missing in type 'any[]'. node_modules/chrome-devtools-frontend/front_end/layer_viewer/Layers3DView.js(1080,24): error TS2694: Namespace 'Protocol' has no exported member 'DOM'. node_modules/chrome-devtools-frontend/front_end/layer_viewer/Layers3DView.js(1098,15): error TS2304: Cannot find name 'CSSMatrix'. node_modules/chrome-devtools-frontend/front_end/layer_viewer/Layers3DView.js(1143,19): error TS2694: Namespace 'SDK' has no exported member 'SnapshotWithRect'. @@ -7154,7 +7156,8 @@ node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingMana node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingManager.js(224,32): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingManager.js(266,15): error TS2339: Property 'singleton' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(14,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(20,18): error TS2300: Duplicate identifier 'Conditions'. +node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(14,6): error TS2300: Duplicate identifier 'title'. +node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(14,6): error TS2300: Duplicate identifier 'title'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(22,30): error TS2694: Namespace 'MobileThrottling' has no exported member 'Conditions'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(25,16): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(30,30): error TS2694: Namespace 'MobileThrottling' has no exported member 'Conditions'. @@ -7166,6 +7169,7 @@ node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPres node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(48,10): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(49,16): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(56,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(56,6): error TS2300: Duplicate identifier 'title'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(62,30): error TS2694: Namespace 'MobileThrottling' has no exported member 'PlaceholderConditions'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(64,10): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(65,16): error TS2555: Expected at least 2 arguments, but got 1. @@ -7453,7 +7457,7 @@ node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(522,19): error TS2694: Namespace 'UI' has no exported member 'PopoverRequest'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(531,31): error TS2339: Property 'enclosingNodeOrSelfWithClass' does not exist on type 'EventTarget'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(601,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(616,31): error TS2300: Duplicate identifier 'Descriptor'. +node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(601,8): error TS2300: Duplicate identifier 'id'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(616,31): error TS2339: Property 'Descriptor' does not exist on type 'typeof NetworkLogViewColumns'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(640,50): error TS2694: Namespace 'Network.NetworkLogViewColumns' has no exported member 'Descriptor'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(645,12): error TS2555: Expected at least 2 arguments, but got 1. @@ -8018,6 +8022,7 @@ node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1169,70): node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1273,25): error TS2339: Property 'style' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1286,19): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1387,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1387,8): error TS2451: Cannot redeclare block-scoped variable 'name'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1393,19): error TS2339: Property 'Group' does not exist on type 'typeof FlameChart'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1397,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1410,19): error TS2339: Property 'GroupStyle' does not exist on type 'typeof FlameChart'. @@ -8881,11 +8886,8 @@ node_modules/chrome-devtools-frontend/front_end/profiler/ProfileView.js(78,46): node_modules/chrome-devtools-frontend/front_end/profiler/ProfileView.js(79,46): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/profiler/ProfileView.js(80,45): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/profiler/ProfileView.js(84,17): error TS2345: Argument of type '(string | Element)[][]' is not assignable to parameter of type 'ReadonlyArray<[any, any]>'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray<(string | Element)[]>[]): (string | Element)[][]; (...items: ((string | Element)[] | ConcatArray<(string | Element)[]>)[]): (string | Element)[][]; }' is not assignable to type '{ (...items: ConcatArray<[any, any]>[]): [any, any][]; (...items: ([any, any] | ConcatArray<[any, any]>)[]): [any, any][]; }'. - Type '(string | Element)[][]' is not assignable to type '[any, any][]'. - Type '(string | Element)[]' is not assignable to type '[any, any]'. - Property '0' is missing in type '(string | Element)[]'. + Type '(string | Element)[]' is not assignable to type '[any, any]'. + Property '0' is missing in type '(string | Element)[]'. node_modules/chrome-devtools-frontend/front_end/profiler/ProfileView.js(127,5): error TS2322: Type '(ToolbarButton | ToolbarComboBox)[]' is not assignable to type '({ item(): any & any; } & { item(): any & any; })[]'. node_modules/chrome-devtools-frontend/front_end/profiler/ProfileView.js(127,5): error TS2322: Type '(ToolbarButton | ToolbarComboBox)[]' is not assignable to type '({ item(): any & any; } & { item(): any & any; })[]'. Type 'ToolbarButton | ToolbarComboBox' is not assignable to type '{ item(): any & any; } & { item(): any & any; }'. @@ -9637,13 +9639,7 @@ node_modules/chrome-devtools-frontend/front_end/sdk/CookieParser.js(246,25): err node_modules/chrome-devtools-frontend/front_end/sdk/CookieParser.js(250,33): error TS2694: Namespace 'Protocol' has no exported member 'Network'. node_modules/chrome-devtools-frontend/front_end/sdk/CookieParser.js(325,53): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(11,26): error TS2339: Property 'domdebuggerAgent' does not exist on type 'Target'. -node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(69,50): error TS2694: Namespace 'SDK.DOMDebuggerModel.DOMBreakpoint' has no exported member 'Type'. -node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(78,50): error TS2694: Namespace 'SDK.DOMDebuggerModel.DOMBreakpoint' has no exported member 'Type'. -node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(98,50): error TS2694: Namespace 'SDK.DOMDebuggerModel.DOMBreakpoint' has no exported member 'Type'. -node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(154,59): error TS2694: Namespace 'SDK.DOMDebuggerModel.DOMBreakpoint' has no exported member 'Type'. -node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(190,60): error TS2694: Namespace 'SDK.DOMDebuggerModel.DOMBreakpoint' has no exported member 'Type'. node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(232,22): error TS2694: Namespace 'Common' has no exported member 'Event'. -node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(264,50): error TS2694: Namespace 'SDK.DOMDebuggerModel.DOMBreakpoint' has no exported member 'Type'. node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(275,24): error TS2694: Namespace 'Protocol' has no exported member 'DOMDebugger'. node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(387,7): error TS2322: Type 'Promise' is not assignable to type 'Promise'. node_modules/chrome-devtools-frontend/front_end/sdk/DOMDebuggerModel.js(578,9): error TS2555: Expected at least 2 arguments, but got 1. @@ -9923,7 +9919,6 @@ node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(154,5): er node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(166,22): error TS2694: Namespace 'Common' has no exported member 'Event'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(199,20): error TS2339: Property 'Message' does not exist on type 'typeof NetworkManager'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(214,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(220,20): error TS2300: Duplicate identifier 'Conditions'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(220,20): error TS2339: Property 'Conditions' does not exist on type 'typeof NetworkManager'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(222,32): error TS2694: Namespace 'SDK.NetworkManager' has no exported member 'Conditions'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(224,10): error TS2555: Expected at least 2 arguments, but got 1. @@ -10310,6 +10305,7 @@ node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(492,18): err node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(495,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(503,18): error TS2339: Property 'EvaluationOptions' does not exist on type 'typeof RuntimeModel'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(506,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(506,7): error TS2457: Type alias name cannot be 'object'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(511,18): error TS2339: Property 'EvaluationResult' does not exist on type 'typeof RuntimeModel'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(514,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(518,18): error TS2339: Property 'QueryObjectResult' does not exist on type 'typeof RuntimeModel'. @@ -11011,7 +11007,6 @@ node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js( node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(382,13): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(415,52): error TS2694: Namespace 'UI.KeyboardShortcut' has no exported member 'Descriptor'. node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(429,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(435,30): error TS2300: Duplicate identifier 'Item'. node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(435,30): error TS2339: Property 'Item' does not exist on type 'typeof CallStackSidebarPane'. node_modules/chrome-devtools-frontend/front_end/sources/DebuggerPausedMessage.js(11,33): error TS2339: Property 'createChild' does not exist on type 'DocumentFragment'. node_modules/chrome-devtools-frontend/front_end/sources/DebuggerPausedMessage.js(54,37): error TS2555: Expected at least 2 arguments, but got 1. @@ -11811,6 +11806,13 @@ node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1261,5): error TS2322: Type 'CodeMirrorPositionHandle' is not assignable to type '{ resolve(): { lineNumber: number; columnNumber: number; }; equal(positionHandle: any): boolean; }'. node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1261,5): error TS2322: Type 'CodeMirrorPositionHandle' is not assignable to type '{ resolve(): { lineNumber: number; columnNumber: number; }; equal(positionHandle: any): boolean; }'. Property '_codeMirror' does not exist on type '{ resolve(): { lineNumber: number; columnNumber: number; }; equal(positionHandle: any): boolean; }'. +node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1280,21): error TS2339: Property 'autocomplete' does not exist on type 'typeof commands'. +node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1283,21): error TS2339: Property 'undoLastSelection' does not exist on type 'typeof commands'. +node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1286,21): error TS2339: Property 'selectNextOccurrence' does not exist on type 'typeof commands'. +node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1289,21): error TS2339: Property 'moveCamelLeft' does not exist on type 'typeof commands'. +node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1290,21): error TS2339: Property 'selectCamelLeft' does not exist on type 'typeof commands'. +node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1293,21): error TS2339: Property 'moveCamelRight' does not exist on type 'typeof commands'. +node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1294,21): error TS2339: Property 'selectCamelRight' does not exist on type 'typeof commands'. node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1301,31): error TS2339: Property 'listSelections' does not exist on type 'CodeMirror'. node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1305,38): error TS2339: Property 'findMatchingBracket' does not exist on type 'CodeMirror'. node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1313,14): error TS2339: Property 'setSelections' does not exist on type 'CodeMirror'. @@ -11986,8 +11988,10 @@ node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(2 node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(320,41): error TS2339: Property 'peekLast' does not exist on type '{ timestamp: number; metrics: Map; }[]'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(330,24): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(394,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(394,6): error TS2300: Duplicate identifier 'title'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(402,29): error TS2339: Property 'ChartInfo' does not exist on type 'typeof PerformanceMonitor'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(406,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(406,6): error TS2451: Cannot redeclare block-scoped variable 'name'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(411,29): error TS2339: Property 'MetricInfo' does not exist on type 'typeof PerformanceMonitor'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(419,27): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(427,52): error TS2694: Namespace 'Timeline.PerformanceMonitor' has no exported member 'ChartInfo'. @@ -12654,6 +12658,7 @@ node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2059 node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2078,23): error TS2339: Property 'createTextChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2078,39): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2146,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2146,8): error TS2300: Duplicate identifier 'title'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2167,15): error TS2339: Property 'colSpan' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2186,10): error TS2339: Property 'createTextChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2191,5): error TS2322: Type 'string | number' is not assignable to type 'string'. @@ -13342,7 +13347,6 @@ node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(58,15): error T node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(70,18): error TS2694: Namespace 'UI' has no exported member 'AutocompleteConfig'. node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(79,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(91,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(101,15): error TS2300: Duplicate identifier 'Options'. node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(101,15): error TS2339: Property 'Options' does not exist on type '{ (): void; prototype: { widget(): Widget; fullRange(): TextRange; selection(): TextRange; setSelection(selection: TextRange): void; text(textRange?: TextRange): string; setText(text: string): void; ... 5 more ...; tokenAtTextPosition(lineNumber: number, columnNumber: number): { ...; }; }; Events: { ...; }; }'. node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(105,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/ui/TextPrompt.js(52,74): error TS2694: Namespace 'UI.SuggestBox' has no exported member 'Suggestions'. diff --git a/tests/baselines/reference/user/jimp.log b/tests/baselines/reference/user/jimp.log index 9757da0670e..2a11d85e4c5 100644 --- a/tests/baselines/reference/user/jimp.log +++ b/tests/baselines/reference/user/jimp.log @@ -1,8 +1,8 @@ Exit Code: 1 Standard output: -node_modules/jimp/jimp.d.ts(495,16): error TS7010: 'appendConstructorOption', which lacks return-type annotation, implicitly has an 'any' return type. -node_modules/jimp/jimp.d.ts(536,16): error TS7010: 'measureText', which lacks return-type annotation, implicitly has an 'any' return type. -node_modules/jimp/jimp.d.ts(537,16): error TS7010: 'measureTextHeight', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/jimp/jimp.d.ts(487,12): error TS7010: 'appendConstructorOption', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/jimp/jimp.d.ts(529,12): error TS7010: 'measureText', which lacks return-type annotation, implicitly has an 'any' return type. +node_modules/jimp/jimp.d.ts(530,12): error TS7010: 'measureTextHeight', which lacks return-type annotation, implicitly has an 'any' return type. diff --git a/tests/baselines/reference/user/npm.log b/tests/baselines/reference/user/npm.log index d85a724411a..d808deab385 100644 --- a/tests/baselines/reference/user/npm.log +++ b/tests/baselines/reference/user/npm.log @@ -343,8 +343,8 @@ node_modules/npm/lib/install/action/refresh-package-json.js(31,43): error TS2339 node_modules/npm/lib/install/action/remove.js(25,37): error TS2339: Property 'prefix' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/install/action/remove.js(25,51): error TS2339: Property 'prefix' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/install/actions.js(126,24): error TS2339: Property 'limit' does not exist on type 'typeof EventEmitter'. -node_modules/npm/lib/install/actions.js(168,16): error TS2345: Argument of type '"time"' is not assignable to parameter of type '"warning"'. -node_modules/npm/lib/install/actions.js(171,16): error TS2345: Argument of type '"timeEnd"' is not assignable to parameter of type '"warning"'. +node_modules/npm/lib/install/actions.js(168,16): error TS2345: Argument of type '"time"' is not assignable to parameter of type 'Signals'. +node_modules/npm/lib/install/actions.js(171,16): error TS2345: Argument of type '"timeEnd"' is not assignable to parameter of type 'Signals'. node_modules/npm/lib/install/and-add-parent-to-errors.js(9,10): error TS2339: Property 'parent' does not exist on type 'Error'. node_modules/npm/lib/install/audit.js(32,19): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/install/audit.js(89,17): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. @@ -432,8 +432,8 @@ node_modules/npm/lib/install.js(273,7): error TS2532: Object is possibly 'undefi node_modules/npm/lib/install.js(273,7): error TS2684: The 'this' context of type '((err: any, ...args: any[]) => any) | undefined' is not assignable to method's 'this' of type 'Function'. Type 'undefined' is not assignable to type 'Function'. node_modules/npm/lib/install.js(340,25): error TS2339: Property 'failing' does not exist on type 'Installer'. -node_modules/npm/lib/install.js(369,18): error TS2345: Argument of type '"time"' is not assignable to parameter of type '"warning"'. -node_modules/npm/lib/install.js(376,16): error TS2345: Argument of type '"timeEnd"' is not assignable to parameter of type '"warning"'. +node_modules/npm/lib/install.js(369,18): error TS2345: Argument of type '"time"' is not assignable to parameter of type 'Signals'. +node_modules/npm/lib/install.js(376,16): error TS2345: Argument of type '"timeEnd"' is not assignable to parameter of type 'Signals'. node_modules/npm/lib/install.js(519,40): error TS2339: Property 'globalPrefix' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/install.js(597,12): error TS2339: Property 'failing' does not exist on type 'Installer'. node_modules/npm/lib/install.js(614,12): error TS2339: Property 'failing' does not exist on type 'Installer'. @@ -498,7 +498,6 @@ node_modules/npm/lib/ls.js(260,16): error TS2339: Property 'problems' does not e Property 'problems' does not exist on type 'string'. node_modules/npm/lib/ls.js(262,54): error TS2339: Property 'problems' does not exist on type 'string | { name: any; version: any; extraneous: boolean; problems: any; invalid: boolean; from: any; resolved: any; peerInvalid: boolean; dependencies: {}; } | { required: any; missing: boolean; } | { ...; }'. Property 'problems' does not exist on type 'string'. -node_modules/npm/lib/ls.js(264,12): error TS2538: Type '{ name: any; version: any; extraneous: boolean; problems: any; invalid: boolean; from: any; resolved: any; peerInvalid: boolean; dependencies: {}; }' cannot be used as an index type. node_modules/npm/lib/ls.js(357,40): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/ls.js(362,26): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/ls.js(365,15): error TS2339: Property 'color' does not exist on type 'typeof EventEmitter'. @@ -783,7 +782,7 @@ node_modules/npm/lib/utils/error-handler.js(12,21): error TS2339: Property 'roll node_modules/npm/lib/utils/error-handler.js(23,36): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/utils/error-handler.js(29,16): error TS2339: Property 'version' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/utils/error-handler.js(33,12): error TS2345: Argument of type '"timing"' is not assignable to parameter of type 'Signals'. -node_modules/npm/lib/utils/error-handler.js(38,16): error TS2345: Argument of type '"timeEnd"' is not assignable to parameter of type '"warning"'. +node_modules/npm/lib/utils/error-handler.js(38,16): error TS2345: Argument of type '"timeEnd"' is not assignable to parameter of type 'Signals'. node_modules/npm/lib/utils/error-handler.js(40,11): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/utils/error-handler.js(40,32): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/utils/error-handler.js(43,39): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. @@ -1485,9 +1484,9 @@ node_modules/npm/test/tap/prepublish-only.js(6,21): error TS2307: Cannot find mo node_modules/npm/test/tap/prepublish.js(3,20): error TS2307: Cannot find module 'tap'. node_modules/npm/test/tap/process-logger.js(2,22): error TS2307: Cannot find module 'tap'. node_modules/npm/test/tap/process-logger.js(7,24): error TS2554: Expected 1-3 arguments, but got 4. -node_modules/npm/test/tap/process-logger.js(8,37): error TS2345: Argument of type '"log"' is not assignable to parameter of type '"warning"'. -node_modules/npm/test/tap/process-logger.js(9,37): error TS2345: Argument of type '"log"' is not assignable to parameter of type '"warning"'. -node_modules/npm/test/tap/process-logger.js(10,37): error TS2345: Argument of type '"log"' is not assignable to parameter of type '"warning"'. +node_modules/npm/test/tap/process-logger.js(8,37): error TS2345: Argument of type '"log"' is not assignable to parameter of type 'Signals'. +node_modules/npm/test/tap/process-logger.js(9,37): error TS2345: Argument of type '"log"' is not assignable to parameter of type 'Signals'. +node_modules/npm/test/tap/process-logger.js(10,37): error TS2345: Argument of type '"log"' is not assignable to parameter of type 'Signals'. node_modules/npm/test/tap/progress-config.js(3,20): error TS2307: Cannot find module 'tap'. node_modules/npm/test/tap/progress-config.js(12,29): error TS2307: Cannot find module 'require-inject'. node_modules/npm/test/tap/progress-config.js(18,9): error TS2339: Property 'stderr' does not exist on type 'typeof process'. diff --git a/tests/baselines/reference/user/uglify-js.log b/tests/baselines/reference/user/uglify-js.log index 0bc48d677a2..2ba94206d96 100644 --- a/tests/baselines/reference/user/uglify-js.log +++ b/tests/baselines/reference/user/uglify-js.log @@ -16,40 +16,40 @@ node_modules/uglify-js/lib/compress.js(1202,87): error TS2322: Type 'false' is n node_modules/uglify-js/lib/compress.js(1210,29): error TS2322: Type 'false' is not assignable to type 'never'. node_modules/uglify-js/lib/compress.js(1316,38): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/compress.js(1411,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1507,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1539,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1963,44): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(2149,19): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3205,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3218,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. -node_modules/uglify-js/lib/compress.js(3358,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3413,14): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3430,29): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3455,62): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3681,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3702,24): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3712,28): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3871,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary & { set: (key: any, val: any) => any; add: (key: any, val: any) => any; get: (key: any) => any; del: (key: any) => any; has: (key: any) => boolean; each: (f: any) => void; size: () => any; map: (f: any) => any[]; clone: () => Dictionary & any; toObject: () => any; }', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(3923,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. -node_modules/uglify-js/lib/compress.js(3979,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4088,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4387,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(4471,22): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4821,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4828,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ get: () => string; toString: () => string; indent: () => void; indentation: () => number; current_width: () => number; should_break: () => boolean; has_parens: () => boolean; newline: () => void; print: (str: any) => void; ... 24 more ...; parent: (n: any) => any; }'. -node_modules/uglify-js/lib/compress.js(4832,36): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(4837,41): error TS2339: Property 'get' does not exist on type 'string'. -node_modules/uglify-js/lib/compress.js(5324,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. -node_modules/uglify-js/lib/compress.js(5759,25): error TS2367: This condition will always return 'false' since the types 'boolean' and '"f"' have no overlap. -node_modules/uglify-js/lib/compress.js(5787,32): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5847,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5919,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5925,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(6318,43): error TS2454: Variable 'property' is used before being assigned. -node_modules/uglify-js/lib/compress.js(6333,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6336,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. -node_modules/uglify-js/lib/compress.js(6342,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6370,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1519,27): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1551,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1975,44): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(2161,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3214,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3227,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. +node_modules/uglify-js/lib/compress.js(3367,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3422,14): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3439,29): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3464,62): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3690,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3711,24): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3721,28): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3880,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary & { set: (key: any, val: any) => any; add: (key: any, val: any) => any; get: (key: any) => any; del: (key: any) => any; has: (key: any) => boolean; each: (f: any) => void; size: () => any; map: (f: any) => any[]; clone: () => Dictionary & any; toObject: () => any; }', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(3932,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. +node_modules/uglify-js/lib/compress.js(3988,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4097,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4396,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(4480,22): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4830,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4837,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ get: () => string; toString: () => string; indent: () => void; indentation: () => number; current_width: () => number; should_break: () => boolean; has_parens: () => boolean; newline: () => void; print: (str: any) => void; ... 24 more ...; parent: (n: any) => any; }'. +node_modules/uglify-js/lib/compress.js(4841,36): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(4846,41): error TS2339: Property 'get' does not exist on type 'string'. +node_modules/uglify-js/lib/compress.js(5333,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. +node_modules/uglify-js/lib/compress.js(5765,25): error TS2367: This condition will always return 'false' since the types 'boolean' and '"f"' have no overlap. +node_modules/uglify-js/lib/compress.js(5792,32): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5855,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5927,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5933,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(6337,43): error TS2454: Variable 'property' is used before being assigned. +node_modules/uglify-js/lib/compress.js(6352,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6355,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. +node_modules/uglify-js/lib/compress.js(6361,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6389,19): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/minify.js(170,75): error TS2339: Property 'compress' does not exist on type 'Compressor'. node_modules/uglify-js/lib/mozilla-ast.js(566,18): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/output.js(246,9): error TS2554: Expected 0 arguments, but got 2. From 64ac5a53f4b8216fe49810a413487d167f987427 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 4 Sep 2018 14:47:18 -0700 Subject: [PATCH 143/163] Fixes for type parameter name resolution in JS (#26830) * check for expando initializers in resolveEntityName when resolving type parameters in a prototype property assignment declaration. For example, this already works: ```js /** @template T */ function f(x) { this.x = x } /** @returns {T} */ f.protototype.m = function () { return this.x } ``` This now works too: ```js /** @template T */ var f = function (x) { this.x = x } /** @returns {T} */ f.prototype.m = function () { return this.x } ``` Fixes #26826 * Lookup type parameters on prototype-assignment methods In the same way that they're looked up on prototype-property methods. That is, this previously worked: ```js /** @template T */ function f() { } /** @param {T} p */ f.prototype.m = function () { } ``` And this now works too: ```js /** @template T */ function f() { } f.prototype = { /** @param {T} p */ m() { } } ``` Note that the baselines still have errors; I'll file a followup bug for them. * Look up types on property assignments too --- src/compiler/checker.ts | 24 ++- .../reference/jsdocTemplateTag4.symbols | 113 +++++++++++++ .../reference/jsdocTemplateTag4.types | 141 +++++++++++++++++ .../reference/jsdocTemplateTag5.errors.txt | 77 +++++++++ .../reference/jsdocTemplateTag5.symbols | 114 ++++++++++++++ .../reference/jsdocTemplateTag5.types | 149 ++++++++++++++++++ .../conformance/jsdoc/jsdocTemplateTag4.ts | 63 ++++++++ .../conformance/jsdoc/jsdocTemplateTag5.ts | 70 ++++++++ 8 files changed, 749 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/jsdocTemplateTag4.symbols create mode 100644 tests/baselines/reference/jsdocTemplateTag4.types create mode 100644 tests/baselines/reference/jsdocTemplateTag5.errors.txt create mode 100644 tests/baselines/reference/jsdocTemplateTag5.symbols create mode 100644 tests/baselines/reference/jsdocTemplateTag5.types create mode 100644 tests/cases/conformance/jsdoc/jsdocTemplateTag4.ts create mode 100644 tests/cases/conformance/jsdoc/jsdocTemplateTag5.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da1af15dfa4..57de68ab02b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2140,7 +2140,7 @@ namespace ts { } } - function getJSSpecialAssignmentLocation(node: TypeReferenceNode): Declaration | undefined { + function getJSSpecialAssignmentLocation(node: TypeReferenceNode): Node | undefined { const typeAlias = findAncestor(node, node => !(isJSDocNode(node) || node.flags & NodeFlags.JSDoc) ? "quit" : isJSDocTypeAlias(node)); if (typeAlias) { return; @@ -2149,8 +2149,20 @@ namespace ts { if (isExpressionStatement(host) && isBinaryExpression(host.expression) && getSpecialPropertyAssignmentKind(host.expression) === SpecialPropertyAssignmentKind.PrototypeProperty) { + // X.prototype.m = /** @param {K} p */ function () { } <-- look for K on X's declaration const symbol = getSymbolOfNode(host.expression.left); - return symbol && symbol.parent!.valueDeclaration; + if (symbol) { + return getDeclarationOfJSPrototypeContainer(symbol); + } + } + if ((isObjectLiteralMethod(host) || isPropertyAssignment(host)) && + isBinaryExpression(host.parent.parent) && + getSpecialPropertyAssignmentKind(host.parent.parent) === SpecialPropertyAssignmentKind.Prototype) { + // X.prototype = { /** @param {K} p */m() { } } <-- look for K on X's declaration + const symbol = getSymbolOfNode(host.parent.parent.left); + if (symbol) { + return getDeclarationOfJSPrototypeContainer(symbol); + } } const sig = getHostSignatureFromJSDocHost(host); if (sig) { @@ -2159,6 +2171,14 @@ namespace ts { } } + function getDeclarationOfJSPrototypeContainer(symbol: Symbol) { + const decl = symbol.parent!.valueDeclaration; + const initializer = isAssignmentDeclaration(decl) ? getAssignedJavascriptInitializer(decl) : + hasOnlyExpressionInitializer(decl) ? getDeclaredJavascriptInitializer(decl) : + undefined; + return initializer || decl; + } + function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression): Symbol | undefined { return resolveExternalModuleNameWorker(location, moduleReferenceExpression, Diagnostics.Cannot_find_module_0); } diff --git a/tests/baselines/reference/jsdocTemplateTag4.symbols b/tests/baselines/reference/jsdocTemplateTag4.symbols new file mode 100644 index 00000000000..02ce7221fc2 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag4.symbols @@ -0,0 +1,113 @@ +=== tests/cases/conformance/jsdoc/a.js === +/** + * Should work for function declarations + * @constructor + * @template {string} K + * @template V + */ +function Multimap() { +>Multimap : Symbol(Multimap, Decl(a.js, 0, 0)) + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map : Symbol(Multimap._map, Decl(a.js, 6, 21)) +>this : Symbol(Multimap, Decl(a.js, 0, 0)) +>_map : Symbol(Multimap._map, Decl(a.js, 6, 21)) + +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Multimap.prototype.get = function (key) { +>Multimap.prototype : Symbol(Multimap.get, Decl(a.js, 9, 2)) +>Multimap : Symbol(Multimap, Decl(a.js, 0, 0)) +>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>get : Symbol(Multimap.get, Decl(a.js, 9, 2)) +>key : Symbol(key, Decl(a.js, 15, 35)) + + return this._map[key + '']; +>this._map : Symbol(Multimap._map, Decl(a.js, 6, 21)) +>this : Symbol(Multimap, Decl(a.js, 0, 0)) +>_map : Symbol(Multimap._map, Decl(a.js, 6, 21)) +>key : Symbol(key, Decl(a.js, 15, 35)) +} + +/** + * Should work for initialisers too + * @constructor + * @template {string} K + * @template V + */ +var Multimap2 = function() { +>Multimap2 : Symbol(Multimap2, Decl(a.js, 25, 3)) + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map : Symbol(Multimap2._map, Decl(a.js, 25, 28)) +>this : Symbol(Multimap2, Decl(a.js, 25, 15)) +>_map : Symbol(Multimap2._map, Decl(a.js, 25, 28)) + +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Multimap2.prototype.get = function (key) { +>Multimap2.prototype : Symbol(Multimap2.get, Decl(a.js, 28, 2)) +>Multimap2 : Symbol(Multimap2, Decl(a.js, 25, 3)) +>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>get : Symbol(Multimap2.get, Decl(a.js, 28, 2)) +>key : Symbol(key, Decl(a.js, 34, 36)) + + return this._map[key + '']; +>this._map : Symbol(Multimap2._map, Decl(a.js, 25, 28)) +>this : Symbol(Multimap2, Decl(a.js, 25, 15)) +>_map : Symbol(Multimap2._map, Decl(a.js, 25, 28)) +>key : Symbol(key, Decl(a.js, 34, 36)) +} + +var Ns = {}; +>Ns : Symbol(Ns, Decl(a.js, 38, 3), Decl(a.js, 38, 12)) + +/** + * Should work for expando-namespaced initialisers too + * @constructor + * @template {string} K + * @template V + */ +Ns.Multimap3 = function() { +>Ns.Multimap3 : Symbol(Ns.Multimap3, Decl(a.js, 38, 12)) +>Ns : Symbol(Ns, Decl(a.js, 38, 3), Decl(a.js, 38, 12)) +>Multimap3 : Symbol(Ns.Multimap3, Decl(a.js, 38, 12)) + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map : Symbol(Multimap3._map, Decl(a.js, 45, 27)) +>this : Symbol(Multimap3, Decl(a.js, 45, 14)) +>_map : Symbol(Multimap3._map, Decl(a.js, 45, 27)) + +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Ns.Multimap3.prototype.get = function (key) { +>Ns.Multimap3.prototype : Symbol(Ns.Multimap3.get, Decl(a.js, 48, 2)) +>Ns.Multimap3 : Symbol(Ns.Multimap3, Decl(a.js, 38, 12)) +>Ns : Symbol(Ns, Decl(a.js, 38, 3), Decl(a.js, 38, 12)) +>Multimap3 : Symbol(Ns.Multimap3, Decl(a.js, 38, 12)) +>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>get : Symbol(Ns.Multimap3.get, Decl(a.js, 48, 2)) +>key : Symbol(key, Decl(a.js, 54, 39)) + + return this._map[key + '']; +>this._map : Symbol(Multimap3._map, Decl(a.js, 45, 27)) +>this : Symbol(Multimap3, Decl(a.js, 45, 14)) +>_map : Symbol(Multimap3._map, Decl(a.js, 45, 27)) +>key : Symbol(key, Decl(a.js, 54, 39)) +} + diff --git a/tests/baselines/reference/jsdocTemplateTag4.types b/tests/baselines/reference/jsdocTemplateTag4.types new file mode 100644 index 00000000000..6df18d4b98a --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag4.types @@ -0,0 +1,141 @@ +=== tests/cases/conformance/jsdoc/a.js === +/** + * Should work for function declarations + * @constructor + * @template {string} K + * @template V + */ +function Multimap() { +>Multimap : typeof Multimap + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map = {} : {} +>this._map : { [x: string]: V; } +>this : Multimap +>_map : { [x: string]: V; } +>{} : {} + +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Multimap.prototype.get = function (key) { +>Multimap.prototype.get = function (key) { return this._map[key + ''];} : (key: K) => V +>Multimap.prototype.get : any +>Multimap.prototype : any +>Multimap : typeof Multimap +>prototype : any +>get : any +>function (key) { return this._map[key + ''];} : (key: K) => V +>key : K + + return this._map[key + '']; +>this._map[key + ''] : V +>this._map : { [x: string]: V; } +>this : Multimap +>_map : { [x: string]: V; } +>key + '' : string +>key : K +>'' : "" +} + +/** + * Should work for initialisers too + * @constructor + * @template {string} K + * @template V + */ +var Multimap2 = function() { +>Multimap2 : typeof Multimap2 +>function() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {};} : typeof Multimap2 + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map = {} : {} +>this._map : { [x: string]: V; } +>this : Multimap2 +>_map : { [x: string]: V; } +>{} : {} + +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Multimap2.prototype.get = function (key) { +>Multimap2.prototype.get = function (key) { return this._map[key + ''];} : (key: K) => V +>Multimap2.prototype.get : any +>Multimap2.prototype : any +>Multimap2 : typeof Multimap2 +>prototype : any +>get : any +>function (key) { return this._map[key + ''];} : (key: K) => V +>key : K + + return this._map[key + '']; +>this._map[key + ''] : V +>this._map : { [x: string]: V; } +>this : Multimap2 +>_map : { [x: string]: V; } +>key + '' : string +>key : K +>'' : "" +} + +var Ns = {}; +>Ns : typeof Ns +>{} : {} + +/** + * Should work for expando-namespaced initialisers too + * @constructor + * @template {string} K + * @template V + */ +Ns.Multimap3 = function() { +>Ns.Multimap3 = function() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {};} : typeof Multimap3 +>Ns.Multimap3 : typeof Multimap3 +>Ns : typeof Ns +>Multimap3 : typeof Multimap3 +>function() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {};} : typeof Multimap3 + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map = {} : {} +>this._map : { [x: string]: V; } +>this : Multimap3 +>_map : { [x: string]: V; } +>{} : {} + +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Ns.Multimap3.prototype.get = function (key) { +>Ns.Multimap3.prototype.get = function (key) { return this._map[key + ''];} : (key: K) => V +>Ns.Multimap3.prototype.get : any +>Ns.Multimap3.prototype : any +>Ns.Multimap3 : typeof Multimap3 +>Ns : typeof Ns +>Multimap3 : typeof Multimap3 +>prototype : any +>get : any +>function (key) { return this._map[key + ''];} : (key: K) => V +>key : K + + return this._map[key + '']; +>this._map[key + ''] : V +>this._map : { [x: string]: V; } +>this : Multimap3 +>_map : { [x: string]: V; } +>key + '' : string +>key : K +>'' : "" +} + diff --git a/tests/baselines/reference/jsdocTemplateTag5.errors.txt b/tests/baselines/reference/jsdocTemplateTag5.errors.txt new file mode 100644 index 00000000000..e24cd0926b6 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag5.errors.txt @@ -0,0 +1,77 @@ +tests/cases/conformance/jsdoc/a.js(18,21): error TS2339: Property '_map' does not exist on type '{ get(key: K): V; }'. +tests/cases/conformance/jsdoc/a.js(39,21): error TS2339: Property '_map' does not exist on type '{ get: (key: K) => V; }'. +tests/cases/conformance/jsdoc/a.js(61,21): error TS2339: Property '_map' does not exist on type '{ get(key: K): V; }'. + + +==== tests/cases/conformance/jsdoc/a.js (3 errors) ==== + /** + * Should work for function declarations + * @constructor + * @template {string} K + * @template V + */ + function Multimap() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; + }; + + Multimap.prototype = { + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get(key) { + return this._map[key + '']; + ~~~~ +!!! error TS2339: Property '_map' does not exist on type '{ get(key: K): V; }'. + } + } + + /** + * Should work for initialisers too + * @constructor + * @template {string} K + * @template V + */ + var Multimap2 = function() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; + }; + + Multimap2.prototype = { + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get: function(key) { + return this._map[key + '']; + ~~~~ +!!! error TS2339: Property '_map' does not exist on type '{ get: (key: K) => V; }'. + } + } + + var Ns = {}; + /** + * Should work for expando-namespaced initialisers too + * @constructor + * @template {string} K + * @template V + */ + Ns.Multimap3 = function() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; + }; + + Ns.Multimap3.prototype = { + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get(key) { + return this._map[key + '']; + ~~~~ +!!! error TS2339: Property '_map' does not exist on type '{ get(key: K): V; }'. + } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocTemplateTag5.symbols b/tests/baselines/reference/jsdocTemplateTag5.symbols new file mode 100644 index 00000000000..249e92ab257 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag5.symbols @@ -0,0 +1,114 @@ +=== tests/cases/conformance/jsdoc/a.js === +/** + * Should work for function declarations + * @constructor + * @template {string} K + * @template V + */ +function Multimap() { +>Multimap : Symbol(Multimap, Decl(a.js, 0, 0), Decl(a.js, 9, 2)) + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map : Symbol(Multimap._map, Decl(a.js, 6, 21)) +>_map : Symbol(Multimap._map, Decl(a.js, 6, 21)) + +}; + +Multimap.prototype = { +>Multimap.prototype : Symbol(Multimap.prototype, Decl(a.js, 9, 2)) +>Multimap : Symbol(Multimap, Decl(a.js, 0, 0), Decl(a.js, 9, 2)) +>prototype : Symbol(Multimap.prototype, Decl(a.js, 9, 2)) + + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get(key) { +>get : Symbol(get, Decl(a.js, 11, 22)) +>key : Symbol(key, Decl(a.js, 16, 8)) + + return this._map[key + '']; +>this : Symbol(__object, Decl(a.js, 11, 20)) +>key : Symbol(key, Decl(a.js, 16, 8)) + } +} + +/** + * Should work for initialisers too + * @constructor + * @template {string} K + * @template V + */ +var Multimap2 = function() { +>Multimap2 : Symbol(Multimap2, Decl(a.js, 27, 3), Decl(a.js, 30, 2)) + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map : Symbol(Multimap2._map, Decl(a.js, 27, 28)) +>_map : Symbol(Multimap2._map, Decl(a.js, 27, 28)) + +}; + +Multimap2.prototype = { +>Multimap2.prototype : Symbol(Multimap2.prototype, Decl(a.js, 30, 2)) +>Multimap2 : Symbol(Multimap2, Decl(a.js, 27, 3), Decl(a.js, 30, 2)) +>prototype : Symbol(Multimap2.prototype, Decl(a.js, 30, 2)) + + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get: function(key) { +>get : Symbol(get, Decl(a.js, 32, 23)) +>key : Symbol(key, Decl(a.js, 37, 18)) + + return this._map[key + '']; +>this : Symbol(__object, Decl(a.js, 32, 21)) +>key : Symbol(key, Decl(a.js, 37, 18)) + } +} + +var Ns = {}; +>Ns : Symbol(Ns, Decl(a.js, 42, 3), Decl(a.js, 42, 12), Decl(a.js, 52, 2)) + +/** + * Should work for expando-namespaced initialisers too + * @constructor + * @template {string} K + * @template V + */ +Ns.Multimap3 = function() { +>Ns.Multimap3 : Symbol(Ns.Multimap3, Decl(a.js, 42, 12), Decl(a.js, 54, 3)) +>Ns : Symbol(Ns, Decl(a.js, 42, 3), Decl(a.js, 42, 12), Decl(a.js, 52, 2)) +>Multimap3 : Symbol(Ns.Multimap3, Decl(a.js, 42, 12), Decl(a.js, 54, 3)) + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map : Symbol(Multimap3._map, Decl(a.js, 49, 27)) +>_map : Symbol(Multimap3._map, Decl(a.js, 49, 27)) + +}; + +Ns.Multimap3.prototype = { +>Ns.Multimap3.prototype : Symbol(Ns.Multimap3.prototype, Decl(a.js, 52, 2)) +>Ns.Multimap3 : Symbol(Ns.Multimap3, Decl(a.js, 42, 12), Decl(a.js, 54, 3)) +>Ns : Symbol(Ns, Decl(a.js, 42, 3), Decl(a.js, 42, 12), Decl(a.js, 52, 2)) +>Multimap3 : Symbol(Ns.Multimap3, Decl(a.js, 42, 12), Decl(a.js, 54, 3)) +>prototype : Symbol(Ns.Multimap3.prototype, Decl(a.js, 52, 2)) + + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get(key) { +>get : Symbol(get, Decl(a.js, 54, 26)) +>key : Symbol(key, Decl(a.js, 59, 8)) + + return this._map[key + '']; +>this : Symbol(__object, Decl(a.js, 54, 24)) +>key : Symbol(key, Decl(a.js, 59, 8)) + } +} + + diff --git a/tests/baselines/reference/jsdocTemplateTag5.types b/tests/baselines/reference/jsdocTemplateTag5.types new file mode 100644 index 00000000000..c5b8752d2b6 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag5.types @@ -0,0 +1,149 @@ +=== tests/cases/conformance/jsdoc/a.js === +/** + * Should work for function declarations + * @constructor + * @template {string} K + * @template V + */ +function Multimap() { +>Multimap : typeof Multimap + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map = {} : {} +>this._map : { [x: string]: V; } +>this : Multimap & { get(key: K): V; } +>_map : { [x: string]: V; } +>{} : {} + +}; + +Multimap.prototype = { +>Multimap.prototype = { /** * @param {K} key the key ok * @returns {V} the value ok */ get(key) { return this._map[key + '']; }} : { get(key: K): V; } +>Multimap.prototype : { get(key: K): V; } +>Multimap : typeof Multimap +>prototype : { get(key: K): V; } +>{ /** * @param {K} key the key ok * @returns {V} the value ok */ get(key) { return this._map[key + '']; }} : { get(key: K): V; } + + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get(key) { +>get : (key: K) => V +>key : K + + return this._map[key + '']; +>this._map[key + ''] : any +>this._map : any +>this : { get(key: K): V; } +>_map : any +>key + '' : string +>key : K +>'' : "" + } +} + +/** + * Should work for initialisers too + * @constructor + * @template {string} K + * @template V + */ +var Multimap2 = function() { +>Multimap2 : typeof Multimap2 +>function() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {};} : typeof Multimap2 + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map = {} : {} +>this._map : { [x: string]: V; } +>this : Multimap2 & { get: (key: K) => V; } +>_map : { [x: string]: V; } +>{} : {} + +}; + +Multimap2.prototype = { +>Multimap2.prototype = { /** * @param {K} key the key ok * @returns {V} the value ok */ get: function(key) { return this._map[key + '']; }} : { get: (key: K) => V; } +>Multimap2.prototype : { get: (key: K) => V; } +>Multimap2 : typeof Multimap2 +>prototype : { get: (key: K) => V; } +>{ /** * @param {K} key the key ok * @returns {V} the value ok */ get: function(key) { return this._map[key + '']; }} : { get: (key: K) => V; } + + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get: function(key) { +>get : (key: K) => V +>function(key) { return this._map[key + '']; } : (key: K) => V +>key : K + + return this._map[key + '']; +>this._map[key + ''] : any +>this._map : any +>this : { get: (key: K) => V; } +>_map : any +>key + '' : string +>key : K +>'' : "" + } +} + +var Ns = {}; +>Ns : typeof Ns +>{} : {} + +/** + * Should work for expando-namespaced initialisers too + * @constructor + * @template {string} K + * @template V + */ +Ns.Multimap3 = function() { +>Ns.Multimap3 = function() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {};} : typeof Multimap3 +>Ns.Multimap3 : typeof Multimap3 +>Ns : typeof Ns +>Multimap3 : typeof Multimap3 +>function() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {};} : typeof Multimap3 + + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +>this._map = {} : {} +>this._map : { [x: string]: V; } +>this : Multimap3 & { get(key: K): V; } +>_map : { [x: string]: V; } +>{} : {} + +}; + +Ns.Multimap3.prototype = { +>Ns.Multimap3.prototype = { /** * @param {K} key the key ok * @returns {V} the value ok */ get(key) { return this._map[key + '']; }} : { get(key: K): V; } +>Ns.Multimap3.prototype : { get(key: K): V; } +>Ns.Multimap3 : typeof Multimap3 +>Ns : typeof Ns +>Multimap3 : typeof Multimap3 +>prototype : { get(key: K): V; } +>{ /** * @param {K} key the key ok * @returns {V} the value ok */ get(key) { return this._map[key + '']; }} : { get(key: K): V; } + + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get(key) { +>get : (key: K) => V +>key : K + + return this._map[key + '']; +>this._map[key + ''] : any +>this._map : any +>this : { get(key: K): V; } +>_map : any +>key + '' : string +>key : K +>'' : "" + } +} + + diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateTag4.ts b/tests/cases/conformance/jsdoc/jsdocTemplateTag4.ts new file mode 100644 index 00000000000..adbf6bfbaca --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTemplateTag4.ts @@ -0,0 +1,63 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @strict: true +// @Filename: a.js + +/** + * Should work for function declarations + * @constructor + * @template {string} K + * @template V + */ +function Multimap() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Multimap.prototype.get = function (key) { + return this._map[key + '']; +} + +/** + * Should work for initialisers too + * @constructor + * @template {string} K + * @template V + */ +var Multimap2 = function() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Multimap2.prototype.get = function (key) { + return this._map[key + '']; +} + +var Ns = {}; +/** + * Should work for expando-namespaced initialisers too + * @constructor + * @template {string} K + * @template V + */ +Ns.Multimap3 = function() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +}; + +/** + * @param {K} key the key ok + * @returns {V} the value ok + */ +Ns.Multimap3.prototype.get = function (key) { + return this._map[key + '']; +} diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateTag5.ts b/tests/cases/conformance/jsdoc/jsdocTemplateTag5.ts new file mode 100644 index 00000000000..0bfb6b7ca37 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTemplateTag5.ts @@ -0,0 +1,70 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @strict: true +// @Filename: a.js + +/** + * Should work for function declarations + * @constructor + * @template {string} K + * @template V + */ +function Multimap() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +}; + +Multimap.prototype = { + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get(key) { + return this._map[key + '']; + } +} + +/** + * Should work for initialisers too + * @constructor + * @template {string} K + * @template V + */ +var Multimap2 = function() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +}; + +Multimap2.prototype = { + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get: function(key) { + return this._map[key + '']; + } +} + +var Ns = {}; +/** + * Should work for expando-namespaced initialisers too + * @constructor + * @template {string} K + * @template V + */ +Ns.Multimap3 = function() { + /** @type {Object} TODO: Remove the prototype from the fresh object */ + this._map = {}; +}; + +Ns.Multimap3.prototype = { + /** + * @param {K} key the key ok + * @returns {V} the value ok + */ + get(key) { + return this._map[key + '']; + } +} + From 262ea5b06ee22e4e79d11f66f84c09775808a0f2 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 4 Sep 2018 16:41:08 -0600 Subject: [PATCH 144/163] Skip asterisks after newline when parsing JSDoc types (#26528) * Skip asterisks after newline when parsing JSDoc types * Single boolean expression * Test for parsing and printing multiline function signatures with * --- src/compiler/parser.ts | 2 + src/compiler/scanner.ts | 15 ++ src/compiler/utilities.ts | 13 +- .../reference/typedefTagWrapping.errors.txt | 136 ++++++++++++++ .../reference/typedefTagWrapping.symbols | 166 ++++++++++++++++- .../reference/typedefTagWrapping.types | 170 +++++++++++++++++- .../conformance/jsdoc/typedefTagWrapping.ts | 122 ++++++++++++- .../fourslash/jsDocFunctionSignatures12.ts | 29 ++- 8 files changed, 641 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/typedefTagWrapping.errors.txt diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b40648033de..d1102eb78ac 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2377,8 +2377,10 @@ namespace ts { } function parseJSDocType(): TypeNode { + scanner.setInJSDocType(true); const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken); let type = parseTypeOrTypePredicate(); + scanner.setInJSDocType(false); if (dotdotdot) { const variadic = createNode(SyntaxKind.JSDocVariadicType, dotdotdot.pos) as JSDocVariadicType; variadic.type = type; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 61ce8330bff..809ccadbc6e 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -42,6 +42,8 @@ namespace ts { setScriptTarget(scriptTarget: ScriptTarget): void; setLanguageVariant(variant: LanguageVariant): void; setTextPos(textPos: number): void; + /* @internal */ + setInJSDocType(inType: boolean): void; // Invokes the provided callback then unconditionally restores the scanner to the state it // was in immediately prior to invoking the callback. The result of invoking the callback // is returned from this function. @@ -824,6 +826,8 @@ namespace ts { let tokenValue!: string; let tokenFlags: TokenFlags; + let inJSDocType = 0; + setText(text, start, length); return { @@ -854,6 +858,7 @@ namespace ts { setLanguageVariant, setOnError, setTextPos, + setInJSDocType, tryScan, lookAhead, scanRange, @@ -1350,6 +1355,7 @@ namespace ts { function scan(): SyntaxKind { startPos = pos; tokenFlags = 0; + let asteriskSeen = false; while (true) { tokenPos = pos; if (pos >= end) { @@ -1447,6 +1453,11 @@ namespace ts { return pos += 2, token = SyntaxKind.AsteriskAsteriskToken; } pos++; + if (inJSDocType && !asteriskSeen && (tokenFlags & TokenFlags.PrecedingLineBreak)) { + // decoration at the start of a JSDoc comment line + asteriskSeen = true; + continue; + } return token = SyntaxKind.AsteriskToken; case CharacterCodes.plus: if (text.charCodeAt(pos + 1) === CharacterCodes.plus) { @@ -2078,5 +2089,9 @@ namespace ts { tokenValue = undefined!; tokenFlags = 0; } + + function setInJSDocType(inType: boolean) { + inJSDocType += inType ? 1 : -1; + } } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7c5f2108c1e..3d5893d0a03 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -490,12 +490,23 @@ namespace ts { return getTextOfNodeFromSourceText(sourceFile.text, node, includeTrivia); } + function isJSDocTypeExpressionOrChild(node: Node): boolean { + return node.kind === SyntaxKind.JSDocTypeExpression || (node.parent && isJSDocTypeExpressionOrChild(node.parent)); + } + export function getTextOfNodeFromSourceText(sourceText: string, node: Node, includeTrivia = false): string { if (nodeIsMissing(node)) { return ""; } - return sourceText.substring(includeTrivia ? node.pos : skipTrivia(sourceText, node.pos), node.end); + let text = sourceText.substring(includeTrivia ? node.pos : skipTrivia(sourceText, node.pos), node.end); + + if (isJSDocTypeExpressionOrChild(node)) { + // strip space + asterisk at line start + text = text.replace(/(^|\r?\n|\r)\s*\*\s*/g, "$1"); + } + + return text; } export function getTextOfNode(node: Node, includeTrivia = false): string { diff --git a/tests/baselines/reference/typedefTagWrapping.errors.txt b/tests/baselines/reference/typedefTagWrapping.errors.txt new file mode 100644 index 00000000000..f480c1391e8 --- /dev/null +++ b/tests/baselines/reference/typedefTagWrapping.errors.txt @@ -0,0 +1,136 @@ +tests/cases/conformance/jsdoc/mod7.js(5,7): error TS1110: Type expected. +tests/cases/conformance/jsdoc/mod7.js(8,4): error TS1110: Type expected. + + +==== tests/cases/conformance/jsdoc/mod1.js (0 errors) ==== + /** + * @typedef {function(string): boolean} + * Type1 + */ + + /** + * Tries to use a type whose name is on a different + * line than the typedef tag. + * @param {Type1} func The function to call. + * @param {string} arg The argument to call it with. + * @returns {boolean} The return. + */ + function callIt(func, arg) { + return func(arg); + } + +==== tests/cases/conformance/jsdoc/mod2.js (0 errors) ==== + /** + * @typedef {{ + * num: number, + * str: string, + * boo: boolean + * }} Type2 + */ + + /** + * Makes use of a type with a multiline type expression. + * @param {Type2} obj The object. + * @returns {string|number} The return. + */ + function check(obj) { + return obj.boo ? obj.num : obj.str; + } + +==== tests/cases/conformance/jsdoc/mod3.js (0 errors) ==== + /** + * A function whose signature is very long. + * + * @typedef {function(boolean, string, number): + * (string|number)} StringOrNumber1 + */ + + /** + * Makes use of a function type with a long signature. + * @param {StringOrNumber1} func The function. + * @param {boolean} bool The condition. + * @param {string} str The string. + * @param {number} num The number. + * @returns {string|number} The return. + */ + function use1(func, bool, str, num) { + return func(bool, str, num) + } + +==== tests/cases/conformance/jsdoc/mod4.js (0 errors) ==== + /** + * A function whose signature is very long. + * + * @typedef {function(boolean, string, + * number): + * (string|number)} StringOrNumber2 + */ + + /** + * Makes use of a function type with a long signature. + * @param {StringOrNumber2} func The function. + * @param {boolean} bool The condition. + * @param {string} str The string. + * @param {number} num The number. + * @returns {string|number} The return. + */ + function use2(func, bool, str, num) { + return func(bool, str, num) + } + +==== tests/cases/conformance/jsdoc/mod5.js (0 errors) ==== + /** + * @typedef {{ + * num: + * number, + * str: + * string, + * boo: + * boolean + * }} Type5 + */ + + /** + * Makes use of a type with a multiline type expression. + * @param {Type5} obj The object. + * @returns {string|number} The return. + */ + function check5(obj) { + return obj.boo ? obj.num : obj.str; + } + +==== tests/cases/conformance/jsdoc/mod6.js (0 errors) ==== + /** + * @typedef {{ + * foo: + * *, + * bar: + * * + * }} Type6 + */ + + /** + * Makes use of a type with a multiline type expression. + * @param {Type6} obj The object. + * @returns {*} The return. + */ + function check6(obj) { + return obj.foo; + } + + +==== tests/cases/conformance/jsdoc/mod7.js (2 errors) ==== + /** + Multiline type expressions in comments without leading * are not supported. + @typedef {{ + foo: + *, + ~ +!!! error TS1110: Type expected. + bar: + * + }} Type7 + ~ +!!! error TS1110: Type expected. + */ + \ No newline at end of file diff --git a/tests/baselines/reference/typedefTagWrapping.symbols b/tests/baselines/reference/typedefTagWrapping.symbols index ec93da5a45b..ea0bb73a849 100644 --- a/tests/baselines/reference/typedefTagWrapping.symbols +++ b/tests/baselines/reference/typedefTagWrapping.symbols @@ -1,13 +1,13 @@ === tests/cases/conformance/jsdoc/mod1.js === /** * @typedef {function(string): boolean} - * MyType + * Type1 */ /** * Tries to use a type whose name is on a different * line than the typedef tag. - * @param {MyType} func The function to call. + * @param {Type1} func The function to call. * @param {string} arg The argument to call it with. * @returns {boolean} The return. */ @@ -21,3 +21,165 @@ function callIt(func, arg) { >arg : Symbol(arg, Decl(mod1.js, 12, 21)) } +=== tests/cases/conformance/jsdoc/mod2.js === +/** + * @typedef {{ + * num: number, + * str: string, + * boo: boolean + * }} Type2 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type2} obj The object. + * @returns {string|number} The return. + */ +function check(obj) { +>check : Symbol(check, Decl(mod2.js, 0, 0)) +>obj : Symbol(obj, Decl(mod2.js, 13, 15)) + + return obj.boo ? obj.num : obj.str; +>obj.boo : Symbol(boo, Decl(mod2.js, 3, 17)) +>obj : Symbol(obj, Decl(mod2.js, 13, 15)) +>boo : Symbol(boo, Decl(mod2.js, 3, 17)) +>obj.num : Symbol(num, Decl(mod2.js, 1, 14)) +>obj : Symbol(obj, Decl(mod2.js, 13, 15)) +>num : Symbol(num, Decl(mod2.js, 1, 14)) +>obj.str : Symbol(str, Decl(mod2.js, 2, 17)) +>obj : Symbol(obj, Decl(mod2.js, 13, 15)) +>str : Symbol(str, Decl(mod2.js, 2, 17)) +} + +=== tests/cases/conformance/jsdoc/mod3.js === +/** + * A function whose signature is very long. + * + * @typedef {function(boolean, string, number): + * (string|number)} StringOrNumber1 + */ + +/** + * Makes use of a function type with a long signature. + * @param {StringOrNumber1} func The function. + * @param {boolean} bool The condition. + * @param {string} str The string. + * @param {number} num The number. + * @returns {string|number} The return. + */ +function use1(func, bool, str, num) { +>use1 : Symbol(use1, Decl(mod3.js, 0, 0)) +>func : Symbol(func, Decl(mod3.js, 15, 14)) +>bool : Symbol(bool, Decl(mod3.js, 15, 19)) +>str : Symbol(str, Decl(mod3.js, 15, 25)) +>num : Symbol(num, Decl(mod3.js, 15, 30)) + + return func(bool, str, num) +>func : Symbol(func, Decl(mod3.js, 15, 14)) +>bool : Symbol(bool, Decl(mod3.js, 15, 19)) +>str : Symbol(str, Decl(mod3.js, 15, 25)) +>num : Symbol(num, Decl(mod3.js, 15, 30)) +} + +=== tests/cases/conformance/jsdoc/mod4.js === +/** + * A function whose signature is very long. + * + * @typedef {function(boolean, string, + * number): + * (string|number)} StringOrNumber2 + */ + +/** + * Makes use of a function type with a long signature. + * @param {StringOrNumber2} func The function. + * @param {boolean} bool The condition. + * @param {string} str The string. + * @param {number} num The number. + * @returns {string|number} The return. + */ +function use2(func, bool, str, num) { +>use2 : Symbol(use2, Decl(mod4.js, 0, 0)) +>func : Symbol(func, Decl(mod4.js, 16, 14)) +>bool : Symbol(bool, Decl(mod4.js, 16, 19)) +>str : Symbol(str, Decl(mod4.js, 16, 25)) +>num : Symbol(num, Decl(mod4.js, 16, 30)) + + return func(bool, str, num) +>func : Symbol(func, Decl(mod4.js, 16, 14)) +>bool : Symbol(bool, Decl(mod4.js, 16, 19)) +>str : Symbol(str, Decl(mod4.js, 16, 25)) +>num : Symbol(num, Decl(mod4.js, 16, 30)) +} + +=== tests/cases/conformance/jsdoc/mod5.js === +/** + * @typedef {{ + * num: + * number, + * str: + * string, + * boo: + * boolean + * }} Type5 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type5} obj The object. + * @returns {string|number} The return. + */ +function check5(obj) { +>check5 : Symbol(check5, Decl(mod5.js, 0, 0)) +>obj : Symbol(obj, Decl(mod5.js, 16, 16)) + + return obj.boo ? obj.num : obj.str; +>obj.boo : Symbol(boo, Decl(mod5.js, 5, 12)) +>obj : Symbol(obj, Decl(mod5.js, 16, 16)) +>boo : Symbol(boo, Decl(mod5.js, 5, 12)) +>obj.num : Symbol(num, Decl(mod5.js, 1, 14)) +>obj : Symbol(obj, Decl(mod5.js, 16, 16)) +>num : Symbol(num, Decl(mod5.js, 1, 14)) +>obj.str : Symbol(str, Decl(mod5.js, 3, 12)) +>obj : Symbol(obj, Decl(mod5.js, 16, 16)) +>str : Symbol(str, Decl(mod5.js, 3, 12)) +} + +=== tests/cases/conformance/jsdoc/mod6.js === +/** + * @typedef {{ + * foo: + * *, + * bar: + * * + * }} Type6 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type6} obj The object. + * @returns {*} The return. + */ +function check6(obj) { +>check6 : Symbol(check6, Decl(mod6.js, 0, 0)) +>obj : Symbol(obj, Decl(mod6.js, 14, 16)) + + return obj.foo; +>obj.foo : Symbol(foo, Decl(mod6.js, 1, 14)) +>obj : Symbol(obj, Decl(mod6.js, 14, 16)) +>foo : Symbol(foo, Decl(mod6.js, 1, 14)) +} + + +=== tests/cases/conformance/jsdoc/mod7.js === +/** +No type information for this code. Multiline type expressions in comments without leading * are not supported. +No type information for this code. @typedef {{ +No type information for this code. foo: +No type information for this code. *, +No type information for this code. bar: +No type information for this code. * +No type information for this code. }} Type7 +No type information for this code. */ +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/typedefTagWrapping.types b/tests/baselines/reference/typedefTagWrapping.types index 8c92717d1a1..8b49439d7db 100644 --- a/tests/baselines/reference/typedefTagWrapping.types +++ b/tests/baselines/reference/typedefTagWrapping.types @@ -1,13 +1,13 @@ === tests/cases/conformance/jsdoc/mod1.js === /** * @typedef {function(string): boolean} - * MyType + * Type1 */ /** * Tries to use a type whose name is on a different * line than the typedef tag. - * @param {MyType} func The function to call. + * @param {Type1} func The function to call. * @param {string} arg The argument to call it with. * @returns {boolean} The return. */ @@ -22,3 +22,169 @@ function callIt(func, arg) { >arg : string } +=== tests/cases/conformance/jsdoc/mod2.js === +/** + * @typedef {{ + * num: number, + * str: string, + * boo: boolean + * }} Type2 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type2} obj The object. + * @returns {string|number} The return. + */ +function check(obj) { +>check : (obj: { num: number; str: string; boo: boolean; }) => string | number +>obj : { num: number; str: string; boo: boolean; } + + return obj.boo ? obj.num : obj.str; +>obj.boo ? obj.num : obj.str : string | number +>obj.boo : boolean +>obj : { num: number; str: string; boo: boolean; } +>boo : boolean +>obj.num : number +>obj : { num: number; str: string; boo: boolean; } +>num : number +>obj.str : string +>obj : { num: number; str: string; boo: boolean; } +>str : string +} + +=== tests/cases/conformance/jsdoc/mod3.js === +/** + * A function whose signature is very long. + * + * @typedef {function(boolean, string, number): + * (string|number)} StringOrNumber1 + */ + +/** + * Makes use of a function type with a long signature. + * @param {StringOrNumber1} func The function. + * @param {boolean} bool The condition. + * @param {string} str The string. + * @param {number} num The number. + * @returns {string|number} The return. + */ +function use1(func, bool, str, num) { +>use1 : (func: (arg0: boolean, arg1: string, arg2: number) => string | number, bool: boolean, str: string, num: number) => string | number +>func : (arg0: boolean, arg1: string, arg2: number) => string | number +>bool : boolean +>str : string +>num : number + + return func(bool, str, num) +>func(bool, str, num) : string | number +>func : (arg0: boolean, arg1: string, arg2: number) => string | number +>bool : boolean +>str : string +>num : number +} + +=== tests/cases/conformance/jsdoc/mod4.js === +/** + * A function whose signature is very long. + * + * @typedef {function(boolean, string, + * number): + * (string|number)} StringOrNumber2 + */ + +/** + * Makes use of a function type with a long signature. + * @param {StringOrNumber2} func The function. + * @param {boolean} bool The condition. + * @param {string} str The string. + * @param {number} num The number. + * @returns {string|number} The return. + */ +function use2(func, bool, str, num) { +>use2 : (func: (arg0: boolean, arg1: string, arg2: number) => string | number, bool: boolean, str: string, num: number) => string | number +>func : (arg0: boolean, arg1: string, arg2: number) => string | number +>bool : boolean +>str : string +>num : number + + return func(bool, str, num) +>func(bool, str, num) : string | number +>func : (arg0: boolean, arg1: string, arg2: number) => string | number +>bool : boolean +>str : string +>num : number +} + +=== tests/cases/conformance/jsdoc/mod5.js === +/** + * @typedef {{ + * num: + * number, + * str: + * string, + * boo: + * boolean + * }} Type5 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type5} obj The object. + * @returns {string|number} The return. + */ +function check5(obj) { +>check5 : (obj: { num: number; str: string; boo: boolean; }) => string | number +>obj : { num: number; str: string; boo: boolean; } + + return obj.boo ? obj.num : obj.str; +>obj.boo ? obj.num : obj.str : string | number +>obj.boo : boolean +>obj : { num: number; str: string; boo: boolean; } +>boo : boolean +>obj.num : number +>obj : { num: number; str: string; boo: boolean; } +>num : number +>obj.str : string +>obj : { num: number; str: string; boo: boolean; } +>str : string +} + +=== tests/cases/conformance/jsdoc/mod6.js === +/** + * @typedef {{ + * foo: + * *, + * bar: + * * + * }} Type6 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type6} obj The object. + * @returns {*} The return. + */ +function check6(obj) { +>check6 : (obj: { foo: any; bar: any; }) => any +>obj : { foo: any; bar: any; } + + return obj.foo; +>obj.foo : any +>obj : { foo: any; bar: any; } +>foo : any +} + + +=== tests/cases/conformance/jsdoc/mod7.js === +/** +No type information for this code. Multiline type expressions in comments without leading * are not supported. +No type information for this code. @typedef {{ +No type information for this code. foo: +No type information for this code. *, +No type information for this code. bar: +No type information for this code. * +No type information for this code. }} Type7 +No type information for this code. */ +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/cases/conformance/jsdoc/typedefTagWrapping.ts b/tests/cases/conformance/jsdoc/typedefTagWrapping.ts index 53cff6d02c0..19f4f1289a2 100644 --- a/tests/cases/conformance/jsdoc/typedefTagWrapping.ts +++ b/tests/cases/conformance/jsdoc/typedefTagWrapping.ts @@ -1,20 +1,138 @@ // @noEmit: true // @allowJs: true // @checkJs: true + // @Filename: mod1.js /** * @typedef {function(string): boolean} - * MyType + * Type1 */ /** * Tries to use a type whose name is on a different * line than the typedef tag. - * @param {MyType} func The function to call. + * @param {Type1} func The function to call. * @param {string} arg The argument to call it with. * @returns {boolean} The return. */ function callIt(func, arg) { return func(arg); } + +// @Filename: mod2.js + +/** + * @typedef {{ + * num: number, + * str: string, + * boo: boolean + * }} Type2 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type2} obj The object. + * @returns {string|number} The return. + */ +function check(obj) { + return obj.boo ? obj.num : obj.str; +} + +// @Filename: mod3.js + +/** + * A function whose signature is very long. + * + * @typedef {function(boolean, string, number): + * (string|number)} StringOrNumber1 + */ + +/** + * Makes use of a function type with a long signature. + * @param {StringOrNumber1} func The function. + * @param {boolean} bool The condition. + * @param {string} str The string. + * @param {number} num The number. + * @returns {string|number} The return. + */ +function use1(func, bool, str, num) { + return func(bool, str, num) +} + +// @Filename: mod4.js + +/** + * A function whose signature is very long. + * + * @typedef {function(boolean, string, + * number): + * (string|number)} StringOrNumber2 + */ + +/** + * Makes use of a function type with a long signature. + * @param {StringOrNumber2} func The function. + * @param {boolean} bool The condition. + * @param {string} str The string. + * @param {number} num The number. + * @returns {string|number} The return. + */ +function use2(func, bool, str, num) { + return func(bool, str, num) +} + +// @Filename: mod5.js + +/** + * @typedef {{ + * num: + * number, + * str: + * string, + * boo: + * boolean + * }} Type5 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type5} obj The object. + * @returns {string|number} The return. + */ +function check5(obj) { + return obj.boo ? obj.num : obj.str; +} + +// @Filename: mod6.js + +/** + * @typedef {{ + * foo: + * *, + * bar: + * * + * }} Type6 + */ + +/** + * Makes use of a type with a multiline type expression. + * @param {Type6} obj The object. + * @returns {*} The return. + */ +function check6(obj) { + return obj.foo; +} + + +// @Filename: mod7.js + +/** + Multiline type expressions in comments without leading * are not supported. + @typedef {{ + foo: + *, + bar: + * + }} Type7 + */ diff --git a/tests/cases/fourslash/jsDocFunctionSignatures12.ts b/tests/cases/fourslash/jsDocFunctionSignatures12.ts index 29a8ac4caeb..5976d01a3d6 100644 --- a/tests/cases/fourslash/jsDocFunctionSignatures12.ts +++ b/tests/cases/fourslash/jsDocFunctionSignatures12.ts @@ -1,13 +1,32 @@ - /// + // @allowJs: true -// @Filename: Foo.js +// @Filename: jsDocFunctionSignatures.js + /////** -//// * @param {{ stringProp: string, -//// * numProp: number }} o +//// * @param {{ +//// * stringProp: string, +//// * numProp: number, +//// * boolProp: boolean, +//// * anyProp: *, +//// * anotherAnyProp: +//// * *, +//// * functionProp: +//// * function(string, +//// * *): +//// * * +//// * }} o //// */ ////function f1(o) { //// o/**/; ////} + goTo.marker(); -verify.quickInfoIs("(parameter) o: any"); +verify.quickInfoIs(`(parameter) o: { + stringProp: string; + numProp: number; + boolProp: boolean; + anyProp: any; + anotherAnyProp: any; + functionProp: (arg0: string, arg1: any) => any; +}`); From f1370ecd543c6610edc0f4a56039c4df6cb325bb Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 4 Sep 2018 15:58:18 -0700 Subject: [PATCH 145/163] Allow special assignments to have a contextual type of their declared type if present (#26802) * Allow special assignments to have a contextual type of their declared type if present * Expand change to cover all js special assignments * Remove extraneous line --- src/compiler/binder.ts | 4 +- src/compiler/checker.ts | 50 +++++--- .../expandoFunctionContextualTypes.js | 22 ++++ .../expandoFunctionContextualTypes.symbols | 34 ++++++ .../expandoFunctionContextualTypes.types | 31 +++++ .../expandoFunctionContextualTypesJs.symbols | 86 ++++++++++++++ .../expandoFunctionContextualTypesJs.types | 109 ++++++++++++++++++ .../reference/moduleExportAssignment2.symbols | 4 +- .../expandoFunctionContextualTypes.ts | 14 +++ .../expandoFunctionContextualTypesJs.ts | 57 +++++++++ 10 files changed, 393 insertions(+), 18 deletions(-) create mode 100644 tests/baselines/reference/expandoFunctionContextualTypes.js create mode 100644 tests/baselines/reference/expandoFunctionContextualTypes.symbols create mode 100644 tests/baselines/reference/expandoFunctionContextualTypes.types create mode 100644 tests/baselines/reference/expandoFunctionContextualTypesJs.symbols create mode 100644 tests/baselines/reference/expandoFunctionContextualTypesJs.types create mode 100644 tests/cases/compiler/expandoFunctionContextualTypes.ts create mode 100644 tests/cases/compiler/expandoFunctionContextualTypesJs.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index bab6ca7b360..9c7756d0d30 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2080,8 +2080,8 @@ namespace ts { if (isInJavaScriptFile(node) && file.commonJsModuleIndicator && isModuleExportsPropertyAccessExpression(node as PropertyAccessExpression) && - !lookupSymbolForNameWorker(container, "module" as __String)) { - declareSymbol(container.locals!, /*parent*/ undefined, (node as PropertyAccessExpression).expression as Identifier, + !lookupSymbolForNameWorker(blockScopeContainer, "module" as __String)) { + declareSymbol(file.locals!, /*parent*/ undefined, (node as PropertyAccessExpression).expression as Identifier, SymbolFlags.FunctionScopedVariable | SymbolFlags.ModuleExports, SymbolFlags.FunctionScopedVariableExcludes); } break; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 57de68ab02b..29720ff8532 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16122,7 +16122,14 @@ namespace ts { const { left, operatorToken, right } = binaryExpression; switch (operatorToken.kind) { case SyntaxKind.EqualsToken: - return node === right && isContextSensitiveAssignment(binaryExpression) ? getTypeOfExpression(left) : undefined; + if (node !== right) { + return undefined; + } + const contextSensitive = getIsContextSensitiveAssignmentOrContextType(binaryExpression); + if (!contextSensitive) { + return undefined; + } + return contextSensitive === true ? getTypeOfExpression(left) : contextSensitive; case SyntaxKind.BarBarToken: // When an || expression has a contextual type, the operands are contextually typed by that type. When an || // expression has no contextual type, the right operand is contextually typed by the type of the left operand, @@ -16140,7 +16147,7 @@ namespace ts { // In an assignment expression, the right operand is contextually typed by the type of the left operand. // Don't do this for special property assignments unless there is a type tag on the assignment, to avoid circularity from checking the right operand. - function isContextSensitiveAssignment(binaryExpression: BinaryExpression): boolean { + function getIsContextSensitiveAssignmentOrContextType(binaryExpression: BinaryExpression): boolean | Type { const kind = getSpecialPropertyAssignmentKind(binaryExpression); switch (kind) { case SpecialPropertyAssignmentKind.None: @@ -16159,29 +16166,44 @@ namespace ts { if (!decl) { return false; } - if (isInJavaScriptFile(decl)) { - return !!getJSDocTypeTag(decl); + const lhs = binaryExpression.left as PropertyAccessExpression; + const overallAnnotation = getEffectiveTypeAnnotationNode(decl); + if (overallAnnotation) { + return getTypeFromTypeNode(overallAnnotation); } - else if (isIdentifier((binaryExpression.left as PropertyAccessExpression).expression)) { - const id = (binaryExpression.left as PropertyAccessExpression).expression as Identifier; + else if (isIdentifier(lhs.expression)) { + const id = lhs.expression; const parentSymbol = resolveName(id, id.escapedText, SymbolFlags.Value, undefined, id.escapedText, /*isUse*/ true); - return !isFunctionSymbol(parentSymbol); + if (parentSymbol && isFunctionSymbol(parentSymbol)) { + const annotated = getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration); + if (annotated) { + const type = getTypeOfPropertyOfContextualType(getTypeFromTypeNode(annotated), lhs.name.escapedText); + return type || false; + } + return false; + } } - return true; + return !isInJavaScriptFile(decl); } + case SpecialPropertyAssignmentKind.ModuleExports: case SpecialPropertyAssignmentKind.ThisProperty: - if (!binaryExpression.symbol || - binaryExpression.symbol.valueDeclaration && !!getJSDocTypeTag(binaryExpression.symbol.valueDeclaration)) { - return true; + if (!binaryExpression.symbol) return true; + if (binaryExpression.symbol.valueDeclaration) { + const annotated = getEffectiveTypeAnnotationNode(binaryExpression.symbol.valueDeclaration); + if (annotated) { + const type = getTypeFromTypeNode(annotated); + if (type) { + return type; + } + } } + if (kind === SpecialPropertyAssignmentKind.ModuleExports) return false; const thisAccess = binaryExpression.left as PropertyAccessExpression; if (!isObjectLiteralMethod(getThisContainer(thisAccess.expression, /*includeArrowFunctions*/ false))) { return false; } const thisType = checkThisExpression(thisAccess.expression); - return thisType && !!getPropertyOfType(thisType, thisAccess.name.escapedText); - case SpecialPropertyAssignmentKind.ModuleExports: - return !binaryExpression.symbol || binaryExpression.symbol.valueDeclaration && !!getJSDocTypeTag(binaryExpression.symbol.valueDeclaration); + return thisType && getTypeOfPropertyOfContextualType(thisType, thisAccess.name.escapedText) || false; default: return Debug.assertNever(kind); } diff --git a/tests/baselines/reference/expandoFunctionContextualTypes.js b/tests/baselines/reference/expandoFunctionContextualTypes.js new file mode 100644 index 00000000000..541adf963e4 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionContextualTypes.js @@ -0,0 +1,22 @@ +//// [expandoFunctionContextualTypes.ts] +interface MyComponentProps { + color: "red" | "blue" +} + +interface StatelessComponent

{ + (): any; + defaultProps?: Partial

; +} + +const MyComponent: StatelessComponent = () => null as any; + +MyComponent.defaultProps = { + color: "red" +}; + + +//// [expandoFunctionContextualTypes.js] +var MyComponent = function () { return null; }; +MyComponent.defaultProps = { + color: "red" +}; diff --git a/tests/baselines/reference/expandoFunctionContextualTypes.symbols b/tests/baselines/reference/expandoFunctionContextualTypes.symbols new file mode 100644 index 00000000000..cea0647c762 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionContextualTypes.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/expandoFunctionContextualTypes.ts === +interface MyComponentProps { +>MyComponentProps : Symbol(MyComponentProps, Decl(expandoFunctionContextualTypes.ts, 0, 0)) + + color: "red" | "blue" +>color : Symbol(MyComponentProps.color, Decl(expandoFunctionContextualTypes.ts, 0, 28)) +} + +interface StatelessComponent

{ +>StatelessComponent : Symbol(StatelessComponent, Decl(expandoFunctionContextualTypes.ts, 2, 1)) +>P : Symbol(P, Decl(expandoFunctionContextualTypes.ts, 4, 29)) + + (): any; + defaultProps?: Partial

; +>defaultProps : Symbol(StatelessComponent.defaultProps, Decl(expandoFunctionContextualTypes.ts, 5, 12)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(expandoFunctionContextualTypes.ts, 4, 29)) +} + +const MyComponent: StatelessComponent = () => null as any; +>MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5)) +>StatelessComponent : Symbol(StatelessComponent, Decl(expandoFunctionContextualTypes.ts, 2, 1)) +>MyComponentProps : Symbol(MyComponentProps, Decl(expandoFunctionContextualTypes.ts, 0, 0)) + +MyComponent.defaultProps = { +>MyComponent.defaultProps : Symbol(StatelessComponent.defaultProps, Decl(expandoFunctionContextualTypes.ts, 5, 12)) +>MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5)) +>defaultProps : Symbol(StatelessComponent.defaultProps, Decl(expandoFunctionContextualTypes.ts, 5, 12)) + + color: "red" +>color : Symbol(color, Decl(expandoFunctionContextualTypes.ts, 11, 28)) + +}; + diff --git a/tests/baselines/reference/expandoFunctionContextualTypes.types b/tests/baselines/reference/expandoFunctionContextualTypes.types new file mode 100644 index 00000000000..e1eca92659c --- /dev/null +++ b/tests/baselines/reference/expandoFunctionContextualTypes.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/expandoFunctionContextualTypes.ts === +interface MyComponentProps { + color: "red" | "blue" +>color : "red" | "blue" +} + +interface StatelessComponent

{ + (): any; + defaultProps?: Partial

; +>defaultProps : Partial

+} + +const MyComponent: StatelessComponent = () => null as any; +>MyComponent : StatelessComponent +>() => null as any : { (): any; defaultProps: { color: "red"; }; } +>null as any : any +>null : null + +MyComponent.defaultProps = { +>MyComponent.defaultProps = { color: "red"} : { color: "red"; } +>MyComponent.defaultProps : Partial +>MyComponent : StatelessComponent +>defaultProps : Partial +>{ color: "red"} : { color: "red"; } + + color: "red" +>color : "red" +>"red" : "red" + +}; + diff --git a/tests/baselines/reference/expandoFunctionContextualTypesJs.symbols b/tests/baselines/reference/expandoFunctionContextualTypesJs.symbols new file mode 100644 index 00000000000..5ef7acd5366 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionContextualTypesJs.symbols @@ -0,0 +1,86 @@ +=== tests/cases/compiler/input.js === +/** @typedef {{ color: "red" | "blue" }} MyComponentProps */ + +/** + * @template P + * @typedef {{ (): any; defaultProps?: Partial

}} StatelessComponent */ + + /** + * @type {StatelessComponent} + */ +const MyComponent = () => /* @type {any} */(null); +>MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5)) + +MyComponent.defaultProps = { +>MyComponent.defaultProps : Symbol(defaultProps, Decl(input.js, 4, 23)) +>MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5)) +>defaultProps : Symbol(defaultProps, Decl(input.js, 4, 23)) + + color: "red" +>color : Symbol(color, Decl(input.js, 11, 28)) + +}; + +const MyComponent2 = () => null; +>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5)) + +/** + * @type {MyComponentProps} + */ +MyComponent2.defaultProps = { +>MyComponent2.defaultProps : Symbol(MyComponent2.defaultProps, Decl(input.js, 15, 32)) +>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5)) +>defaultProps : Symbol(MyComponent2.defaultProps, Decl(input.js, 15, 32)) + + color: "red" +>color : Symbol(color, Decl(input.js, 20, 29)) +} + +/** + * @type {StatelessComponent} + */ +const check = MyComponent2; +>check : Symbol(check, Decl(input.js, 27, 5)) +>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5)) + +/** + * + * @param {{ props: MyComponentProps }} p + */ +function expectLiteral(p) {} +>expectLiteral : Symbol(expectLiteral, Decl(input.js, 27, 27)) +>p : Symbol(p, Decl(input.js, 33, 23)) + +function foo() { +>foo : Symbol(foo, Decl(input.js, 33, 28)) + + /** + * @type {MyComponentProps} + */ + this.props = { color: "red" }; +>props : Symbol(foo.props, Decl(input.js, 35, 16)) +>color : Symbol(color, Decl(input.js, 39, 18)) + + expectLiteral(this); +>expectLiteral : Symbol(expectLiteral, Decl(input.js, 27, 27)) +} + +/** + * @type {MyComponentProps} + */ +module.exports = { +>module.exports : Symbol("tests/cases/compiler/input", Decl(input.js, 0, 0)) +>module : Symbol(export=, Decl(input.js, 42, 1)) +>exports : Symbol(export=, Decl(input.js, 42, 1)) + + color: "red" +>color : Symbol(color, Decl(input.js, 47, 18)) +} + +expectLiteral({ props: module.exports }); +>expectLiteral : Symbol(expectLiteral, Decl(input.js, 27, 27)) +>props : Symbol(props, Decl(input.js, 51, 15)) +>module.exports : Symbol("tests/cases/compiler/input", Decl(input.js, 0, 0)) +>module : Symbol(module, Decl(input.js, 42, 1), Decl(input.js, 51, 22)) +>exports : Symbol("tests/cases/compiler/input", Decl(input.js, 0, 0)) + diff --git a/tests/baselines/reference/expandoFunctionContextualTypesJs.types b/tests/baselines/reference/expandoFunctionContextualTypesJs.types new file mode 100644 index 00000000000..081c57c0dac --- /dev/null +++ b/tests/baselines/reference/expandoFunctionContextualTypesJs.types @@ -0,0 +1,109 @@ +=== tests/cases/compiler/input.js === +/** @typedef {{ color: "red" | "blue" }} MyComponentProps */ + +/** + * @template P + * @typedef {{ (): any; defaultProps?: Partial

}} StatelessComponent */ + + /** + * @type {StatelessComponent} + */ +const MyComponent = () => /* @type {any} */(null); +>MyComponent : { (): any; defaultProps?: Partial<{ color: "red" | "blue"; }>; } +>() => /* @type {any} */(null) : { (): any; defaultProps: { color: "red"; }; } +>(null) : null +>null : null + +MyComponent.defaultProps = { +>MyComponent.defaultProps = { color: "red"} : { color: "red"; } +>MyComponent.defaultProps : Partial<{ color: "red" | "blue"; }> +>MyComponent : { (): any; defaultProps?: Partial<{ color: "red" | "blue"; }>; } +>defaultProps : Partial<{ color: "red" | "blue"; }> +>{ color: "red"} : { color: "red"; } + + color: "red" +>color : "red" +>"red" : "red" + +}; + +const MyComponent2 = () => null; +>MyComponent2 : { (): any; defaultProps: { color: "red" | "blue"; }; } +>() => null : { (): any; defaultProps: { color: "red" | "blue"; }; } +>null : null + +/** + * @type {MyComponentProps} + */ +MyComponent2.defaultProps = { +>MyComponent2.defaultProps = { color: "red"} : { color: "red"; } +>MyComponent2.defaultProps : { color: "red" | "blue"; } +>MyComponent2 : { (): any; defaultProps: { color: "red" | "blue"; }; } +>defaultProps : { color: "red" | "blue"; } +>{ color: "red"} : { color: "red"; } + + color: "red" +>color : "red" +>"red" : "red" +} + +/** + * @type {StatelessComponent} + */ +const check = MyComponent2; +>check : { (): any; defaultProps?: Partial<{ color: "red" | "blue"; }>; } +>MyComponent2 : { (): any; defaultProps: { color: "red" | "blue"; }; } + +/** + * + * @param {{ props: MyComponentProps }} p + */ +function expectLiteral(p) {} +>expectLiteral : (p: { props: { color: "red" | "blue"; }; }) => void +>p : { props: { color: "red" | "blue"; }; } + +function foo() { +>foo : typeof foo + + /** + * @type {MyComponentProps} + */ + this.props = { color: "red" }; +>this.props = { color: "red" } : { color: "red"; } +>this.props : any +>this : any +>props : any +>{ color: "red" } : { color: "red"; } +>color : "red" +>"red" : "red" + + expectLiteral(this); +>expectLiteral(this) : void +>expectLiteral : (p: { props: { color: "red" | "blue"; }; }) => void +>this : any +} + +/** + * @type {MyComponentProps} + */ +module.exports = { +>module.exports = { color: "red"} : { color: "red" | "blue"; } +>module.exports : { color: "red" | "blue"; } +>module : { "tests/cases/compiler/input": { color: "red" | "blue"; }; } +>exports : { color: "red" | "blue"; } +>{ color: "red"} : { color: "red"; } + + color: "red" +>color : "red" +>"red" : "red" +} + +expectLiteral({ props: module.exports }); +>expectLiteral({ props: module.exports }) : void +>expectLiteral : (p: { props: { color: "red" | "blue"; }; }) => void +>{ props: module.exports } : { props: { color: "red" | "blue"; }; } +>props : { color: "red" | "blue"; } +>module.exports : { color: "red" | "blue"; } +>module : { "tests/cases/compiler/input": { color: "red" | "blue"; }; } +>exports : { color: "red" | "blue"; } + diff --git a/tests/baselines/reference/moduleExportAssignment2.symbols b/tests/baselines/reference/moduleExportAssignment2.symbols index 25e80647d89..eaafdbefb1f 100644 --- a/tests/baselines/reference/moduleExportAssignment2.symbols +++ b/tests/baselines/reference/moduleExportAssignment2.symbols @@ -9,7 +9,7 @@ var npm = module.exports = function (tree) { module.exports.asReadInstalled = function (tree) { >module.exports.asReadInstalled : Symbol(asReadInstalled, Decl(npm.js, 1, 1)) >module.exports : Symbol(asReadInstalled, Decl(npm.js, 1, 1)) ->module : Symbol(module, Decl(npm.js, 0, 9)) +>module : Symbol(module, Decl(npm.js, 0, 9), Decl(npm.js, 3, 13)) >exports : Symbol("tests/cases/conformance/salsa/npm", Decl(npm.js, 0, 0)) >asReadInstalled : Symbol(asReadInstalled, Decl(npm.js, 1, 1)) >tree : Symbol(tree, Decl(npm.js, 2, 43)) @@ -20,7 +20,7 @@ module.exports.asReadInstalled = function (tree) { module.exports(tree) >module.exports : Symbol("tests/cases/conformance/salsa/npm", Decl(npm.js, 0, 0)) ->module : Symbol(module, Decl(npm.js, 3, 13)) +>module : Symbol(module, Decl(npm.js, 0, 9), Decl(npm.js, 3, 13)) >exports : Symbol("tests/cases/conformance/salsa/npm", Decl(npm.js, 0, 0)) >tree : Symbol(tree, Decl(npm.js, 2, 43)) } diff --git a/tests/cases/compiler/expandoFunctionContextualTypes.ts b/tests/cases/compiler/expandoFunctionContextualTypes.ts new file mode 100644 index 00000000000..ae624549252 --- /dev/null +++ b/tests/cases/compiler/expandoFunctionContextualTypes.ts @@ -0,0 +1,14 @@ +interface MyComponentProps { + color: "red" | "blue" +} + +interface StatelessComponent

{ + (): any; + defaultProps?: Partial

; +} + +const MyComponent: StatelessComponent = () => null as any; + +MyComponent.defaultProps = { + color: "red" +}; diff --git a/tests/cases/compiler/expandoFunctionContextualTypesJs.ts b/tests/cases/compiler/expandoFunctionContextualTypesJs.ts new file mode 100644 index 00000000000..e69f3dc79c4 --- /dev/null +++ b/tests/cases/compiler/expandoFunctionContextualTypesJs.ts @@ -0,0 +1,57 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @filename: input.js + +/** @typedef {{ color: "red" | "blue" }} MyComponentProps */ + +/** + * @template P + * @typedef {{ (): any; defaultProps?: Partial

}} StatelessComponent */ + + /** + * @type {StatelessComponent} + */ +const MyComponent = () => /* @type {any} */(null); + +MyComponent.defaultProps = { + color: "red" +}; + +const MyComponent2 = () => null; + +/** + * @type {MyComponentProps} + */ +MyComponent2.defaultProps = { + color: "red" +} + +/** + * @type {StatelessComponent} + */ +const check = MyComponent2; + +/** + * + * @param {{ props: MyComponentProps }} p + */ +function expectLiteral(p) {} + +function foo() { + /** + * @type {MyComponentProps} + */ + this.props = { color: "red" }; + + expectLiteral(this); +} + +/** + * @type {MyComponentProps} + */ +module.exports = { + color: "red" +} + +expectLiteral({ props: module.exports }); From ca662419e8544618cf9ce13392b66d606a4649d3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 4 Sep 2018 16:00:10 -0700 Subject: [PATCH 146/163] Dont consider export specifiers visible in their local scope (#26884) --- src/compiler/checker.ts | 6 ++- ...rationEmitExportAliasVisibiilityMarking.js | 46 +++++++++++++++++++ ...nEmitExportAliasVisibiilityMarking.symbols | 39 ++++++++++++++++ ...ionEmitExportAliasVisibiilityMarking.types | 44 ++++++++++++++++++ ...s6ExportClauseWithoutModuleSpecifier.types | 10 ++-- ...ortClauseWithoutModuleSpecifierInEs5.types | 10 ++-- .../exportSpecifierForAGlobal.errors.txt | 5 +- .../reference/exportSpecifierForAGlobal.js | 5 ++ .../reference/exportsAndImports1-amd.types | 8 ++-- .../reference/exportsAndImports1-es6.types | 8 ++-- .../reference/exportsAndImports1.types | 8 ++-- .../reference/exportsAndImports3-amd.symbols | 12 ++--- .../reference/exportsAndImports3-amd.types | 16 +++---- .../reference/exportsAndImports3-es6.symbols | 12 ++--- .../reference/exportsAndImports3-es6.types | 16 +++---- .../reference/exportsAndImports3.symbols | 12 ++--- .../reference/exportsAndImports3.types | 16 +++---- .../isolatedModulesReExportType.types | 2 +- ...eSameValueDuplicateExportedBindings2.types | 2 +- ...eexportWrittenCorrectlyInDeclaration.types | 4 +- .../systemNamespaceAliasEmit.symbols | 4 +- ...rationEmitExportAliasVisibiilityMarking.ts | 14 ++++++ 22 files changed, 224 insertions(+), 75 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.js create mode 100644 tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.symbols create mode 100644 tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.types create mode 100644 tests/cases/compiler/declarationEmitExportAliasVisibiilityMarking.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 29720ff8532..70c7f428951 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2748,7 +2748,11 @@ namespace ts { && symbolFromSymbolTable.escapedName !== InternalSymbolName.Default && !(isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && isExternalModule(getSourceFileOfNode(enclosingDeclaration))) // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name - && (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))) { + && (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration)) + // While exports are generally considered to be in scope, export-specifier declared symbols are _not_ + // See similar comment in `resolveName` for details + && (ignoreQualification || !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)) + ) { const resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable); if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification)) { diff --git a/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.js b/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.js new file mode 100644 index 00000000000..fcc0722c07e --- /dev/null +++ b/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.js @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/declarationEmitExportAliasVisibiilityMarking.ts] //// + +//// [Types.ts] +type Suit = 'Hearts' | 'Spades' | 'Clubs' | 'Diamonds'; +type Rank = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 'Jack' | 'Queen' | 'King'; +export { Suit, Rank }; + +//// [Card.ts] +import { Suit, Rank } from './Types'; +export default (suit: Suit, rank: Rank) => ({suit, rank}); + +//// [index.ts] +export let lazyCard = () => import('./Card').then(a => a.default); +export { Suit, Rank } from './Types'; + + +//// [Types.js] +"use strict"; +exports.__esModule = true; +//// [Card.js] +"use strict"; +exports.__esModule = true; +exports["default"] = (function (suit, rank) { return ({ suit: suit, rank: rank }); }); +//// [index.js] +"use strict"; +exports.__esModule = true; +exports.lazyCard = function () { return Promise.resolve().then(function () { return require('./Card'); }).then(function (a) { return a["default"]; }); }; + + +//// [Types.d.ts] +declare type Suit = 'Hearts' | 'Spades' | 'Clubs' | 'Diamonds'; +declare type Rank = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 'Jack' | 'Queen' | 'King'; +export { Suit, Rank }; +//// [Card.d.ts] +import { Suit, Rank } from './Types'; +declare const _default: (suit: Suit, rank: Rank) => { + suit: Suit; + rank: Rank; +}; +export default _default; +//// [index.d.ts] +export declare let lazyCard: () => Promise<(suit: import("./Types").Suit, rank: import("./Types").Rank) => { + suit: import("./Types").Suit; + rank: import("./Types").Rank; +}>; +export { Suit, Rank } from './Types'; diff --git a/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.symbols b/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.symbols new file mode 100644 index 00000000000..a89d82fff50 --- /dev/null +++ b/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.symbols @@ -0,0 +1,39 @@ +=== tests/cases/compiler/Types.ts === +type Suit = 'Hearts' | 'Spades' | 'Clubs' | 'Diamonds'; +>Suit : Symbol(Suit, Decl(Types.ts, 0, 0)) + +type Rank = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 'Jack' | 'Queen' | 'King'; +>Rank : Symbol(Rank, Decl(Types.ts, 0, 55)) + +export { Suit, Rank }; +>Suit : Symbol(Suit, Decl(Types.ts, 2, 8)) +>Rank : Symbol(Rank, Decl(Types.ts, 2, 14)) + +=== tests/cases/compiler/Card.ts === +import { Suit, Rank } from './Types'; +>Suit : Symbol(Suit, Decl(Card.ts, 0, 8)) +>Rank : Symbol(Rank, Decl(Card.ts, 0, 14)) + +export default (suit: Suit, rank: Rank) => ({suit, rank}); +>suit : Symbol(suit, Decl(Card.ts, 1, 16)) +>Suit : Symbol(Suit, Decl(Card.ts, 0, 8)) +>rank : Symbol(rank, Decl(Card.ts, 1, 27)) +>Rank : Symbol(Rank, Decl(Card.ts, 0, 14)) +>suit : Symbol(suit, Decl(Card.ts, 1, 45)) +>rank : Symbol(rank, Decl(Card.ts, 1, 50)) + +=== tests/cases/compiler/index.ts === +export let lazyCard = () => import('./Card').then(a => a.default); +>lazyCard : Symbol(lazyCard, Decl(index.ts, 0, 10)) +>import('./Card').then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>'./Card' : Symbol("tests/cases/compiler/Card", Decl(Card.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>a : Symbol(a, Decl(index.ts, 0, 50)) +>a.default : Symbol(default, Decl(Card.ts, 0, 37)) +>a : Symbol(a, Decl(index.ts, 0, 50)) +>default : Symbol(default, Decl(Card.ts, 0, 37)) + +export { Suit, Rank } from './Types'; +>Suit : Symbol(Suit, Decl(index.ts, 1, 8)) +>Rank : Symbol(Rank, Decl(index.ts, 1, 14)) + diff --git a/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.types b/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.types new file mode 100644 index 00000000000..bf9666f3082 --- /dev/null +++ b/tests/baselines/reference/declarationEmitExportAliasVisibiilityMarking.types @@ -0,0 +1,44 @@ +=== tests/cases/compiler/Types.ts === +type Suit = 'Hearts' | 'Spades' | 'Clubs' | 'Diamonds'; +>Suit : Suit + +type Rank = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 'Jack' | 'Queen' | 'King'; +>Rank : Rank + +export { Suit, Rank }; +>Suit : any +>Rank : any + +=== tests/cases/compiler/Card.ts === +import { Suit, Rank } from './Types'; +>Suit : any +>Rank : any + +export default (suit: Suit, rank: Rank) => ({suit, rank}); +>(suit: Suit, rank: Rank) => ({suit, rank}) : (suit: Suit, rank: Rank) => { suit: Suit; rank: Rank; } +>suit : Suit +>rank : Rank +>({suit, rank}) : { suit: Suit; rank: Rank; } +>{suit, rank} : { suit: Suit; rank: Rank; } +>suit : Suit +>rank : Rank + +=== tests/cases/compiler/index.ts === +export let lazyCard = () => import('./Card').then(a => a.default); +>lazyCard : () => Promise<(suit: import("tests/cases/compiler/Types").Suit, rank: import("tests/cases/compiler/Types").Rank) => { suit: import("tests/cases/compiler/Types").Suit; rank: import("tests/cases/compiler/Types").Rank; }> +>() => import('./Card').then(a => a.default) : () => Promise<(suit: import("tests/cases/compiler/Types").Suit, rank: import("tests/cases/compiler/Types").Rank) => { suit: import("tests/cases/compiler/Types").Suit; rank: import("tests/cases/compiler/Types").Rank; }> +>import('./Card').then(a => a.default) : Promise<(suit: import("tests/cases/compiler/Types").Suit, rank: import("tests/cases/compiler/Types").Rank) => { suit: import("tests/cases/compiler/Types").Suit; rank: import("tests/cases/compiler/Types").Rank; }> +>import('./Card').then : (onfulfilled?: (value: typeof import("tests/cases/compiler/Card")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>import('./Card') : Promise +>'./Card' : "./Card" +>then : (onfulfilled?: (value: typeof import("tests/cases/compiler/Card")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +>a => a.default : (a: typeof import("tests/cases/compiler/Card")) => (suit: import("tests/cases/compiler/Types").Suit, rank: import("tests/cases/compiler/Types").Rank) => { suit: import("tests/cases/compiler/Types").Suit; rank: import("tests/cases/compiler/Types").Rank; } +>a : typeof import("tests/cases/compiler/Card") +>a.default : (suit: import("tests/cases/compiler/Types").Suit, rank: import("tests/cases/compiler/Types").Rank) => { suit: import("tests/cases/compiler/Types").Suit; rank: import("tests/cases/compiler/Types").Rank; } +>a : typeof import("tests/cases/compiler/Card") +>default : (suit: import("tests/cases/compiler/Types").Suit, rank: import("tests/cases/compiler/Types").Rank) => { suit: import("tests/cases/compiler/Types").Suit; rank: import("tests/cases/compiler/Types").Rank; } + +export { Suit, Rank } from './Types'; +>Suit : any +>Rank : any + diff --git a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types index 532931fd2b3..523f0673025 100644 --- a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types +++ b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifier.types @@ -20,16 +20,16 @@ export module uninstantiated { === tests/cases/compiler/client.ts === export { c } from "server"; ->c : typeof c +>c : typeof import("tests/cases/compiler/server").c export { c as c2 } from "server"; ->c : typeof c ->c2 : typeof c +>c : typeof import("tests/cases/compiler/server").c +>c2 : typeof import("tests/cases/compiler/server").c export { i, m as instantiatedModule } from "server"; >i : any ->m : typeof instantiatedModule ->instantiatedModule : typeof instantiatedModule +>m : typeof import("tests/cases/compiler/server").m +>instantiatedModule : typeof import("tests/cases/compiler/server").m export { uninstantiated } from "server"; >uninstantiated : any diff --git a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types index 57b4845a6fa..cb5fd1d3756 100644 --- a/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types +++ b/tests/baselines/reference/es6ExportClauseWithoutModuleSpecifierInEs5.types @@ -20,16 +20,16 @@ export module uninstantiated { === tests/cases/compiler/client.ts === export { c } from "./server"; ->c : typeof c +>c : typeof import("tests/cases/compiler/server").c export { c as c2 } from "./server"; ->c : typeof c ->c2 : typeof c +>c : typeof import("tests/cases/compiler/server").c +>c2 : typeof import("tests/cases/compiler/server").c export { i, m as instantiatedModule } from "./server"; >i : any ->m : typeof instantiatedModule ->instantiatedModule : typeof instantiatedModule +>m : typeof import("tests/cases/compiler/server").m +>instantiatedModule : typeof import("tests/cases/compiler/server").m export { uninstantiated } from "./server"; >uninstantiated : any diff --git a/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt b/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt index 20a1c9a7d41..d2f103a91fa 100644 --- a/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt +++ b/tests/baselines/reference/exportSpecifierForAGlobal.errors.txt @@ -1,17 +1,14 @@ tests/cases/compiler/b.ts(1,9): error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. -tests/cases/compiler/b.ts(2,17): error TS4060: Return type of exported function has or is using private name 'X'. ==== tests/cases/compiler/a.d.ts (0 errors) ==== declare class X { } -==== tests/cases/compiler/b.ts (2 errors) ==== +==== tests/cases/compiler/b.ts (1 errors) ==== export {X}; ~ !!! error TS2661: Cannot export 'X'. Only local declarations can be exported from a module. export function f() { - ~ -!!! error TS4060: Return type of exported function has or is using private name 'X'. var x: X; return x; } diff --git a/tests/baselines/reference/exportSpecifierForAGlobal.js b/tests/baselines/reference/exportSpecifierForAGlobal.js index 9f12241cbd1..6023b7c7f14 100644 --- a/tests/baselines/reference/exportSpecifierForAGlobal.js +++ b/tests/baselines/reference/exportSpecifierForAGlobal.js @@ -19,3 +19,8 @@ function f() { return x; } exports.f = f; + + +//// [b.d.ts] +export { X }; +export declare function f(): X; diff --git a/tests/baselines/reference/exportsAndImports1-amd.types b/tests/baselines/reference/exportsAndImports1-amd.types index b63913106fa..fc79a3dcc78 100644 --- a/tests/baselines/reference/exportsAndImports1-amd.types +++ b/tests/baselines/reference/exportsAndImports1-amd.types @@ -61,11 +61,11 @@ export { v, f, C, I, E, D, M, N, T, a }; export { v, f, C, I, E, D, M, N, T, a } from "./t1"; >v : number >f : () => void ->C : typeof C +>C : typeof import("tests/cases/conformance/es6/modules/t1").C >I : any ->E : typeof E ->D : typeof D ->M : typeof M +>E : typeof import("tests/cases/conformance/es6/modules/t1").E +>D : typeof import("tests/cases/conformance/es6/modules/t1").D +>M : typeof import("tests/cases/conformance/es6/modules/t1").M >N : any >T : any >a : any diff --git a/tests/baselines/reference/exportsAndImports1-es6.types b/tests/baselines/reference/exportsAndImports1-es6.types index b63913106fa..fc79a3dcc78 100644 --- a/tests/baselines/reference/exportsAndImports1-es6.types +++ b/tests/baselines/reference/exportsAndImports1-es6.types @@ -61,11 +61,11 @@ export { v, f, C, I, E, D, M, N, T, a }; export { v, f, C, I, E, D, M, N, T, a } from "./t1"; >v : number >f : () => void ->C : typeof C +>C : typeof import("tests/cases/conformance/es6/modules/t1").C >I : any ->E : typeof E ->D : typeof D ->M : typeof M +>E : typeof import("tests/cases/conformance/es6/modules/t1").E +>D : typeof import("tests/cases/conformance/es6/modules/t1").D +>M : typeof import("tests/cases/conformance/es6/modules/t1").M >N : any >T : any >a : any diff --git a/tests/baselines/reference/exportsAndImports1.types b/tests/baselines/reference/exportsAndImports1.types index b63913106fa..fc79a3dcc78 100644 --- a/tests/baselines/reference/exportsAndImports1.types +++ b/tests/baselines/reference/exportsAndImports1.types @@ -61,11 +61,11 @@ export { v, f, C, I, E, D, M, N, T, a }; export { v, f, C, I, E, D, M, N, T, a } from "./t1"; >v : number >f : () => void ->C : typeof C +>C : typeof import("tests/cases/conformance/es6/modules/t1").C >I : any ->E : typeof E ->D : typeof D ->M : typeof M +>E : typeof import("tests/cases/conformance/es6/modules/t1").E +>D : typeof import("tests/cases/conformance/es6/modules/t1").D +>M : typeof import("tests/cases/conformance/es6/modules/t1").M >N : any >T : any >a : any diff --git a/tests/baselines/reference/exportsAndImports3-amd.symbols b/tests/baselines/reference/exportsAndImports3-amd.symbols index edc5d5c2e4e..f71014281c2 100644 --- a/tests/baselines/reference/exportsAndImports3-amd.symbols +++ b/tests/baselines/reference/exportsAndImports3-amd.symbols @@ -15,17 +15,17 @@ export enum E { >E : Symbol(E, Decl(t1.ts, 5, 1)) A, B, C ->A : Symbol(E1.A, Decl(t1.ts, 6, 15)) ->B : Symbol(E1.B, Decl(t1.ts, 7, 6)) ->C : Symbol(E1.C, Decl(t1.ts, 7, 9)) +>A : Symbol(E.A, Decl(t1.ts, 6, 15)) +>B : Symbol(E.B, Decl(t1.ts, 7, 6)) +>C : Symbol(E.C, Decl(t1.ts, 7, 9)) } export const enum D { >D : Symbol(D, Decl(t1.ts, 8, 1)) A, B, C ->A : Symbol(D1.A, Decl(t1.ts, 9, 21)) ->B : Symbol(D1.B, Decl(t1.ts, 10, 6)) ->C : Symbol(D1.C, Decl(t1.ts, 10, 9)) +>A : Symbol(D.A, Decl(t1.ts, 9, 21)) +>B : Symbol(D.B, Decl(t1.ts, 10, 6)) +>C : Symbol(D.C, Decl(t1.ts, 10, 9)) } export module M { >M : Symbol(M, Decl(t1.ts, 11, 1)) diff --git a/tests/baselines/reference/exportsAndImports3-amd.types b/tests/baselines/reference/exportsAndImports3-amd.types index a8357a4db22..8a021f7a009 100644 --- a/tests/baselines/reference/exportsAndImports3-amd.types +++ b/tests/baselines/reference/exportsAndImports3-amd.types @@ -73,16 +73,16 @@ export { v1 as v, f1 as f, C1 as C, I1 as I, E1 as E, D1 as D, M1 as M, N1 as N, >v : number >f1 : () => void >f : () => void ->C1 : typeof C ->C : typeof C +>C1 : typeof import("tests/cases/conformance/es6/modules/t1").C +>C : typeof import("tests/cases/conformance/es6/modules/t1").C >I1 : any >I : any ->E1 : typeof E ->E : typeof E ->D1 : typeof D ->D : typeof D ->M1 : typeof M ->M : typeof M +>E1 : typeof import("tests/cases/conformance/es6/modules/t1").E +>E : typeof import("tests/cases/conformance/es6/modules/t1").E +>D1 : typeof import("tests/cases/conformance/es6/modules/t1").D +>D : typeof import("tests/cases/conformance/es6/modules/t1").D +>M1 : typeof import("tests/cases/conformance/es6/modules/t1").M +>M : typeof import("tests/cases/conformance/es6/modules/t1").M >N1 : any >N : any >T1 : any diff --git a/tests/baselines/reference/exportsAndImports3-es6.symbols b/tests/baselines/reference/exportsAndImports3-es6.symbols index edc5d5c2e4e..f71014281c2 100644 --- a/tests/baselines/reference/exportsAndImports3-es6.symbols +++ b/tests/baselines/reference/exportsAndImports3-es6.symbols @@ -15,17 +15,17 @@ export enum E { >E : Symbol(E, Decl(t1.ts, 5, 1)) A, B, C ->A : Symbol(E1.A, Decl(t1.ts, 6, 15)) ->B : Symbol(E1.B, Decl(t1.ts, 7, 6)) ->C : Symbol(E1.C, Decl(t1.ts, 7, 9)) +>A : Symbol(E.A, Decl(t1.ts, 6, 15)) +>B : Symbol(E.B, Decl(t1.ts, 7, 6)) +>C : Symbol(E.C, Decl(t1.ts, 7, 9)) } export const enum D { >D : Symbol(D, Decl(t1.ts, 8, 1)) A, B, C ->A : Symbol(D1.A, Decl(t1.ts, 9, 21)) ->B : Symbol(D1.B, Decl(t1.ts, 10, 6)) ->C : Symbol(D1.C, Decl(t1.ts, 10, 9)) +>A : Symbol(D.A, Decl(t1.ts, 9, 21)) +>B : Symbol(D.B, Decl(t1.ts, 10, 6)) +>C : Symbol(D.C, Decl(t1.ts, 10, 9)) } export module M { >M : Symbol(M, Decl(t1.ts, 11, 1)) diff --git a/tests/baselines/reference/exportsAndImports3-es6.types b/tests/baselines/reference/exportsAndImports3-es6.types index a8357a4db22..8a021f7a009 100644 --- a/tests/baselines/reference/exportsAndImports3-es6.types +++ b/tests/baselines/reference/exportsAndImports3-es6.types @@ -73,16 +73,16 @@ export { v1 as v, f1 as f, C1 as C, I1 as I, E1 as E, D1 as D, M1 as M, N1 as N, >v : number >f1 : () => void >f : () => void ->C1 : typeof C ->C : typeof C +>C1 : typeof import("tests/cases/conformance/es6/modules/t1").C +>C : typeof import("tests/cases/conformance/es6/modules/t1").C >I1 : any >I : any ->E1 : typeof E ->E : typeof E ->D1 : typeof D ->D : typeof D ->M1 : typeof M ->M : typeof M +>E1 : typeof import("tests/cases/conformance/es6/modules/t1").E +>E : typeof import("tests/cases/conformance/es6/modules/t1").E +>D1 : typeof import("tests/cases/conformance/es6/modules/t1").D +>D : typeof import("tests/cases/conformance/es6/modules/t1").D +>M1 : typeof import("tests/cases/conformance/es6/modules/t1").M +>M : typeof import("tests/cases/conformance/es6/modules/t1").M >N1 : any >N : any >T1 : any diff --git a/tests/baselines/reference/exportsAndImports3.symbols b/tests/baselines/reference/exportsAndImports3.symbols index edc5d5c2e4e..f71014281c2 100644 --- a/tests/baselines/reference/exportsAndImports3.symbols +++ b/tests/baselines/reference/exportsAndImports3.symbols @@ -15,17 +15,17 @@ export enum E { >E : Symbol(E, Decl(t1.ts, 5, 1)) A, B, C ->A : Symbol(E1.A, Decl(t1.ts, 6, 15)) ->B : Symbol(E1.B, Decl(t1.ts, 7, 6)) ->C : Symbol(E1.C, Decl(t1.ts, 7, 9)) +>A : Symbol(E.A, Decl(t1.ts, 6, 15)) +>B : Symbol(E.B, Decl(t1.ts, 7, 6)) +>C : Symbol(E.C, Decl(t1.ts, 7, 9)) } export const enum D { >D : Symbol(D, Decl(t1.ts, 8, 1)) A, B, C ->A : Symbol(D1.A, Decl(t1.ts, 9, 21)) ->B : Symbol(D1.B, Decl(t1.ts, 10, 6)) ->C : Symbol(D1.C, Decl(t1.ts, 10, 9)) +>A : Symbol(D.A, Decl(t1.ts, 9, 21)) +>B : Symbol(D.B, Decl(t1.ts, 10, 6)) +>C : Symbol(D.C, Decl(t1.ts, 10, 9)) } export module M { >M : Symbol(M, Decl(t1.ts, 11, 1)) diff --git a/tests/baselines/reference/exportsAndImports3.types b/tests/baselines/reference/exportsAndImports3.types index a8357a4db22..8a021f7a009 100644 --- a/tests/baselines/reference/exportsAndImports3.types +++ b/tests/baselines/reference/exportsAndImports3.types @@ -73,16 +73,16 @@ export { v1 as v, f1 as f, C1 as C, I1 as I, E1 as E, D1 as D, M1 as M, N1 as N, >v : number >f1 : () => void >f : () => void ->C1 : typeof C ->C : typeof C +>C1 : typeof import("tests/cases/conformance/es6/modules/t1").C +>C : typeof import("tests/cases/conformance/es6/modules/t1").C >I1 : any >I : any ->E1 : typeof E ->E : typeof E ->D1 : typeof D ->D : typeof D ->M1 : typeof M ->M : typeof M +>E1 : typeof import("tests/cases/conformance/es6/modules/t1").E +>E : typeof import("tests/cases/conformance/es6/modules/t1").E +>D1 : typeof import("tests/cases/conformance/es6/modules/t1").D +>D : typeof import("tests/cases/conformance/es6/modules/t1").D +>M1 : typeof import("tests/cases/conformance/es6/modules/t1").M +>M : typeof import("tests/cases/conformance/es6/modules/t1").M >N1 : any >N : any >T1 : any diff --git a/tests/baselines/reference/isolatedModulesReExportType.types b/tests/baselines/reference/isolatedModulesReExportType.types index 5c857a16952..55c4cdfb7b7 100644 --- a/tests/baselines/reference/isolatedModulesReExportType.types +++ b/tests/baselines/reference/isolatedModulesReExportType.types @@ -8,7 +8,7 @@ export import T2 = require("./exportEqualsT"); // OK, has a value side export { C } from "./exportValue"; ->C : typeof C +>C : typeof import("/exportValue").C // OK, even though the namespace it exports is only types. import * as NS from "./exportT"; diff --git a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.types b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.types index 1e1f0be5101..fbcc5fa6c43 100644 --- a/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.types +++ b/tests/baselines/reference/moduleSameValueDuplicateExportedBindings2.types @@ -4,7 +4,7 @@ No type information for this code.export * from "./c"; No type information for this code. No type information for this code.=== tests/cases/compiler/b.ts === export {Animals} from "./c"; ->Animals : typeof Animals +>Animals : typeof import("tests/cases/compiler/c").Animals === tests/cases/compiler/c.ts === export enum Animals { diff --git a/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.types b/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.types index 37204b21d09..8d84e2a9d35 100644 --- a/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.types +++ b/tests/baselines/reference/reexportWrittenCorrectlyInDeclaration.types @@ -9,10 +9,10 @@ export class ThingB { } === tests/cases/compiler/Things.ts === export {ThingA} from "./ThingA"; ->ThingA : typeof ThingA +>ThingA : typeof import("tests/cases/compiler/ThingA").ThingA export {ThingB} from "./ThingB"; ->ThingB : typeof ThingB +>ThingB : typeof import("tests/cases/compiler/ThingB").ThingB === tests/cases/compiler/Test.ts === import * as things from "./Things"; diff --git a/tests/baselines/reference/systemNamespaceAliasEmit.symbols b/tests/baselines/reference/systemNamespaceAliasEmit.symbols index 89ac66a624d..7e9c2434586 100644 --- a/tests/baselines/reference/systemNamespaceAliasEmit.symbols +++ b/tests/baselines/reference/systemNamespaceAliasEmit.symbols @@ -10,10 +10,10 @@ enum AnEnum { >AnEnum : Symbol(AnEnum, Decl(systemNamespaceAliasEmit.ts, 2, 1)) ONE, ->ONE : Symbol(BarEnum.ONE, Decl(systemNamespaceAliasEmit.ts, 4, 13)) +>ONE : Symbol(AnEnum.ONE, Decl(systemNamespaceAliasEmit.ts, 4, 13)) TWO ->TWO : Symbol(BarEnum.TWO, Decl(systemNamespaceAliasEmit.ts, 5, 8)) +>TWO : Symbol(AnEnum.TWO, Decl(systemNamespaceAliasEmit.ts, 5, 8)) } export {ns, AnEnum, ns as FooBar, AnEnum as BarEnum}; diff --git a/tests/cases/compiler/declarationEmitExportAliasVisibiilityMarking.ts b/tests/cases/compiler/declarationEmitExportAliasVisibiilityMarking.ts new file mode 100644 index 00000000000..666ea9c2eda --- /dev/null +++ b/tests/cases/compiler/declarationEmitExportAliasVisibiilityMarking.ts @@ -0,0 +1,14 @@ +// @lib: es2015 +// @declaration: true +// @filename: Types.ts +type Suit = 'Hearts' | 'Spades' | 'Clubs' | 'Diamonds'; +type Rank = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 'Jack' | 'Queen' | 'King'; +export { Suit, Rank }; + +// @filename: Card.ts +import { Suit, Rank } from './Types'; +export default (suit: Suit, rank: Rank) => ({suit, rank}); + +// @filename: index.ts +export let lazyCard = () => import('./Card').then(a => a.default); +export { Suit, Rank } from './Types'; From 4ac8976750dcaf3caa5d6424d2ea00eb916feafe Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 4 Sep 2018 16:00:28 -0700 Subject: [PATCH 147/163] Always check index type validity for all types when an error node is present so we always issue an error (#26789) * Always check index type validity for all types when an error node is present so we always issue an error * Change type a bit --- src/compiler/checker.ts | 13 ++++++++++++- .../reference/arrayIndexWithArrayFails.errors.txt | 9 +++++++++ .../reference/arrayIndexWithArrayFails.js | 7 +++++++ .../reference/arrayIndexWithArrayFails.symbols | 12 ++++++++++++ .../reference/arrayIndexWithArrayFails.types | 15 +++++++++++++++ .../keyofAndIndexedAccessErrors.errors.txt | 11 ++++++++++- tests/cases/compiler/arrayIndexWithArrayFails.ts | 3 +++ 7 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/arrayIndexWithArrayFails.errors.txt create mode 100644 tests/baselines/reference/arrayIndexWithArrayFails.js create mode 100644 tests/baselines/reference/arrayIndexWithArrayFails.symbols create mode 100644 tests/baselines/reference/arrayIndexWithArrayFails.types create mode 100644 tests/cases/compiler/arrayIndexWithArrayFails.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 70c7f428951..d1a442e8ecc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9380,13 +9380,24 @@ namespace ts { const apparentObjectType = getApparentType(objectType); if (indexType.flags & TypeFlags.Union && !(indexType.flags & TypeFlags.Boolean)) { const propTypes: Type[] = []; + let wasMissingProp = false; for (const t of (indexType).types) { const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false, missingType); if (propType === missingType) { - return missingType; + if (!accessNode) { + // If there's no error node, we can immeditely stop, since error reporting is off + return missingType; + } + else { + // Otherwise we set a flag and return at the end of the loop so we still mark all errors + wasMissingProp = true; + } } propTypes.push(propType); } + if (wasMissingProp) { + return missingType; + } return getUnionType(propTypes); } return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true, missingType); diff --git a/tests/baselines/reference/arrayIndexWithArrayFails.errors.txt b/tests/baselines/reference/arrayIndexWithArrayFails.errors.txt new file mode 100644 index 00000000000..bfe75e6d79c --- /dev/null +++ b/tests/baselines/reference/arrayIndexWithArrayFails.errors.txt @@ -0,0 +1,9 @@ +tests/cases/compiler/arrayIndexWithArrayFails.ts(3,16): error TS2538: Type 'string[]' cannot be used as an index type. + + +==== tests/cases/compiler/arrayIndexWithArrayFails.ts (1 errors) ==== + declare const arr1: (string | string[])[]; + declare const arr2: number[]; + const j = arr2[arr1[0]]; // should error + ~~~~~~~ +!!! error TS2538: Type 'string[]' cannot be used as an index type. \ No newline at end of file diff --git a/tests/baselines/reference/arrayIndexWithArrayFails.js b/tests/baselines/reference/arrayIndexWithArrayFails.js new file mode 100644 index 00000000000..e5541a50704 --- /dev/null +++ b/tests/baselines/reference/arrayIndexWithArrayFails.js @@ -0,0 +1,7 @@ +//// [arrayIndexWithArrayFails.ts] +declare const arr1: (string | string[])[]; +declare const arr2: number[]; +const j = arr2[arr1[0]]; // should error + +//// [arrayIndexWithArrayFails.js] +var j = arr2[arr1[0]]; // should error diff --git a/tests/baselines/reference/arrayIndexWithArrayFails.symbols b/tests/baselines/reference/arrayIndexWithArrayFails.symbols new file mode 100644 index 00000000000..e389f29fbef --- /dev/null +++ b/tests/baselines/reference/arrayIndexWithArrayFails.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/arrayIndexWithArrayFails.ts === +declare const arr1: (string | string[])[]; +>arr1 : Symbol(arr1, Decl(arrayIndexWithArrayFails.ts, 0, 13)) + +declare const arr2: number[]; +>arr2 : Symbol(arr2, Decl(arrayIndexWithArrayFails.ts, 1, 13)) + +const j = arr2[arr1[0]]; // should error +>j : Symbol(j, Decl(arrayIndexWithArrayFails.ts, 2, 5)) +>arr2 : Symbol(arr2, Decl(arrayIndexWithArrayFails.ts, 1, 13)) +>arr1 : Symbol(arr1, Decl(arrayIndexWithArrayFails.ts, 0, 13)) + diff --git a/tests/baselines/reference/arrayIndexWithArrayFails.types b/tests/baselines/reference/arrayIndexWithArrayFails.types new file mode 100644 index 00000000000..7e9b28f733c --- /dev/null +++ b/tests/baselines/reference/arrayIndexWithArrayFails.types @@ -0,0 +1,15 @@ +=== tests/cases/compiler/arrayIndexWithArrayFails.ts === +declare const arr1: (string | string[])[]; +>arr1 : (string | string[])[] + +declare const arr2: number[]; +>arr2 : number[] + +const j = arr2[arr1[0]]; // should error +>j : any +>arr2[arr1[0]] : any +>arr2 : number[] +>arr1[0] : string | string[] +>arr1 : (string | string[])[] +>0 : 0 + diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 14cfbd1ceab..dd5cbe050a9 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -8,9 +8,12 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(25,18): error tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(26,18): error TS2538: Type 'void' cannot be used as an index type. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(27,18): error TS2538: Type 'undefined' cannot be used as an index type. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(28,18): error TS2538: Type '{ x: string; }' cannot be used as an index type. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'number'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(30,18): error TS2538: Type 'string & number' cannot be used as an index type. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2538: Type 'false' cannot be used as an index type. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2538: Type 'true' cannot be used as an index type. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(35,21): error TS2537: Type 'string[]' has no matching index signature for type 'string'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(36,21): error TS2538: Type 'boolean' cannot be used as an index type. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(41,31): error TS2538: Type 'boolean' cannot be used as an index type. @@ -60,7 +63,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error Type 'T' is not assignable to type 'U'. -==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (33 errors) ==== +==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (36 errors) ==== class Shape { name: string; width: number; @@ -111,6 +114,8 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error !!! error TS2538: Type '{ x: string; }' cannot be used as an index type. type T20 = Shape[string | number]; // Error ~~~~~~~~~~~~~~~ +!!! error TS2537: Type 'Shape' has no matching index signature for type 'number'. + ~~~~~~~~~~~~~~~ !!! error TS2537: Type 'Shape' has no matching index signature for type 'string'. type T21 = Shape[string & number]; // Error ~~~~~~~~~~~~~~~ @@ -118,6 +123,10 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error type T22 = Shape[string | boolean]; // Error ~~~~~~~~~~~~~~~~ !!! error TS2537: Type 'Shape' has no matching index signature for type 'string'. + ~~~~~~~~~~~~~~~~ +!!! error TS2538: Type 'false' cannot be used as an index type. + ~~~~~~~~~~~~~~~~ +!!! error TS2538: Type 'true' cannot be used as an index type. type T30 = string[]["length"]; type T31 = string[][number]; diff --git a/tests/cases/compiler/arrayIndexWithArrayFails.ts b/tests/cases/compiler/arrayIndexWithArrayFails.ts new file mode 100644 index 00000000000..242e1ff3334 --- /dev/null +++ b/tests/cases/compiler/arrayIndexWithArrayFails.ts @@ -0,0 +1,3 @@ +declare const arr1: (string | string[])[]; +declare const arr2: number[]; +const j = arr2[arr1[0]]; // should error \ No newline at end of file From 6e318890feebcefa9852562e218486cff59d43bf Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 5 Sep 2018 10:04:34 -0700 Subject: [PATCH 148/163] Update user baselines (#26888) --- tests/baselines/reference/user/bluebird.log | 47 ++++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/tests/baselines/reference/user/bluebird.log b/tests/baselines/reference/user/bluebird.log index ecb85253f43..35d6d9ca05b 100644 --- a/tests/baselines/reference/user/bluebird.log +++ b/tests/baselines/reference/user/bluebird.log @@ -10,19 +10,23 @@ node_modules/bluebird/js/release/async.js(118,21): error TS2300: Duplicate ident node_modules/bluebird/js/release/bluebird.js(5,15): error TS2367: This condition will always return 'false' since the types 'PromiseConstructor' and 'typeof Promise' have no overlap. node_modules/bluebird/js/release/bluebird.js(10,10): error TS2339: Property 'noConflict' does not exist on type 'typeof Promise'. node_modules/bluebird/js/release/catch_filter.js(27,28): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: {}) => string[]) | ((o: any) => string[])' has no compatible call signatures. -node_modules/bluebird/js/release/debuggability.js(18,20): error TS2367: This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. -node_modules/bluebird/js/release/debuggability.js(23,19): error TS2367: This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. -node_modules/bluebird/js/release/debuggability.js(26,26): error TS2367: This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. -node_modules/bluebird/js/release/debuggability.js(29,24): error TS2367: This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. -node_modules/bluebird/js/release/debuggability.js(160,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'event' must be of type 'CustomEvent', but here has type 'Event'. -node_modules/bluebird/js/release/debuggability.js(166,26): error TS2339: Property 'detail' does not exist on type 'Event'. -node_modules/bluebird/js/release/debuggability.js(476,19): error TS2350: Only a void function can be called with the 'new' keyword. -node_modules/bluebird/js/release/debuggability.js(547,46): error TS2554: Expected 0 arguments, but got 1. -node_modules/bluebird/js/release/debuggability.js(721,5): error TS2721: Cannot invoke an object which is possibly 'null'. -node_modules/bluebird/js/release/debuggability.js(739,30): error TS2339: Property 'stack' does not exist on type 'CapturedTrace'. -node_modules/bluebird/js/release/debuggability.js(745,37): error TS2339: Property 'stack' does not exist on type 'CapturedTrace'. -node_modules/bluebird/js/release/debuggability.js(784,38): error TS2339: Property 'stack' does not exist on type 'CapturedTrace'. -node_modules/bluebird/js/release/debuggability.js(793,25): error TS2554: Expected 0 arguments, but got 1. +node_modules/bluebird/js/release/debuggability.js(19,20): error TS2367: This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. +node_modules/bluebird/js/release/debuggability.js(24,19): error TS2367: This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. +node_modules/bluebird/js/release/debuggability.js(27,26): error TS2367: This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. +node_modules/bluebird/js/release/debuggability.js(30,24): error TS2367: This condition will always return 'true' since the types 'string | undefined' and 'number' have no overlap. +node_modules/bluebird/js/release/debuggability.js(161,17): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any) | ((o: any, key: any, desc: any) => any)' has no compatible call signatures. +node_modules/bluebird/js/release/debuggability.js(163,17): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any) | ((o: any, key: any, desc: any) => any)' has no compatible call signatures. +node_modules/bluebird/js/release/debuggability.js(168,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'event' must be of type 'CustomEvent', but here has type 'Event'. +node_modules/bluebird/js/release/debuggability.js(174,26): error TS2339: Property 'detail' does not exist on type 'Event'. +node_modules/bluebird/js/release/debuggability.js(175,17): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any) | ((o: any, key: any, desc: any) => any)' has no compatible call signatures. +node_modules/bluebird/js/release/debuggability.js(176,17): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any) | ((o: any, key: any, desc: any) => any)' has no compatible call signatures. +node_modules/bluebird/js/release/debuggability.js(491,19): error TS2350: Only a void function can be called with the 'new' keyword. +node_modules/bluebird/js/release/debuggability.js(562,46): error TS2554: Expected 0 arguments, but got 1. +node_modules/bluebird/js/release/debuggability.js(736,5): error TS2721: Cannot invoke an object which is possibly 'null'. +node_modules/bluebird/js/release/debuggability.js(754,30): error TS2339: Property 'stack' does not exist on type 'CapturedTrace'. +node_modules/bluebird/js/release/debuggability.js(760,37): error TS2339: Property 'stack' does not exist on type 'CapturedTrace'. +node_modules/bluebird/js/release/debuggability.js(799,38): error TS2339: Property 'stack' does not exist on type 'CapturedTrace'. +node_modules/bluebird/js/release/debuggability.js(808,25): error TS2554: Expected 0 arguments, but got 1. node_modules/bluebird/js/release/errors.js(10,49): error TS2350: Only a void function can be called with the 'new' keyword. node_modules/bluebird/js/release/errors.js(46,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any) | ((o: any, key: any, desc: any) => any)' has no compatible call signatures. node_modules/bluebird/js/release/errors.js(92,18): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{ (a: T[]): ReadonlyArray; (f: T): T; (o: T): Readonly; } | ((obj: any) => any)' has no compatible call signatures. @@ -82,8 +86,9 @@ node_modules/bluebird/js/release/promise.js(483,18): error TS2339: Property '_ex node_modules/bluebird/js/release/promise.js(489,10): error TS2339: Property '_popContext' does not exist on type 'Promise'. node_modules/bluebird/js/release/promise.js(506,19): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. node_modules/bluebird/js/release/promise.js(630,14): error TS2339: Property '_attachExtraTrace' does not exist on type 'Promise'. -node_modules/bluebird/js/release/promise.js(658,14): error TS2339: Property '_ensurePossibleRejectionHandled' does not exist on type 'Promise'. -node_modules/bluebird/js/release/promise.js(698,10): error TS2339: Property '_clearCancellationData' does not exist on type 'Promise'. +node_modules/bluebird/js/release/promise.js(642,14): error TS2339: Property '_dereferenceTrace' does not exist on type 'Promise'. +node_modules/bluebird/js/release/promise.js(659,14): error TS2339: Property '_ensurePossibleRejectionHandled' does not exist on type 'Promise'. +node_modules/bluebird/js/release/promise.js(699,10): error TS2339: Property '_clearCancellationData' does not exist on type 'Promise'. node_modules/bluebird/js/release/promise_array.js(71,18): error TS2339: Property '_resolveEmptyArray' does not exist on type 'PromiseArray'. node_modules/bluebird/js/release/promise_array.js(109,30): error TS2554: Expected 0-1 arguments, but got 2. node_modules/bluebird/js/release/promise_array.js(111,30): error TS2554: Expected 0 arguments, but got 1. @@ -156,12 +161,12 @@ node_modules/bluebird/js/release/using.js(78,20): error TS2339: Property 'doDisp node_modules/bluebird/js/release/using.js(97,23): error TS2339: Property 'data' does not exist on type 'FunctionDisposer'. node_modules/bluebird/js/release/using.js(223,15): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. node_modules/bluebird/js/release/util.js(97,5): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any) | ((o: any, key: any, desc: any) => any)' has no compatible call signatures. -node_modules/bluebird/js/release/util.js(247,28): error TS2554: Expected 0 arguments, but got 2. -node_modules/bluebird/js/release/util.js(275,17): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any) | ((o: any, key: any, desc: any) => any)' has no compatible call signatures. -node_modules/bluebird/js/release/util.js(275,45): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol) => PropertyDescriptor | undefined) | ((o: any, key: any) => { value: any; })' has no compatible call signatures. -node_modules/bluebird/js/release/util.js(363,25): error TS2304: Cannot find name 'chrome'. -node_modules/bluebird/js/release/util.js(363,51): error TS2304: Cannot find name 'chrome'. -node_modules/bluebird/js/release/util.js(364,25): error TS2304: Cannot find name 'chrome'. +node_modules/bluebird/js/release/util.js(251,28): error TS2554: Expected 0 arguments, but got 2. +node_modules/bluebird/js/release/util.js(279,17): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any) | ((o: any, key: any, desc: any) => any)' has no compatible call signatures. +node_modules/bluebird/js/release/util.js(279,45): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((o: any, p: string | number | symbol) => PropertyDescriptor | undefined) | ((o: any, key: any) => { value: any; })' has no compatible call signatures. +node_modules/bluebird/js/release/util.js(367,25): error TS2304: Cannot find name 'chrome'. +node_modules/bluebird/js/release/util.js(367,51): error TS2304: Cannot find name 'chrome'. +node_modules/bluebird/js/release/util.js(368,25): error TS2304: Cannot find name 'chrome'. From ff05082e45a4ffe7e2dc31b9a4243350f98243cf Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 5 Sep 2018 10:53:43 -0700 Subject: [PATCH 149/163] Bind non-expando property assignments at top-level (#26908) * Bind non-expando property assignments at toplevel Previously, only property assignments with expando initialisers were bound in top-level statements. Now, all property assignments are bound. This requires a matching change in the checker to make sure that these assignments remain context sensitive if their valueDeclaration is a 'real' declaration (ie a non assignment-declaration). * Add baselines for new test --- src/compiler/binder.ts | 9 ++- src/compiler/checker.ts | 2 +- ...checkJsdocTypeTagOnObjectProperty1.symbols | 14 ++-- .../classCanExtendConstructorFunction.symbols | 6 +- .../reference/constructorFunctions3.symbols | 14 ++-- .../constructorFunctionsStrict.symbols | 6 +- .../contextualTypedSpecialAssignment.symbols | 8 +-- .../contextualTypedSpecialAssignment.types | 8 +-- .../expandoFunctionContextualTypes.symbols | 4 +- .../expandoFunctionContextualTypesJs.symbols | 10 +-- ...gClassStaticMembersFromAssignments.symbols | 56 ++++++++-------- ...ingClassStaticMembersFromAssignments.types | 14 ++-- .../jsObjectsMarkedAsOpenEnded.symbols | 12 ++-- .../jsObjectsMarkedAsOpenEnded.types | 6 +- .../reference/jsdocTemplateClass.symbols | 4 +- .../jsdocTemplateConstructorFunction.symbols | 6 +- .../jsdocTemplateConstructorFunction2.symbols | 6 +- .../jsdocTypeFromChainedAssignment.symbols | 8 +-- .../reference/moduleExportAlias5.symbols | 6 +- ...xportWithExportPropertyAssignment4.symbols | 10 +-- ...pertyAssignmentOnImportedSymbol.errors.txt | 11 ++++ ...propertyAssignmentOnImportedSymbol.symbols | 6 +- .../propertyAssignmentOnImportedSymbol.types | 8 +-- .../reference/targetTypeTest1.errors.txt | 8 +-- .../reference/targetTypeTest1.symbols | 16 +++-- .../baselines/reference/targetTypeTest1.types | 14 ++-- .../reference/typeFromJSInitializer.symbols | 26 ++++---- .../typeFromPropertyAssignment17.symbols | 10 +-- .../typeFromPropertyAssignment17.types | 28 ++++---- .../typeFromPropertyAssignment18.symbols | 34 +++++----- .../typeFromPropertyAssignment18.types | 36 +++++------ .../typeFromPropertyAssignment22.symbols | 6 +- .../typeFromPropertyAssignment29.symbols | 64 +++++++++---------- .../typeFromPropertyAssignment29.types | 4 +- .../typeFromPropertyAssignment31.symbols | 44 ++++++------- .../typeFromPropertyAssignment32.symbols | 44 ++++++------- .../typeFromPropertyAssignment33.symbols | 44 ++++++------- .../typeFromPropertyAssignment34.symbols | 24 +++++++ .../typeFromPropertyAssignment34.types | 31 +++++++++ .../salsa/typeFromPropertyAssignment34.ts | 10 +++ tests/cases/fourslash/functionTypes.ts | 8 ++- ...eferencesForStringLiteralPropertyNames7.ts | 2 +- 42 files changed, 383 insertions(+), 304 deletions(-) create mode 100644 tests/baselines/reference/propertyAssignmentOnImportedSymbol.errors.txt create mode 100644 tests/baselines/reference/typeFromPropertyAssignment34.symbols create mode 100644 tests/baselines/reference/typeFromPropertyAssignment34.types create mode 100644 tests/cases/conformance/salsa/typeFromPropertyAssignment34.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 9c7756d0d30..1fe5605b498 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2512,11 +2512,10 @@ namespace ts { function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) { let namespaceSymbol = lookupSymbolForPropertyAccess(name); - const isToplevelNamespaceableInitializer = isBinaryExpression(propertyAccess.parent) - ? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile && - !!getJavascriptInitializer(getInitializerOfBinaryExpression(propertyAccess.parent), isPrototypeAccess(propertyAccess.parent.left)) + const isToplevel = isBinaryExpression(propertyAccess.parent) + ? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile : propertyAccess.parent.parent.kind === SyntaxKind.SourceFile; - if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevelNamespaceableInitializer) { + if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevel) { // make symbols or add declarations for intermediate containers const flags = SymbolFlags.Module | SymbolFlags.JSContainer; const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer; @@ -2573,7 +2572,7 @@ namespace ts { return false; } - function getParentOfBinaryExpression(expr: BinaryExpression) { + function getParentOfBinaryExpression(expr: Node) { while (isBinaryExpression(expr.parent)) { expr = expr.parent; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d1a442e8ecc..ec880fc0cc4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16189,7 +16189,7 @@ namespace ts { else if (isIdentifier(lhs.expression)) { const id = lhs.expression; const parentSymbol = resolveName(id, id.escapedText, SymbolFlags.Value, undefined, id.escapedText, /*isUse*/ true); - if (parentSymbol && isFunctionSymbol(parentSymbol)) { + if (parentSymbol) { const annotated = getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration); if (annotated) { const type = getTypeOfPropertyOfContextualType(getTypeFromTypeNode(annotated), lhs.name.escapedText); diff --git a/tests/baselines/reference/checkJsdocTypeTagOnObjectProperty1.symbols b/tests/baselines/reference/checkJsdocTypeTagOnObjectProperty1.symbols index 24d39dce20a..68693872a4b 100644 --- a/tests/baselines/reference/checkJsdocTypeTagOnObjectProperty1.symbols +++ b/tests/baselines/reference/checkJsdocTypeTagOnObjectProperty1.symbols @@ -4,7 +4,7 @@ var lol = "hello Lol" >lol : Symbol(lol, Decl(0.js, 1, 3)) const obj = { ->obj : Symbol(obj, Decl(0.js, 2, 5)) +>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1)) /** @type {string|undefined} */ foo: undefined, @@ -40,31 +40,31 @@ const obj = { } obj.foo = 'string' >obj.foo : Symbol(foo, Decl(0.js, 2, 13)) ->obj : Symbol(obj, Decl(0.js, 2, 5)) +>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1)) >foo : Symbol(foo, Decl(0.js, 2, 13)) obj.lol >obj.lol : Symbol(lol, Decl(0.js, 10, 4)) ->obj : Symbol(obj, Decl(0.js, 2, 5)) +>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1)) >lol : Symbol(lol, Decl(0.js, 10, 4)) obj.bar = undefined; >obj.bar : Symbol(bar, Decl(0.js, 4, 17)) ->obj : Symbol(obj, Decl(0.js, 2, 5)) +>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1)) >bar : Symbol(bar, Decl(0.js, 4, 17)) >undefined : Symbol(undefined) var k = obj.method1(0); >k : Symbol(k, Decl(0.js, 21, 3)) >obj.method1 : Symbol(method1, Decl(0.js, 6, 12)) ->obj : Symbol(obj, Decl(0.js, 2, 5)) +>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1)) >method1 : Symbol(method1, Decl(0.js, 6, 12)) obj.bar1 = "42"; ->obj : Symbol(obj, Decl(0.js, 2, 5)) +>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1)) obj.arrowFunc(0); >obj.arrowFunc : Symbol(arrowFunc, Decl(0.js, 14, 20)) ->obj : Symbol(obj, Decl(0.js, 2, 5)) +>obj : Symbol(obj, Decl(0.js, 2, 5), Decl(0.js, 17, 1)) >arrowFunc : Symbol(arrowFunc, Decl(0.js, 14, 20)) diff --git a/tests/baselines/reference/classCanExtendConstructorFunction.symbols b/tests/baselines/reference/classCanExtendConstructorFunction.symbols index 58aae6eee07..2a794718f4c 100644 --- a/tests/baselines/reference/classCanExtendConstructorFunction.symbols +++ b/tests/baselines/reference/classCanExtendConstructorFunction.symbols @@ -107,15 +107,15 @@ class Sql extends Wagon { } } var db = new Sql(); ->db : Symbol(db, Decl(first.js, 42, 3)) +>db : Symbol(db, Decl(first.js, 42, 3), Decl(first.js, 42, 19)) >Sql : Symbol(Sql, Decl(first.js, 18, 1)) db.numberOxen = db.foonly >db.numberOxen : Symbol(Wagon.numberOxen, Decl(first.js, 4, 28)) ->db : Symbol(db, Decl(first.js, 42, 3)) +>db : Symbol(db, Decl(first.js, 42, 3), Decl(first.js, 42, 19)) >numberOxen : Symbol(Wagon.numberOxen, Decl(first.js, 4, 28)) >db.foonly : Symbol(Sql.foonly, Decl(first.js, 22, 16)) ->db : Symbol(db, Decl(first.js, 42, 3)) +>db : Symbol(db, Decl(first.js, 42, 3), Decl(first.js, 42, 19)) >foonly : Symbol(Sql.foonly, Decl(first.js, 22, 16)) // error, can't extend a TS constructor function diff --git a/tests/baselines/reference/constructorFunctions3.symbols b/tests/baselines/reference/constructorFunctions3.symbols index 7c98cd921e0..385ae3d1be2 100644 --- a/tests/baselines/reference/constructorFunctions3.symbols +++ b/tests/baselines/reference/constructorFunctions3.symbols @@ -16,25 +16,25 @@ i; >i : Symbol(i, Decl(a.js, 3, 3)) function StaticToo() { ->StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2)) +>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2), Decl(a.js, 9, 1)) this.i = 'more complex' >i : Symbol(StaticToo.i, Decl(a.js, 7, 22)) } StaticToo.property = 'yep' >StaticToo.property : Symbol(StaticToo.property, Decl(a.js, 9, 1)) ->StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2)) +>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2), Decl(a.js, 9, 1)) >property : Symbol(StaticToo.property, Decl(a.js, 9, 1)) var s = new StaticToo(); >s : Symbol(s, Decl(a.js, 11, 3)) ->StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2)) +>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2), Decl(a.js, 9, 1)) s; >s : Symbol(s, Decl(a.js, 11, 3)) StaticToo; ->StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2)) +>StaticToo : Symbol(StaticToo, Decl(a.js, 5, 2), Decl(a.js, 9, 1)) // Both! function A () { @@ -74,12 +74,12 @@ A.t = function g(m) { >m : Symbol(m, Decl(a.js, 26, 17)) } var a = new A() ->a : Symbol(a, Decl(a.js, 29, 3)) +>a : Symbol(a, Decl(a.js, 29, 3), Decl(a.js, 31, 6)) >A : Symbol(A, Decl(a.js, 13, 10), Decl(a.js, 24, 1)) a.z(3) >a.z : Symbol(A.z, Decl(a.js, 20, 1)) ->a : Symbol(a, Decl(a.js, 29, 3)) +>a : Symbol(a, Decl(a.js, 29, 3), Decl(a.js, 31, 6)) >z : Symbol(A.z, Decl(a.js, 20, 1)) A.t(2) @@ -89,6 +89,6 @@ A.t(2) a.second = 1 >a.second : Symbol(A.second, Decl(a.js, 17, 14)) ->a : Symbol(a, Decl(a.js, 29, 3)) +>a : Symbol(a, Decl(a.js, 29, 3), Decl(a.js, 31, 6)) >second : Symbol(A.second, Decl(a.js, 17, 14)) diff --git a/tests/baselines/reference/constructorFunctionsStrict.symbols b/tests/baselines/reference/constructorFunctionsStrict.symbols index 4c5d47b7a51..3954e2ce1e6 100644 --- a/tests/baselines/reference/constructorFunctionsStrict.symbols +++ b/tests/baselines/reference/constructorFunctionsStrict.symbols @@ -20,18 +20,18 @@ C.prototype.m = function() { >y : Symbol(C.y, Decl(a.js, 4, 28)) } var c = new C(1) ->c : Symbol(c, Decl(a.js, 7, 3)) +>c : Symbol(c, Decl(a.js, 7, 3), Decl(a.js, 7, 16)) >C : Symbol(C, Decl(a.js, 0, 0)) c.x = undefined // should error >c.x : Symbol(C.x, Decl(a.js, 1, 15)) ->c : Symbol(c, Decl(a.js, 7, 3)) +>c : Symbol(c, Decl(a.js, 7, 3), Decl(a.js, 7, 16)) >x : Symbol(C.x, Decl(a.js, 1, 15)) >undefined : Symbol(undefined) c.y = undefined // ok >c.y : Symbol(C.y, Decl(a.js, 4, 28)) ->c : Symbol(c, Decl(a.js, 7, 3)) +>c : Symbol(c, Decl(a.js, 7, 3), Decl(a.js, 7, 16)) >y : Symbol(C.y, Decl(a.js, 4, 28)) >undefined : Symbol(undefined) diff --git a/tests/baselines/reference/contextualTypedSpecialAssignment.symbols b/tests/baselines/reference/contextualTypedSpecialAssignment.symbols index ae22cf020da..01ba1d6ba79 100644 --- a/tests/baselines/reference/contextualTypedSpecialAssignment.symbols +++ b/tests/baselines/reference/contextualTypedSpecialAssignment.symbols @@ -6,12 +6,12 @@ // property assignment var ns = {} ->ns : Symbol(ns, Decl(test.js, 6, 3)) +>ns : Symbol(ns, Decl(test.js, 6, 3), Decl(test.js, 6, 11)) /** @type {DoneStatus} */ ns.x = { >ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1)) ->ns : Symbol(ns, Decl(test.js, 6, 3)) +>ns : Symbol(ns, Decl(test.js, 6, 3), Decl(test.js, 6, 11)) >x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1)) status: 'done', @@ -24,7 +24,7 @@ ns.x = { ns.x = { >ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1)) ->ns : Symbol(ns, Decl(test.js, 6, 3)) +>ns : Symbol(ns, Decl(test.js, 6, 3), Decl(test.js, 6, 11)) >x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1)) status: 'done', @@ -36,7 +36,7 @@ ns.x = { } ns.x >ns.x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1)) ->ns : Symbol(ns, Decl(test.js, 6, 3)) +>ns : Symbol(ns, Decl(test.js, 6, 3), Decl(test.js, 6, 11)) >x : Symbol(ns.x, Decl(test.js, 6, 11), Decl(test.js, 11, 1)) diff --git a/tests/baselines/reference/contextualTypedSpecialAssignment.types b/tests/baselines/reference/contextualTypedSpecialAssignment.types index 31865449ae3..2788df859cf 100644 --- a/tests/baselines/reference/contextualTypedSpecialAssignment.types +++ b/tests/baselines/reference/contextualTypedSpecialAssignment.types @@ -6,14 +6,14 @@ // property assignment var ns = {} ->ns : { x: { status: "done"; m(n: number): void; }; } +>ns : typeof ns >{} : {} /** @type {DoneStatus} */ ns.x = { >ns.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; } >ns.x : { status: "done"; m(n: number): void; } ->ns : { x: { status: "done"; m(n: number): void; }; } +>ns : typeof ns >x : { status: "done"; m(n: number): void; } >{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; } @@ -29,7 +29,7 @@ ns.x = { ns.x = { >ns.x = { status: 'done', m(n) { }} : { status: "done"; m(n: number): void; } >ns.x : { status: "done"; m(n: number): void; } ->ns : { x: { status: "done"; m(n: number): void; }; } +>ns : typeof ns >x : { status: "done"; m(n: number): void; } >{ status: 'done', m(n) { }} : { status: "done"; m(n: number): void; } @@ -43,7 +43,7 @@ ns.x = { } ns.x >ns.x : { status: "done"; m(n: number): void; } ->ns : { x: { status: "done"; m(n: number): void; }; } +>ns : typeof ns >x : { status: "done"; m(n: number): void; } diff --git a/tests/baselines/reference/expandoFunctionContextualTypes.symbols b/tests/baselines/reference/expandoFunctionContextualTypes.symbols index cea0647c762..38c87d1e941 100644 --- a/tests/baselines/reference/expandoFunctionContextualTypes.symbols +++ b/tests/baselines/reference/expandoFunctionContextualTypes.symbols @@ -18,13 +18,13 @@ interface StatelessComponent

{ } const MyComponent: StatelessComponent = () => null as any; ->MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5)) +>MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5), Decl(expandoFunctionContextualTypes.ts, 9, 76)) >StatelessComponent : Symbol(StatelessComponent, Decl(expandoFunctionContextualTypes.ts, 2, 1)) >MyComponentProps : Symbol(MyComponentProps, Decl(expandoFunctionContextualTypes.ts, 0, 0)) MyComponent.defaultProps = { >MyComponent.defaultProps : Symbol(StatelessComponent.defaultProps, Decl(expandoFunctionContextualTypes.ts, 5, 12)) ->MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5)) +>MyComponent : Symbol(MyComponent, Decl(expandoFunctionContextualTypes.ts, 9, 5), Decl(expandoFunctionContextualTypes.ts, 9, 76)) >defaultProps : Symbol(StatelessComponent.defaultProps, Decl(expandoFunctionContextualTypes.ts, 5, 12)) color: "red" diff --git a/tests/baselines/reference/expandoFunctionContextualTypesJs.symbols b/tests/baselines/reference/expandoFunctionContextualTypesJs.symbols index 5ef7acd5366..bf0b71f5664 100644 --- a/tests/baselines/reference/expandoFunctionContextualTypesJs.symbols +++ b/tests/baselines/reference/expandoFunctionContextualTypesJs.symbols @@ -9,11 +9,11 @@ * @type {StatelessComponent} */ const MyComponent = () => /* @type {any} */(null); ->MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5)) +>MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5), Decl(input.js, 9, 50)) MyComponent.defaultProps = { >MyComponent.defaultProps : Symbol(defaultProps, Decl(input.js, 4, 23)) ->MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5)) +>MyComponent : Symbol(MyComponent, Decl(input.js, 9, 5), Decl(input.js, 9, 50)) >defaultProps : Symbol(defaultProps, Decl(input.js, 4, 23)) color: "red" @@ -22,14 +22,14 @@ MyComponent.defaultProps = { }; const MyComponent2 = () => null; ->MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5)) +>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5), Decl(input.js, 15, 32)) /** * @type {MyComponentProps} */ MyComponent2.defaultProps = { >MyComponent2.defaultProps : Symbol(MyComponent2.defaultProps, Decl(input.js, 15, 32)) ->MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5)) +>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5), Decl(input.js, 15, 32)) >defaultProps : Symbol(MyComponent2.defaultProps, Decl(input.js, 15, 32)) color: "red" @@ -41,7 +41,7 @@ MyComponent2.defaultProps = { */ const check = MyComponent2; >check : Symbol(check, Decl(input.js, 27, 5)) ->MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5)) +>MyComponent2 : Symbol(MyComponent2, Decl(input.js, 15, 5), Decl(input.js, 15, 32)) /** * diff --git a/tests/baselines/reference/inferringClassStaticMembersFromAssignments.symbols b/tests/baselines/reference/inferringClassStaticMembersFromAssignments.symbols index 1c82d05c019..a643fbfba9e 100644 --- a/tests/baselines/reference/inferringClassStaticMembersFromAssignments.symbols +++ b/tests/baselines/reference/inferringClassStaticMembersFromAssignments.symbols @@ -1,67 +1,67 @@ === tests/cases/conformance/salsa/a.js === export class C1 { } ->C1 : Symbol(C1, Decl(a.js, 0, 0)) +>C1 : Symbol(C1, Decl(a.js, 0, 0), Decl(a.js, 0, 19)) C1.staticProp = 0; >C1.staticProp : Symbol(C1.staticProp, Decl(a.js, 0, 19)) ->C1 : Symbol(C1, Decl(a.js, 0, 0)) +>C1 : Symbol(C1, Decl(a.js, 0, 0), Decl(a.js, 0, 19)) >staticProp : Symbol(C1.staticProp, Decl(a.js, 0, 19)) export function F1() { } ->F1 : Symbol(F1, Decl(a.js, 1, 18)) +>F1 : Symbol(F1, Decl(a.js, 1, 18), Decl(a.js, 3, 24)) F1.staticProp = 0; >F1.staticProp : Symbol(F1.staticProp, Decl(a.js, 3, 24)) ->F1 : Symbol(F1, Decl(a.js, 1, 18)) +>F1 : Symbol(F1, Decl(a.js, 1, 18), Decl(a.js, 3, 24)) >staticProp : Symbol(F1.staticProp, Decl(a.js, 3, 24)) export var C2 = class { }; ->C2 : Symbol(C2, Decl(a.js, 6, 10)) +>C2 : Symbol(C2, Decl(a.js, 6, 10), Decl(a.js, 6, 26)) C2.staticProp = 0; >C2.staticProp : Symbol(C2.staticProp, Decl(a.js, 6, 26)) ->C2 : Symbol(C2, Decl(a.js, 6, 10)) +>C2 : Symbol(C2, Decl(a.js, 6, 10), Decl(a.js, 6, 26)) >staticProp : Symbol(C2.staticProp, Decl(a.js, 6, 26)) export let F2 = function () { }; ->F2 : Symbol(F2, Decl(a.js, 9, 10)) +>F2 : Symbol(F2, Decl(a.js, 9, 10), Decl(a.js, 9, 32)) F2.staticProp = 0; >F2.staticProp : Symbol(F2.staticProp, Decl(a.js, 9, 32)) ->F2 : Symbol(F2, Decl(a.js, 9, 10)) +>F2 : Symbol(F2, Decl(a.js, 9, 10), Decl(a.js, 9, 32)) >staticProp : Symbol(F2.staticProp, Decl(a.js, 9, 32)) === tests/cases/conformance/salsa/global.js === class C3 { } ->C3 : Symbol(C3, Decl(global.js, 0, 0)) +>C3 : Symbol(C3, Decl(global.js, 0, 0), Decl(global.js, 0, 12)) C3.staticProp = 0; >C3.staticProp : Symbol(C3.staticProp, Decl(global.js, 0, 12)) ->C3 : Symbol(C3, Decl(global.js, 0, 0)) +>C3 : Symbol(C3, Decl(global.js, 0, 0), Decl(global.js, 0, 12)) >staticProp : Symbol(C3.staticProp, Decl(global.js, 0, 12)) function F3() { } ->F3 : Symbol(F3, Decl(global.js, 1, 18)) +>F3 : Symbol(F3, Decl(global.js, 1, 18), Decl(global.js, 3, 17)) F3.staticProp = 0; >F3.staticProp : Symbol(F3.staticProp, Decl(global.js, 3, 17)) ->F3 : Symbol(F3, Decl(global.js, 1, 18)) +>F3 : Symbol(F3, Decl(global.js, 1, 18), Decl(global.js, 3, 17)) >staticProp : Symbol(F3.staticProp, Decl(global.js, 3, 17)) var C4 = class { }; ->C4 : Symbol(C4, Decl(global.js, 6, 3)) +>C4 : Symbol(C4, Decl(global.js, 6, 3), Decl(global.js, 6, 19)) C4.staticProp = 0; >C4.staticProp : Symbol(C4.staticProp, Decl(global.js, 6, 19)) ->C4 : Symbol(C4, Decl(global.js, 6, 3)) +>C4 : Symbol(C4, Decl(global.js, 6, 3), Decl(global.js, 6, 19)) >staticProp : Symbol(C4.staticProp, Decl(global.js, 6, 19)) let F4 = function () { }; ->F4 : Symbol(F4, Decl(global.js, 9, 3)) +>F4 : Symbol(F4, Decl(global.js, 9, 3), Decl(global.js, 9, 25)) F4.staticProp = 0; >F4.staticProp : Symbol(F4.staticProp, Decl(global.js, 9, 25)) ->F4 : Symbol(F4, Decl(global.js, 9, 3)) +>F4 : Symbol(F4, Decl(global.js, 9, 3), Decl(global.js, 9, 25)) >staticProp : Symbol(F4.staticProp, Decl(global.js, 9, 25)) === tests/cases/conformance/salsa/b.ts === @@ -74,57 +74,57 @@ var n: number; var n = a.C1.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) >a.C1.staticProp : Symbol(a.C1.staticProp, Decl(a.js, 0, 19)) ->a.C1 : Symbol(a.C1, Decl(a.js, 0, 0)) +>a.C1 : Symbol(a.C1, Decl(a.js, 0, 0), Decl(a.js, 0, 19)) >a : Symbol(a, Decl(b.ts, 0, 6)) ->C1 : Symbol(a.C1, Decl(a.js, 0, 0)) +>C1 : Symbol(a.C1, Decl(a.js, 0, 0), Decl(a.js, 0, 19)) >staticProp : Symbol(a.C1.staticProp, Decl(a.js, 0, 19)) var n = a.C2.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) >a.C2.staticProp : Symbol(a.C2.staticProp, Decl(a.js, 6, 26)) ->a.C2 : Symbol(a.C2, Decl(a.js, 6, 10)) +>a.C2 : Symbol(a.C2, Decl(a.js, 6, 10), Decl(a.js, 6, 26)) >a : Symbol(a, Decl(b.ts, 0, 6)) ->C2 : Symbol(a.C2, Decl(a.js, 6, 10)) +>C2 : Symbol(a.C2, Decl(a.js, 6, 10), Decl(a.js, 6, 26)) >staticProp : Symbol(a.C2.staticProp, Decl(a.js, 6, 26)) var n = a.F1.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) >a.F1.staticProp : Symbol(a.F1.staticProp, Decl(a.js, 3, 24)) ->a.F1 : Symbol(a.F1, Decl(a.js, 1, 18)) +>a.F1 : Symbol(a.F1, Decl(a.js, 1, 18), Decl(a.js, 3, 24)) >a : Symbol(a, Decl(b.ts, 0, 6)) ->F1 : Symbol(a.F1, Decl(a.js, 1, 18)) +>F1 : Symbol(a.F1, Decl(a.js, 1, 18), Decl(a.js, 3, 24)) >staticProp : Symbol(a.F1.staticProp, Decl(a.js, 3, 24)) var n = a.F2.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) >a.F2.staticProp : Symbol(a.F2.staticProp, Decl(a.js, 9, 32)) ->a.F2 : Symbol(a.F2, Decl(a.js, 9, 10)) +>a.F2 : Symbol(a.F2, Decl(a.js, 9, 10), Decl(a.js, 9, 32)) >a : Symbol(a, Decl(b.ts, 0, 6)) ->F2 : Symbol(a.F2, Decl(a.js, 9, 10)) +>F2 : Symbol(a.F2, Decl(a.js, 9, 10), Decl(a.js, 9, 32)) >staticProp : Symbol(a.F2.staticProp, Decl(a.js, 9, 32)) var n = C3.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) >C3.staticProp : Symbol(C3.staticProp, Decl(global.js, 0, 12)) ->C3 : Symbol(C3, Decl(global.js, 0, 0)) +>C3 : Symbol(C3, Decl(global.js, 0, 0), Decl(global.js, 0, 12)) >staticProp : Symbol(C3.staticProp, Decl(global.js, 0, 12)) var n = C4.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) >C4.staticProp : Symbol(C4.staticProp, Decl(global.js, 6, 19)) ->C4 : Symbol(C4, Decl(global.js, 6, 3)) +>C4 : Symbol(C4, Decl(global.js, 6, 3), Decl(global.js, 6, 19)) >staticProp : Symbol(C4.staticProp, Decl(global.js, 6, 19)) var n = F3.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) >F3.staticProp : Symbol(F3.staticProp, Decl(global.js, 3, 17)) ->F3 : Symbol(F3, Decl(global.js, 1, 18)) +>F3 : Symbol(F3, Decl(global.js, 1, 18), Decl(global.js, 3, 17)) >staticProp : Symbol(F3.staticProp, Decl(global.js, 3, 17)) var n = F4.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) >F4.staticProp : Symbol(F4.staticProp, Decl(global.js, 9, 25)) ->F4 : Symbol(F4, Decl(global.js, 9, 3)) +>F4 : Symbol(F4, Decl(global.js, 9, 3), Decl(global.js, 9, 25)) >staticProp : Symbol(F4.staticProp, Decl(global.js, 9, 25)) diff --git a/tests/baselines/reference/inferringClassStaticMembersFromAssignments.types b/tests/baselines/reference/inferringClassStaticMembersFromAssignments.types index 69dff49724b..c38c61dc2f2 100644 --- a/tests/baselines/reference/inferringClassStaticMembersFromAssignments.types +++ b/tests/baselines/reference/inferringClassStaticMembersFromAssignments.types @@ -10,12 +10,12 @@ C1.staticProp = 0; >0 : 0 export function F1() { } ->F1 : { (): void; staticProp: number; } +>F1 : typeof F1 F1.staticProp = 0; >F1.staticProp = 0 : 0 >F1.staticProp : number ->F1 : { (): void; staticProp: number; } +>F1 : typeof F1 >staticProp : number >0 : 0 @@ -53,12 +53,12 @@ C3.staticProp = 0; >0 : 0 function F3() { } ->F3 : { (): void; staticProp: number; } +>F3 : typeof F3 F3.staticProp = 0; >F3.staticProp = 0 : 0 >F3.staticProp : number ->F3 : { (): void; staticProp: number; } +>F3 : typeof F3 >staticProp : number >0 : 0 @@ -110,9 +110,9 @@ var n = a.C2.staticProp; var n = a.F1.staticProp; >n : number >a.F1.staticProp : number ->a.F1 : { (): void; staticProp: number; } +>a.F1 : typeof a.F1 >a : typeof a ->F1 : { (): void; staticProp: number; } +>F1 : typeof a.F1 >staticProp : number var n = a.F2.staticProp; @@ -139,7 +139,7 @@ var n = C4.staticProp; var n = F3.staticProp; >n : number >F3.staticProp : number ->F3 : { (): void; staticProp: number; } +>F3 : typeof F3 >staticProp : number var n = F4.staticProp; diff --git a/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols b/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols index 231d9fa60b2..9d9f2164845 100644 --- a/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols +++ b/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols @@ -1,10 +1,10 @@ === tests/cases/conformance/salsa/a.js === var variable = {}; ->variable : Symbol(variable, Decl(a.js, 0, 3)) +>variable : Symbol(variable, Decl(a.js, 0, 3), Decl(a.js, 0, 18)) variable.a = 0; >variable.a : Symbol(variable.a, Decl(a.js, 0, 18)) ->variable : Symbol(variable, Decl(a.js, 0, 3)) +>variable : Symbol(variable, Decl(a.js, 0, 3), Decl(a.js, 0, 18)) >a : Symbol(variable.a, Decl(a.js, 0, 18)) class C { @@ -27,7 +27,7 @@ class C { } var obj = { ->obj : Symbol(obj, Decl(a.js, 11, 3)) +>obj : Symbol(obj, Decl(a.js, 11, 3), Decl(a.js, 13, 2)) property: {} >property : Symbol(property, Decl(a.js, 11, 11)) @@ -36,7 +36,7 @@ var obj = { obj.property.a = 0; >obj.property : Symbol(property, Decl(a.js, 11, 11)) ->obj : Symbol(obj, Decl(a.js, 11, 3)) +>obj : Symbol(obj, Decl(a.js, 11, 3), Decl(a.js, 13, 2)) >property : Symbol(property, Decl(a.js, 11, 11)) var arr = [{}]; @@ -52,7 +52,7 @@ function getObj() { === tests/cases/conformance/salsa/b.ts === variable.a = 1; >variable.a : Symbol(variable.a, Decl(a.js, 0, 18)) ->variable : Symbol(variable, Decl(a.js, 0, 3)) +>variable : Symbol(variable, Decl(a.js, 0, 3), Decl(a.js, 0, 18)) >a : Symbol(variable.a, Decl(a.js, 0, 18)) (new C()).member.a = 1; @@ -67,7 +67,7 @@ variable.a = 1; obj.property.a = 1; >obj.property : Symbol(property, Decl(a.js, 11, 11)) ->obj : Symbol(obj, Decl(a.js, 11, 3)) +>obj : Symbol(obj, Decl(a.js, 11, 3), Decl(a.js, 13, 2)) >property : Symbol(property, Decl(a.js, 11, 11)) arr[0].a = 1; diff --git a/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.types b/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.types index c30a5e99b2a..996165537bc 100644 --- a/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.types +++ b/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.types @@ -1,12 +1,12 @@ === tests/cases/conformance/salsa/a.js === var variable = {}; ->variable : { a: number; } +>variable : typeof variable >{} : {} variable.a = 0; >variable.a = 0 : 0 >variable.a : number ->variable : { a: number; } +>variable : typeof variable >a : number >0 : 0 @@ -72,7 +72,7 @@ function getObj() { variable.a = 1; >variable.a = 1 : 1 >variable.a : number ->variable : { a: number; } +>variable : typeof variable >a : number >1 : 1 diff --git a/tests/baselines/reference/jsdocTemplateClass.symbols b/tests/baselines/reference/jsdocTemplateClass.symbols index a2da2f051cd..ee2fc5a6fb9 100644 --- a/tests/baselines/reference/jsdocTemplateClass.symbols +++ b/tests/baselines/reference/jsdocTemplateClass.symbols @@ -38,7 +38,7 @@ class Foo { } } var f = new Foo(1) ->f : Symbol(f, Decl(templateTagOnClasses.js, 22, 3)) +>f : Symbol(f, Decl(templateTagOnClasses.js, 22, 3), Decl(templateTagOnClasses.js, 23, 22)) >Foo : Symbol(Foo, Decl(templateTagOnClasses.js, 0, 0)) var g = new Foo(false) @@ -47,7 +47,7 @@ var g = new Foo(false) f.a = g.a >f.a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 8, 21)) ->f : Symbol(f, Decl(templateTagOnClasses.js, 22, 3)) +>f : Symbol(f, Decl(templateTagOnClasses.js, 22, 3), Decl(templateTagOnClasses.js, 23, 22)) >a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 8, 21)) >g.a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 8, 21)) >g : Symbol(g, Decl(templateTagOnClasses.js, 23, 3)) diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols b/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols index 6a8a948cba8..d176aba903e 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols @@ -45,16 +45,16 @@ Zet.prototype.add = function(v, id) { >u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 8, 17), Decl(templateTagOnConstructorFunctions.js, 17, 37)) } var z = new Zet(1) ->z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 21, 3)) +>z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 21, 3), Decl(templateTagOnConstructorFunctions.js, 21, 18)) >Zet : Symbol(Zet, Decl(templateTagOnConstructorFunctions.js, 0, 0)) z.t = 2 >z.t : Symbol(Zet.t, Decl(templateTagOnConstructorFunctions.js, 10, 10)) ->z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 21, 3)) +>z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 21, 3), Decl(templateTagOnConstructorFunctions.js, 21, 18)) >t : Symbol(Zet.t, Decl(templateTagOnConstructorFunctions.js, 10, 10)) z.u = false >z.u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 8, 17), Decl(templateTagOnConstructorFunctions.js, 17, 37)) ->z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 21, 3)) +>z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 21, 3), Decl(templateTagOnConstructorFunctions.js, 21, 18)) >u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 8, 17), Decl(templateTagOnConstructorFunctions.js, 17, 37)) diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols index 703e23c5af8..ca12425262b 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols @@ -41,17 +41,17 @@ Zet.prototype.add = function(v, o) { >u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) } var z = new Zet(1) ->z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3)) +>z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3), Decl(templateTagWithNestedTypeLiteral.js, 18, 18)) >Zet : Symbol(Zet, Decl(templateTagWithNestedTypeLiteral.js, 0, 0)) z.t = 2 >z.t : Symbol(Zet.t, Decl(templateTagWithNestedTypeLiteral.js, 6, 10)) ->z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3)) +>z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3), Decl(templateTagWithNestedTypeLiteral.js, 18, 18)) >t : Symbol(Zet.t, Decl(templateTagWithNestedTypeLiteral.js, 6, 10)) z.u = false >z.u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) ->z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3)) +>z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3), Decl(templateTagWithNestedTypeLiteral.js, 18, 18)) >u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) // lookup in typedef should not crash the compiler, even when the type is unknown diff --git a/tests/baselines/reference/jsdocTypeFromChainedAssignment.symbols b/tests/baselines/reference/jsdocTypeFromChainedAssignment.symbols index c2d14050ee1..dbf21cf0925 100644 --- a/tests/baselines/reference/jsdocTypeFromChainedAssignment.symbols +++ b/tests/baselines/reference/jsdocTypeFromChainedAssignment.symbols @@ -45,17 +45,17 @@ A.s = A.t = function g(m) { >this : Symbol(A, Decl(a.js, 0, 0), Decl(a.js, 8, 1)) } var a = new A() ->a : Symbol(a, Decl(a.js, 13, 3)) +>a : Symbol(a, Decl(a.js, 13, 3), Decl(a.js, 17, 22)) >A : Symbol(A, Decl(a.js, 0, 0), Decl(a.js, 8, 1)) a.y('no') // error >a.y : Symbol(A.y, Decl(a.js, 4, 1)) ->a : Symbol(a, Decl(a.js, 13, 3)) +>a : Symbol(a, Decl(a.js, 13, 3), Decl(a.js, 17, 22)) >y : Symbol(A.y, Decl(a.js, 4, 1)) a.z('not really') // error >a.z : Symbol(A.z, Decl(a.js, 6, 15)) ->a : Symbol(a, Decl(a.js, 13, 3)) +>a : Symbol(a, Decl(a.js, 13, 3), Decl(a.js, 17, 22)) >z : Symbol(A.z, Decl(a.js, 6, 15)) A.s('still no') // error @@ -70,6 +70,6 @@ A.t('not here either') // error a.first = 10 // error: '10' isn't assignable to '1' >a.first : Symbol(A.first, Decl(a.js, 1, 14)) ->a : Symbol(a, Decl(a.js, 13, 3)) +>a : Symbol(a, Decl(a.js, 13, 3), Decl(a.js, 17, 22)) >first : Symbol(A.first, Decl(a.js, 1, 14)) diff --git a/tests/baselines/reference/moduleExportAlias5.symbols b/tests/baselines/reference/moduleExportAlias5.symbols index cc9cd7212f4..35e27b4a642 100644 --- a/tests/baselines/reference/moduleExportAlias5.symbols +++ b/tests/baselines/reference/moduleExportAlias5.symbols @@ -1,14 +1,14 @@ === tests/cases/conformance/salsa/bug24754.js === // #24754 const webpack = function (){ ->webpack : Symbol(webpack, Decl(bug24754.js, 1, 5)) +>webpack : Symbol(webpack, Decl(bug24754.js, 1, 5), Decl(bug24754.js, 4, 23)) } exports = module.exports = webpack; >exports : Symbol("tests/cases/conformance/salsa/bug24754", Decl(bug24754.js, 0, 0)) >module.exports : Symbol("tests/cases/conformance/salsa/bug24754", Decl(bug24754.js, 0, 0)) >module : Symbol(export=, Decl(bug24754.js, 3, 9)) >exports : Symbol(export=, Decl(bug24754.js, 3, 9)) ->webpack : Symbol(webpack, Decl(bug24754.js, 1, 5)) +>webpack : Symbol(webpack, Decl(bug24754.js, 1, 5), Decl(bug24754.js, 4, 23)) exports.version = 1001; >exports.version : Symbol(version, Decl(bug24754.js, 3, 35)) @@ -17,6 +17,6 @@ exports.version = 1001; webpack.WebpackOptionsDefaulter = 1111; >webpack.WebpackOptionsDefaulter : Symbol(webpack.WebpackOptionsDefaulter, Decl(bug24754.js, 4, 23)) ->webpack : Symbol(webpack, Decl(bug24754.js, 1, 5)) +>webpack : Symbol(webpack, Decl(bug24754.js, 1, 5), Decl(bug24754.js, 4, 23)) >WebpackOptionsDefaulter : Symbol(webpack.WebpackOptionsDefaulter, Decl(bug24754.js, 4, 23)) diff --git a/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols b/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols index 61ff2fffe8a..1dd9bed92e6 100644 --- a/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols +++ b/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols @@ -49,27 +49,27 @@ module.exports.bothBefore = 'string' A.justExport = 4 >A.justExport : Symbol(A.justExport, Decl(mod1.js, 1, 36)) ->A : Symbol(A, Decl(mod1.js, 5, 18)) +>A : Symbol(A, Decl(mod1.js, 5, 18), Decl(mod1.js, 1, 36)) >justExport : Symbol(A.justExport, Decl(mod1.js, 1, 36)) A.bothBefore = 2 >A.bothBefore : Symbol(A.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) ->A : Symbol(A, Decl(mod1.js, 5, 18)) +>A : Symbol(A, Decl(mod1.js, 5, 18), Decl(mod1.js, 1, 36)) >bothBefore : Symbol(A.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) A.bothAfter = 3 >A.bothAfter : Symbol(A.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) ->A : Symbol(A, Decl(mod1.js, 5, 18)) +>A : Symbol(A, Decl(mod1.js, 5, 18), Decl(mod1.js, 1, 36)) >bothAfter : Symbol(A.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) module.exports = A >module.exports : Symbol("tests/cases/conformance/salsa/mod1", Decl(mod1.js, 0, 0)) >module : Symbol(export=, Decl(mod1.js, 4, 15)) >exports : Symbol(export=, Decl(mod1.js, 4, 15)) ->A : Symbol(A, Decl(mod1.js, 5, 18)) +>A : Symbol(A, Decl(mod1.js, 5, 18), Decl(mod1.js, 1, 36)) function A() { ->A : Symbol(A, Decl(mod1.js, 5, 18)) +>A : Symbol(A, Decl(mod1.js, 5, 18), Decl(mod1.js, 1, 36)) this.p = 1 >p : Symbol(A.p, Decl(mod1.js, 6, 14)) diff --git a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.errors.txt b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.errors.txt new file mode 100644 index 00000000000..ee17bd087a1 --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/salsa/bug24658.js(1,10): error TS2440: Import declaration conflicts with local declaration of 'hurk'. + + +==== tests/cases/conformance/salsa/mod1.js (0 errors) ==== + export var hurk = {} +==== tests/cases/conformance/salsa/bug24658.js (1 errors) ==== + import { hurk } from './mod1' + ~~~~ +!!! error TS2440: Import declaration conflicts with local declaration of 'hurk'. + hurk.expando = 4 + \ No newline at end of file diff --git a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols index f8d01ae6981..453816e38cf 100644 --- a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols +++ b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols @@ -4,8 +4,10 @@ export var hurk = {} === tests/cases/conformance/salsa/bug24658.js === import { hurk } from './mod1' ->hurk : Symbol(hurk, Decl(bug24658.js, 0, 8)) +>hurk : Symbol(hurk, Decl(bug24658.js, 0, 8), Decl(bug24658.js, 0, 29)) hurk.expando = 4 ->hurk : Symbol(hurk, Decl(bug24658.js, 0, 8)) +>hurk.expando : Symbol(hurk.expando, Decl(bug24658.js, 0, 29)) +>hurk : Symbol(hurk, Decl(bug24658.js, 0, 8), Decl(bug24658.js, 0, 29)) +>expando : Symbol(hurk.expando, Decl(bug24658.js, 0, 29)) diff --git a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types index 8df4f984574..53930f09a65 100644 --- a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types +++ b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types @@ -5,12 +5,12 @@ export var hurk = {} === tests/cases/conformance/salsa/bug24658.js === import { hurk } from './mod1' ->hurk : {} +>hurk : typeof hurk hurk.expando = 4 >hurk.expando = 4 : 4 ->hurk.expando : any ->hurk : {} ->expando : any +>hurk.expando : number +>hurk : typeof hurk +>expando : number >4 : 4 diff --git a/tests/baselines/reference/targetTypeTest1.errors.txt b/tests/baselines/reference/targetTypeTest1.errors.txt index 63d061d66b7..a0b05690a3b 100644 --- a/tests/baselines/reference/targetTypeTest1.errors.txt +++ b/tests/baselines/reference/targetTypeTest1.errors.txt @@ -1,13 +1,11 @@ tests/cases/compiler/targetTypeTest1.ts(1,15): error TS2300: Duplicate identifier 'Point'. -tests/cases/compiler/targetTypeTest1.ts(6,43): error TS2304: Cannot find name 'Point'. -tests/cases/compiler/targetTypeTest1.ts(7,22): error TS2304: Cannot find name 'Point'. tests/cases/compiler/targetTypeTest1.ts(14,10): error TS2300: Duplicate identifier 'Point'. tests/cases/compiler/targetTypeTest1.ts(19,18): error TS2384: Overload signatures must all be ambient or non-ambient. tests/cases/compiler/targetTypeTest1.ts(53,15): error TS2300: Duplicate identifier 'C'. tests/cases/compiler/targetTypeTest1.ts(60,10): error TS2300: Duplicate identifier 'C'. -==== tests/cases/compiler/targetTypeTest1.ts (7 errors) ==== +==== tests/cases/compiler/targetTypeTest1.ts (5 errors) ==== declare class Point ~~~~~ !!! error TS2300: Duplicate identifier 'Point'. @@ -16,11 +14,7 @@ tests/cases/compiler/targetTypeTest1.ts(60,10): error TS2300: Duplicate identifi public x: number; public y: number; public add(dx: number, dy: number): Point; - ~~~~~ -!!! error TS2304: Cannot find name 'Point'. static origin: Point; - ~~~~~ -!!! error TS2304: Cannot find name 'Point'. } diff --git a/tests/baselines/reference/targetTypeTest1.symbols b/tests/baselines/reference/targetTypeTest1.symbols index 7596de0d69f..e8b5292603f 100644 --- a/tests/baselines/reference/targetTypeTest1.symbols +++ b/tests/baselines/reference/targetTypeTest1.symbols @@ -16,9 +16,11 @@ declare class Point >add : Symbol(Point.add, Decl(targetTypeTest1.ts, 4, 23)) >dx : Symbol(dx, Decl(targetTypeTest1.ts, 5, 17)) >dy : Symbol(dy, Decl(targetTypeTest1.ts, 5, 28)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) static origin: Point; >origin : Symbol(Point.origin, Decl(targetTypeTest1.ts, 5, 48)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) } @@ -26,7 +28,7 @@ declare class Point // Because Point is a constructor function, this is inferred // to be Point and return type is inferred to be void function Point(x, y) { ->Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) >x : Symbol(x, Decl(targetTypeTest1.ts, 13, 15)) >y : Symbol(y, Decl(targetTypeTest1.ts, 13, 17)) @@ -56,22 +58,22 @@ var x = EF1(1,2); // Point.origin declared as type Point Point.origin = new Point(0, 0); >Point.origin : Symbol(Point.origin, Decl(targetTypeTest1.ts, 22, 17)) ->Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) >origin : Symbol(Point.origin, Decl(targetTypeTest1.ts, 22, 17)) ->Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) // Point.prototype declared as type Point // this inferred as Point because of obj.prop assignment // dx, dy, and return type inferred using target typing Point.prototype.add = function(dx, dy) { >Point.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) ->Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) >prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) >dx : Symbol(dx, Decl(targetTypeTest1.ts, 30, 31)) >dy : Symbol(dy, Decl(targetTypeTest1.ts, 30, 34)) return new Point(this.x + dx, this.y + dy); ->Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) >dx : Symbol(dx, Decl(targetTypeTest1.ts, 30, 31)) >dy : Symbol(dy, Decl(targetTypeTest1.ts, 30, 34)) @@ -85,7 +87,7 @@ var f : number = 5; // dx, dy, and return type of add inferred using target typing Point.prototype = { >Point.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) ->Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) >prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) x: 0, @@ -100,7 +102,7 @@ Point.prototype = { >dy : Symbol(dy, Decl(targetTypeTest1.ts, 42, 21)) return new Point(this.x + dx, this.y + dy); ->Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1)) +>Point : Symbol(Point, Decl(targetTypeTest1.ts, 8, 1), Decl(targetTypeTest1.ts, 22, 17)) >dx : Symbol(dx, Decl(targetTypeTest1.ts, 42, 18)) >dy : Symbol(dy, Decl(targetTypeTest1.ts, 42, 21)) } diff --git a/tests/baselines/reference/targetTypeTest1.types b/tests/baselines/reference/targetTypeTest1.types index 0cd418c1241..fcf994b941a 100644 --- a/tests/baselines/reference/targetTypeTest1.types +++ b/tests/baselines/reference/targetTypeTest1.types @@ -26,7 +26,7 @@ declare class Point // Because Point is a constructor function, this is inferred // to be Point and return type is inferred to be void function Point(x, y) { ->Point : { (x: any, y: any): void; origin: any; } +>Point : typeof Point >x : any >y : any @@ -69,10 +69,10 @@ var x = EF1(1,2); Point.origin = new Point(0, 0); >Point.origin = new Point(0, 0) : any >Point.origin : any ->Point : { (x: any, y: any): void; origin: any; } +>Point : typeof Point >origin : any >new Point(0, 0) : any ->Point : { (x: any, y: any): void; origin: any; } +>Point : typeof Point >0 : 0 >0 : 0 @@ -83,7 +83,7 @@ Point.prototype.add = function(dx, dy) { >Point.prototype.add = function(dx, dy) { return new Point(this.x + dx, this.y + dy);} : (dx: any, dy: any) => any >Point.prototype.add : any >Point.prototype : any ->Point : { (x: any, y: any): void; origin: any; } +>Point : typeof Point >prototype : any >add : any >function(dx, dy) { return new Point(this.x + dx, this.y + dy);} : (dx: any, dy: any) => any @@ -92,7 +92,7 @@ Point.prototype.add = function(dx, dy) { return new Point(this.x + dx, this.y + dy); >new Point(this.x + dx, this.y + dy) : any ->Point : { (x: any, y: any): void; origin: any; } +>Point : typeof Point >this.x + dx : any >this.x : any >this : any @@ -116,7 +116,7 @@ var f : number = 5; Point.prototype = { >Point.prototype = { x: 0, y: 0, add: function(dx, dy) { return new Point(this.x + dx, this.y + dy); }} : { x: number; y: number; add: (dx: any, dy: any) => any; } >Point.prototype : any ->Point : { (x: any, y: any): void; origin: any; } +>Point : typeof Point >prototype : any >{ x: 0, y: 0, add: function(dx, dy) { return new Point(this.x + dx, this.y + dy); }} : { x: number; y: number; add: (dx: any, dy: any) => any; } @@ -136,7 +136,7 @@ Point.prototype = { return new Point(this.x + dx, this.y + dy); >new Point(this.x + dx, this.y + dy) : any ->Point : { (x: any, y: any): void; origin: any; } +>Point : typeof Point >this.x + dx : any >this.x : any >this : any diff --git a/tests/baselines/reference/typeFromJSInitializer.symbols b/tests/baselines/reference/typeFromJSInitializer.symbols index d2212ccd367..d7453d1f1e1 100644 --- a/tests/baselines/reference/typeFromJSInitializer.symbols +++ b/tests/baselines/reference/typeFromJSInitializer.symbols @@ -14,74 +14,74 @@ function A () { >empty : Symbol(A.empty, Decl(a.js, 3, 31)) } var a = new A() ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >A : Symbol(A, Decl(a.js, 0, 0)) a.unknown = 1 >a.unknown : Symbol(A.unknown, Decl(a.js, 0, 15)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >unknown : Symbol(A.unknown, Decl(a.js, 0, 15)) a.unknown = true >a.unknown : Symbol(A.unknown, Decl(a.js, 0, 15)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >unknown : Symbol(A.unknown, Decl(a.js, 0, 15)) a.unknown = {} >a.unknown : Symbol(A.unknown, Decl(a.js, 0, 15)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >unknown : Symbol(A.unknown, Decl(a.js, 0, 15)) a.unknown = 'hi' >a.unknown : Symbol(A.unknown, Decl(a.js, 0, 15)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >unknown : Symbol(A.unknown, Decl(a.js, 0, 15)) a.unknowable = 1 >a.unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23)) a.unknowable = true >a.unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23)) a.unknowable = {} >a.unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23)) a.unknowable = 'hi' >a.unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23)) a.empty.push(1) >a.empty.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) >a.empty : Symbol(A.empty, Decl(a.js, 3, 31)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >empty : Symbol(A.empty, Decl(a.js, 3, 31)) >push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) a.empty.push(true) >a.empty.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) >a.empty : Symbol(A.empty, Decl(a.js, 3, 31)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >empty : Symbol(A.empty, Decl(a.js, 3, 31)) >push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) a.empty.push({}) >a.empty.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) >a.empty : Symbol(A.empty, Decl(a.js, 3, 31)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >empty : Symbol(A.empty, Decl(a.js, 3, 31)) >push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) a.empty.push('hi') >a.empty.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) >a.empty : Symbol(A.empty, Decl(a.js, 3, 31)) ->a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16)) +>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 6, 15)) >empty : Symbol(A.empty, Decl(a.js, 3, 31)) >push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment17.symbols b/tests/baselines/reference/typeFromPropertyAssignment17.symbols index 6708c25796e..165d3a04f8d 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment17.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment17.symbols @@ -41,17 +41,17 @@ module.exports = minimatch >module.exports : Symbol("tests/cases/conformance/salsa/minimatch", Decl(minimatch.js, 0, 0)) >module : Symbol(export=, Decl(minimatch.js, 0, 0)) >exports : Symbol(export=, Decl(minimatch.js, 0, 0)) ->minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1)) +>minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1), Decl(minimatch.js, 1, 26)) minimatch.M = M >minimatch.M : Symbol(minimatch.M, Decl(minimatch.js, 1, 26)) ->minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1)) +>minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1), Decl(minimatch.js, 1, 26)) >M : Symbol(minimatch.M, Decl(minimatch.js, 1, 26)) >M : Symbol(M, Decl(minimatch.js, 13, 1), Decl(minimatch.js, 8, 1)) minimatch.filter = filter >minimatch.filter : Symbol(minimatch.filter, Decl(minimatch.js, 2, 15)) ->minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1)) +>minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1), Decl(minimatch.js, 1, 26)) >filter : Symbol(minimatch.filter, Decl(minimatch.js, 2, 15)) >filter : Symbol(filter, Decl(minimatch.js, 3, 25)) @@ -59,10 +59,10 @@ function filter() { >filter : Symbol(filter, Decl(minimatch.js, 3, 25)) return minimatch() ->minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1)) +>minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1), Decl(minimatch.js, 1, 26)) } function minimatch() { ->minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1)) +>minimatch : Symbol(minimatch, Decl(minimatch.js, 6, 1), Decl(minimatch.js, 1, 26)) } M.defaults = function (def) { >M.defaults : Symbol(M.defaults, Decl(minimatch.js, 8, 1)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment17.types b/tests/baselines/reference/typeFromPropertyAssignment17.types index 448880f4c89..8d32ac016b3 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment17.types +++ b/tests/baselines/reference/typeFromPropertyAssignment17.types @@ -1,8 +1,8 @@ === tests/cases/conformance/salsa/use.js === /// var mini = require('./minimatch') ->mini : { (): void; M: typeof M; filter: () => void; } ->require('./minimatch') : { (): void; M: typeof M; filter: () => void; } +>mini : typeof minimatch +>require('./minimatch') : typeof minimatch >require : any >'./minimatch' : "./minimatch" @@ -10,7 +10,7 @@ mini.M.defaults() >mini.M.defaults() : any >mini.M.defaults : (def: any) => any >mini.M : typeof M ->mini : { (): void; M: typeof M; filter: () => void; } +>mini : typeof minimatch >M : typeof M >defaults : (def: any) => any @@ -18,7 +18,7 @@ var m = new mini.M() >m : M >new mini.M() : M >mini.M : typeof M ->mini : { (): void; M: typeof M; filter: () => void; } +>mini : typeof minimatch >M : typeof M m.m() @@ -30,7 +30,7 @@ m.m() mini.filter() >mini.filter() : void >mini.filter : () => void ->mini : { (): void; M: typeof M; filter: () => void; } +>mini : typeof minimatch >filter : () => void === tests/cases/conformance/salsa/types.d.ts === @@ -43,23 +43,23 @@ declare var module: any; === tests/cases/conformance/salsa/minimatch.js === /// module.exports = minimatch ->module.exports = minimatch : { (): void; M: typeof M; filter: () => void; } ->module.exports : { (): void; M: typeof M; filter: () => void; } ->module : { "tests/cases/conformance/salsa/minimatch": { (): void; M: typeof M; filter: () => void; }; } ->exports : { (): void; M: typeof M; filter: () => void; } ->minimatch : { (): void; M: typeof M; filter: () => void; } +>module.exports = minimatch : typeof minimatch +>module.exports : typeof minimatch +>module : { "tests/cases/conformance/salsa/minimatch": typeof minimatch; } +>exports : typeof minimatch +>minimatch : typeof minimatch minimatch.M = M >minimatch.M = M : typeof M >minimatch.M : typeof M ->minimatch : { (): void; M: typeof M; filter: () => void; } +>minimatch : typeof minimatch >M : typeof M >M : typeof M minimatch.filter = filter >minimatch.filter = filter : () => void >minimatch.filter : () => void ->minimatch : { (): void; M: typeof M; filter: () => void; } +>minimatch : typeof minimatch >filter : () => void >filter : () => void @@ -68,10 +68,10 @@ function filter() { return minimatch() >minimatch() : void ->minimatch : { (): void; M: typeof M; filter: () => void; } +>minimatch : typeof minimatch } function minimatch() { ->minimatch : { (): void; M: typeof M; filter: () => void; } +>minimatch : typeof minimatch } M.defaults = function (def) { >M.defaults = function (def) { return def} : (def: any) => any diff --git a/tests/baselines/reference/typeFromPropertyAssignment18.symbols b/tests/baselines/reference/typeFromPropertyAssignment18.symbols index cb74bd66d39..1a7e1c292af 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment18.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment18.symbols @@ -1,46 +1,46 @@ === tests/cases/conformance/salsa/a.js === var GLOBSTAR = m.GLOBSTAR = {} ->GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3)) ->m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) ->m : Symbol(m, Decl(a.js, 0, 30)) ->GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) +>GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3), Decl(a.js, 2, 1)) +>m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14), Decl(a.js, 4, 2)) +>m : Symbol(m, Decl(a.js, 0, 30), Decl(a.js, 3, 14)) +>GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14), Decl(a.js, 4, 2)) function m() { ->m : Symbol(m, Decl(a.js, 0, 30)) +>m : Symbol(m, Decl(a.js, 0, 30), Decl(a.js, 3, 14)) } GLOBSTAR.p = 1 >GLOBSTAR.p : Symbol(GLOBSTAR.p, Decl(a.js, 2, 1)) ->GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3)) +>GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3), Decl(a.js, 2, 1)) >p : Symbol(GLOBSTAR.p, Decl(a.js, 2, 1)) m.GLOBSTAR.q = 2 >m.GLOBSTAR.q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) ->m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) ->m : Symbol(m, Decl(a.js, 0, 30)) ->GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) +>m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14), Decl(a.js, 4, 2)) +>m : Symbol(m, Decl(a.js, 0, 30), Decl(a.js, 3, 14)) +>GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14), Decl(a.js, 4, 2)) >q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) GLOBSTAR.p >GLOBSTAR.p : Symbol(GLOBSTAR.p, Decl(a.js, 2, 1)) ->GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3)) +>GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3), Decl(a.js, 2, 1)) >p : Symbol(GLOBSTAR.p, Decl(a.js, 2, 1)) GLOBSTAR.q >GLOBSTAR.q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) ->GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3)) +>GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3), Decl(a.js, 2, 1)) >q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) m.GLOBSTAR.p >m.GLOBSTAR.p : Symbol(GLOBSTAR.p, Decl(a.js, 2, 1)) ->m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) ->m : Symbol(m, Decl(a.js, 0, 30)) ->GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) +>m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14), Decl(a.js, 4, 2)) +>m : Symbol(m, Decl(a.js, 0, 30), Decl(a.js, 3, 14)) +>GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14), Decl(a.js, 4, 2)) >p : Symbol(GLOBSTAR.p, Decl(a.js, 2, 1)) m.GLOBSTAR.q >m.GLOBSTAR.q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) ->m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) ->m : Symbol(m, Decl(a.js, 0, 30)) ->GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) +>m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14), Decl(a.js, 4, 2)) +>m : Symbol(m, Decl(a.js, 0, 30), Decl(a.js, 3, 14)) +>GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14), Decl(a.js, 4, 2)) >q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment18.types b/tests/baselines/reference/typeFromPropertyAssignment18.types index 6973115a0f8..1058ae610b3 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment18.types +++ b/tests/baselines/reference/typeFromPropertyAssignment18.types @@ -1,52 +1,52 @@ === tests/cases/conformance/salsa/a.js === var GLOBSTAR = m.GLOBSTAR = {} ->GLOBSTAR : { q: number; p: number; } ->m.GLOBSTAR = {} : { q: number; p: number; } ->m.GLOBSTAR : { q: number; p: number; } ->m : { (): void; GLOBSTAR: { q: number; p: number; }; } ->GLOBSTAR : { q: number; p: number; } +>GLOBSTAR : typeof m.GLOBSTAR +>m.GLOBSTAR = {} : typeof m.GLOBSTAR +>m.GLOBSTAR : typeof m.GLOBSTAR +>m : typeof m +>GLOBSTAR : typeof m.GLOBSTAR >{} : {} function m() { ->m : { (): void; GLOBSTAR: { q: number; p: number; }; } +>m : typeof m } GLOBSTAR.p = 1 >GLOBSTAR.p = 1 : 1 >GLOBSTAR.p : number ->GLOBSTAR : { q: number; p: number; } +>GLOBSTAR : typeof m.GLOBSTAR >p : number >1 : 1 m.GLOBSTAR.q = 2 >m.GLOBSTAR.q = 2 : 2 >m.GLOBSTAR.q : number ->m.GLOBSTAR : { q: number; p: number; } ->m : { (): void; GLOBSTAR: { q: number; p: number; }; } ->GLOBSTAR : { q: number; p: number; } +>m.GLOBSTAR : typeof m.GLOBSTAR +>m : typeof m +>GLOBSTAR : typeof m.GLOBSTAR >q : number >2 : 2 GLOBSTAR.p >GLOBSTAR.p : number ->GLOBSTAR : { q: number; p: number; } +>GLOBSTAR : typeof m.GLOBSTAR >p : number GLOBSTAR.q >GLOBSTAR.q : number ->GLOBSTAR : { q: number; p: number; } +>GLOBSTAR : typeof m.GLOBSTAR >q : number m.GLOBSTAR.p >m.GLOBSTAR.p : number ->m.GLOBSTAR : { q: number; p: number; } ->m : { (): void; GLOBSTAR: { q: number; p: number; }; } ->GLOBSTAR : { q: number; p: number; } +>m.GLOBSTAR : typeof m.GLOBSTAR +>m : typeof m +>GLOBSTAR : typeof m.GLOBSTAR >p : number m.GLOBSTAR.q >m.GLOBSTAR.q : number ->m.GLOBSTAR : { q: number; p: number; } ->m : { (): void; GLOBSTAR: { q: number; p: number; }; } ->GLOBSTAR : { q: number; p: number; } +>m.GLOBSTAR : typeof m.GLOBSTAR +>m : typeof m +>GLOBSTAR : typeof m.GLOBSTAR >q : number diff --git a/tests/baselines/reference/typeFromPropertyAssignment22.symbols b/tests/baselines/reference/typeFromPropertyAssignment22.symbols index 7288d7f6e26..fbdfb304f2c 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment22.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment22.symbols @@ -28,14 +28,14 @@ Installer.prototype.loadArgMetadata = function (next) { } } var i = new Installer() ->i : Symbol(i, Decl(npm-install.js, 10, 3)) +>i : Symbol(i, Decl(npm-install.js, 10, 3), Decl(npm-install.js, 10, 23)) >Installer : Symbol(Installer, Decl(npm-install.js, 0, 0)) i.newProperty = i.args // ok, number ==> number | undefined >i.newProperty : Symbol(Installer.newProperty, Decl(npm-install.js, 6, 24)) ->i : Symbol(i, Decl(npm-install.js, 10, 3)) +>i : Symbol(i, Decl(npm-install.js, 10, 3), Decl(npm-install.js, 10, 23)) >newProperty : Symbol(Installer.newProperty, Decl(npm-install.js, 6, 24)) >i.args : Symbol(Installer.args, Decl(npm-install.js, 0, 23), Decl(npm-install.js, 5, 15)) ->i : Symbol(i, Decl(npm-install.js, 10, 3)) +>i : Symbol(i, Decl(npm-install.js, 10, 3), Decl(npm-install.js, 10, 23)) >args : Symbol(Installer.args, Decl(npm-install.js, 0, 23), Decl(npm-install.js, 5, 15)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment29.symbols b/tests/baselines/reference/typeFromPropertyAssignment29.symbols index 2e51e26304b..8be54d3d87c 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment29.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment29.symbols @@ -1,6 +1,6 @@ === tests/cases/conformance/salsa/typeFromPropertyAssignment29.ts === function ExpandoDecl(n: number) { ->ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 3, 20)) +>ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 2, 1)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 0, 21)) return n.toString(); @@ -10,12 +10,12 @@ function ExpandoDecl(n: number) { } ExpandoDecl.prop = 2 >ExpandoDecl.prop : Symbol(ExpandoDecl.prop, Decl(typeFromPropertyAssignment29.ts, 2, 1)) ->ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 3, 20)) +>ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 2, 1)) >prop : Symbol(ExpandoDecl.prop, Decl(typeFromPropertyAssignment29.ts, 2, 1)) ExpandoDecl.m = function(n: number) { >ExpandoDecl.m : Symbol(ExpandoDecl.m, Decl(typeFromPropertyAssignment29.ts, 3, 20)) ->ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 3, 20)) +>ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 2, 1)) >m : Symbol(ExpandoDecl.m, Decl(typeFromPropertyAssignment29.ts, 3, 20)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 4, 25)) @@ -25,17 +25,17 @@ ExpandoDecl.m = function(n: number) { var n = ExpandoDecl.prop + ExpandoDecl.m(12) + ExpandoDecl(101).length >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) >ExpandoDecl.prop : Symbol(ExpandoDecl.prop, Decl(typeFromPropertyAssignment29.ts, 2, 1)) ->ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 3, 20)) +>ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 2, 1)) >prop : Symbol(ExpandoDecl.prop, Decl(typeFromPropertyAssignment29.ts, 2, 1)) >ExpandoDecl.m : Symbol(ExpandoDecl.m, Decl(typeFromPropertyAssignment29.ts, 3, 20)) ->ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 3, 20)) +>ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 2, 1)) >m : Symbol(ExpandoDecl.m, Decl(typeFromPropertyAssignment29.ts, 3, 20)) >ExpandoDecl(101).length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) ->ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 3, 20)) +>ExpandoDecl : Symbol(ExpandoDecl, Decl(typeFromPropertyAssignment29.ts, 0, 0), Decl(typeFromPropertyAssignment29.ts, 2, 1)) >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) const ExpandoExpr = function (n: number) { ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 11, 1)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 9, 30)) return n.toString(); @@ -45,19 +45,19 @@ const ExpandoExpr = function (n: number) { } ExpandoExpr.prop = { x: 2 } >ExpandoExpr.prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 11, 1)) >prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) >x : Symbol(x, Decl(typeFromPropertyAssignment29.ts, 12, 20)) ExpandoExpr.prop = { y: "" } >ExpandoExpr.prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 11, 1)) >prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) >y : Symbol(y, Decl(typeFromPropertyAssignment29.ts, 13, 20)) ExpandoExpr.m = function(n: number) { >ExpandoExpr.m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 13, 28)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 11, 1)) >m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 13, 28)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 14, 25)) @@ -68,18 +68,18 @@ var n = (ExpandoExpr.prop.x || 0) + ExpandoExpr.m(12) + ExpandoExpr(101).length >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) >ExpandoExpr.prop.x : Symbol(x, Decl(typeFromPropertyAssignment29.ts, 12, 20)) >ExpandoExpr.prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 11, 1)) >prop : Symbol(ExpandoExpr.prop, Decl(typeFromPropertyAssignment29.ts, 11, 1), Decl(typeFromPropertyAssignment29.ts, 12, 27)) >x : Symbol(x, Decl(typeFromPropertyAssignment29.ts, 12, 20)) >ExpandoExpr.m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 13, 28)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 11, 1)) >m : Symbol(ExpandoExpr.m, Decl(typeFromPropertyAssignment29.ts, 13, 28)) >ExpandoExpr(101).length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) ->ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 13, 28)) +>ExpandoExpr : Symbol(ExpandoExpr, Decl(typeFromPropertyAssignment29.ts, 9, 5), Decl(typeFromPropertyAssignment29.ts, 11, 1)) >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) const ExpandoArrow = (n: number) => n.toString(); ->ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 20, 21)) +>ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 19, 49)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 19, 22)) >n.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 19, 22)) @@ -87,12 +87,12 @@ const ExpandoArrow = (n: number) => n.toString(); ExpandoArrow.prop = 2 >ExpandoArrow.prop : Symbol(ExpandoArrow.prop, Decl(typeFromPropertyAssignment29.ts, 19, 49)) ->ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 20, 21)) +>ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 19, 49)) >prop : Symbol(ExpandoArrow.prop, Decl(typeFromPropertyAssignment29.ts, 19, 49)) ExpandoArrow.m = function(n: number) { >ExpandoArrow.m : Symbol(ExpandoArrow.m, Decl(typeFromPropertyAssignment29.ts, 20, 21)) ->ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 20, 21)) +>ExpandoArrow : Symbol(ExpandoArrow, Decl(typeFromPropertyAssignment29.ts, 19, 5), Decl(typeFromPropertyAssignment29.ts, 19, 49)) >m : Symbol(ExpandoArrow.m, Decl(typeFromPropertyAssignment29.ts, 20, 21)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 21, 26)) @@ -102,7 +102,7 @@ ExpandoArrow.m = function(n: number) { } function ExpandoNested(n: number) { ->ExpandoNested : Symbol(ExpandoNested, Decl(typeFromPropertyAssignment29.ts, 24, 1)) +>ExpandoNested : Symbol(ExpandoNested, Decl(typeFromPropertyAssignment29.ts, 24, 1), Decl(typeFromPropertyAssignment29.ts, 32, 1)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 26, 23)) const nested = function (m: number) { @@ -125,11 +125,11 @@ function ExpandoNested(n: number) { } ExpandoNested.also = -1; >ExpandoNested.also : Symbol(ExpandoNested.also, Decl(typeFromPropertyAssignment29.ts, 32, 1)) ->ExpandoNested : Symbol(ExpandoNested, Decl(typeFromPropertyAssignment29.ts, 24, 1)) +>ExpandoNested : Symbol(ExpandoNested, Decl(typeFromPropertyAssignment29.ts, 24, 1), Decl(typeFromPropertyAssignment29.ts, 32, 1)) >also : Symbol(ExpandoNested.also, Decl(typeFromPropertyAssignment29.ts, 32, 1)) function ExpandoMerge(n: number) { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 37, 1), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 35, 22)) return n * 100; @@ -137,17 +137,17 @@ function ExpandoMerge(n: number) { } ExpandoMerge.p1 = 111 >ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment29.ts, 37, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 37, 1), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) >p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment29.ts, 37, 1)) namespace ExpandoMerge { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 37, 1), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) export var p2 = 222; >p2 : Symbol(p2, Decl(typeFromPropertyAssignment29.ts, 40, 14)) } namespace ExpandoMerge { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 37, 1), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) export var p3 = 333; >p3 : Symbol(p3, Decl(typeFromPropertyAssignment29.ts, 43, 14)) @@ -155,15 +155,15 @@ namespace ExpandoMerge { var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge(1); >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) >ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment29.ts, 37, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 37, 1), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) >p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment29.ts, 37, 1)) >ExpandoMerge.p2 : Symbol(ExpandoMerge.p2, Decl(typeFromPropertyAssignment29.ts, 40, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 37, 1), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) >p2 : Symbol(ExpandoMerge.p2, Decl(typeFromPropertyAssignment29.ts, 40, 14)) >ExpandoMerge.p3 : Symbol(ExpandoMerge.p3, Decl(typeFromPropertyAssignment29.ts, 43, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 37, 1), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) >p3 : Symbol(ExpandoMerge.p3, Decl(typeFromPropertyAssignment29.ts, 43, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment29.ts, 33, 24), Decl(typeFromPropertyAssignment29.ts, 37, 1), Decl(typeFromPropertyAssignment29.ts, 38, 21), Decl(typeFromPropertyAssignment29.ts, 41, 1)) namespace Ns { >Ns : Symbol(Ns, Decl(typeFromPropertyAssignment29.ts, 45, 78)) @@ -186,7 +186,7 @@ namespace Ns { // Should not work in Typescript -- must be const var ExpandoExpr2 = function (n: number) { ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 58, 1)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 56, 29)) return n.toString(); @@ -195,10 +195,10 @@ var ExpandoExpr2 = function (n: number) { >toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) } ExpandoExpr2.prop = 2 ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 58, 1)) ExpandoExpr2.m = function(n: number) { ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 58, 1)) >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 60, 26)) return n + 1; @@ -206,10 +206,10 @@ ExpandoExpr2.m = function(n: number) { } var n = ExpandoExpr2.prop + ExpandoExpr2.m(12) + ExpandoExpr2(101).length >n : Symbol(n, Decl(typeFromPropertyAssignment29.ts, 7, 3), Decl(typeFromPropertyAssignment29.ts, 17, 3), Decl(typeFromPropertyAssignment29.ts, 45, 3), Decl(typeFromPropertyAssignment29.ts, 63, 3), Decl(typeFromPropertyAssignment29.ts, 73, 3) ... and 1 more) ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 58, 1)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 58, 1)) >ExpandoExpr2(101).length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) ->ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 59, 21)) +>ExpandoExpr2 : Symbol(ExpandoExpr2, Decl(typeFromPropertyAssignment29.ts, 56, 3), Decl(typeFromPropertyAssignment29.ts, 58, 1)) >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) // Should not work in typescript -- classes already have statics diff --git a/tests/baselines/reference/typeFromPropertyAssignment29.types b/tests/baselines/reference/typeFromPropertyAssignment29.types index 1421ec885c5..28a6700f482 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment29.types +++ b/tests/baselines/reference/typeFromPropertyAssignment29.types @@ -144,7 +144,7 @@ ExpandoArrow.m = function(n: number) { } function ExpandoNested(n: number) { ->ExpandoNested : { (n: number): { (m: number): number; total: number; }; also: number; } +>ExpandoNested : typeof ExpandoNested >n : number const nested = function (m: number) { @@ -173,7 +173,7 @@ function ExpandoNested(n: number) { ExpandoNested.also = -1; >ExpandoNested.also = -1 : -1 >ExpandoNested.also : number ->ExpandoNested : { (n: number): { (m: number): number; total: number; }; also: number; } +>ExpandoNested : typeof ExpandoNested >also : number >-1 : -1 >1 : 1 diff --git a/tests/baselines/reference/typeFromPropertyAssignment31.symbols b/tests/baselines/reference/typeFromPropertyAssignment31.symbols index e5a6de9c82a..5a20510a739 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment31.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment31.symbols @@ -1,6 +1,6 @@ === tests/cases/conformance/salsa/typeFromPropertyAssignment31.ts === function ExpandoMerge(n: number) { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 0, 22)) return n; @@ -8,12 +8,12 @@ function ExpandoMerge(n: number) { } ExpandoMerge.p1 = 111 >ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment31.ts, 2, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment31.ts, 2, 1)) ExpandoMerge.m = function(n: number) { >ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(typeFromPropertyAssignment31.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >m : Symbol(ExpandoMerge.m, Decl(typeFromPropertyAssignment31.ts, 3, 21)) >n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 4, 26)) @@ -21,28 +21,28 @@ ExpandoMerge.m = function(n: number) { >n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 4, 26)) } namespace ExpandoMerge { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) export var p2 = 222; >p2 : Symbol(p2, Decl(typeFromPropertyAssignment31.ts, 8, 14)) } ExpandoMerge.p4 = 44444; // ok >ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p4 : Symbol(ExpandoMerge.p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) ExpandoMerge.p6 = 66666; // ok >ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p6 : Symbol(ExpandoMerge.p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) ExpandoMerge.p8 = false; // type error >ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p8 : Symbol(ExpandoMerge.p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) namespace ExpandoMerge { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) export var p3 = 333; >p3 : Symbol(p3, Decl(typeFromPropertyAssignment31.ts, 14, 14)) @@ -67,50 +67,50 @@ namespace ExpandoMerge { } ExpandoMerge.p5 = 555555; // ok >ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p5 : Symbol(ExpandoMerge.p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) ExpandoMerge.p7 = 777777; // ok >ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p7 : Symbol(ExpandoMerge.p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) ExpandoMerge.p9 = false; // type error >ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p9 : Symbol(ExpandoMerge.p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); >n : Symbol(n, Decl(typeFromPropertyAssignment31.ts, 25, 3)) >ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment31.ts, 2, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p1 : Symbol(ExpandoMerge.p1, Decl(typeFromPropertyAssignment31.ts, 2, 1)) >ExpandoMerge.p2 : Symbol(ExpandoMerge.p2, Decl(typeFromPropertyAssignment31.ts, 8, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p2 : Symbol(ExpandoMerge.p2, Decl(typeFromPropertyAssignment31.ts, 8, 14)) >ExpandoMerge.p3 : Symbol(ExpandoMerge.p3, Decl(typeFromPropertyAssignment31.ts, 14, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p3 : Symbol(ExpandoMerge.p3, Decl(typeFromPropertyAssignment31.ts, 14, 14)) >ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p4 : Symbol(ExpandoMerge.p4, Decl(typeFromPropertyAssignment31.ts, 9, 1), Decl(typeFromPropertyAssignment31.ts, 15, 14)) >ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p5 : Symbol(ExpandoMerge.p5, Decl(typeFromPropertyAssignment31.ts, 16, 14), Decl(typeFromPropertyAssignment31.ts, 21, 1)) >ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p6 : Symbol(ExpandoMerge.p6, Decl(typeFromPropertyAssignment31.ts, 10, 24), Decl(typeFromPropertyAssignment31.ts, 17, 14)) >ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p7 : Symbol(ExpandoMerge.p7, Decl(typeFromPropertyAssignment31.ts, 18, 14), Decl(typeFromPropertyAssignment31.ts, 22, 25)) >ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p8 : Symbol(ExpandoMerge.p8, Decl(typeFromPropertyAssignment31.ts, 11, 24), Decl(typeFromPropertyAssignment31.ts, 19, 14)) >ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >p9 : Symbol(ExpandoMerge.p9, Decl(typeFromPropertyAssignment31.ts, 20, 14), Decl(typeFromPropertyAssignment31.ts, 23, 25)) >ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(typeFromPropertyAssignment31.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) >m : Symbol(ExpandoMerge.m, Decl(typeFromPropertyAssignment31.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 3, 21), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(typeFromPropertyAssignment31.ts, 0, 0), Decl(typeFromPropertyAssignment31.ts, 2, 1), Decl(typeFromPropertyAssignment31.ts, 6, 1), Decl(typeFromPropertyAssignment31.ts, 12, 24)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment32.symbols b/tests/baselines/reference/typeFromPropertyAssignment32.symbols index d730f4d7e11..0daec198f71 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment32.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment32.symbols @@ -1,6 +1,6 @@ === tests/cases/conformance/salsa/expando.ts === function ExpandoMerge(n: number) { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >n : Symbol(n, Decl(expando.ts, 0, 22)) return n; @@ -8,12 +8,12 @@ function ExpandoMerge(n: number) { } ExpandoMerge.p1 = 111 >ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) ExpandoMerge.m = function(n: number) { >ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) >n : Symbol(n, Decl(expando.ts, 4, 26)) @@ -22,71 +22,71 @@ ExpandoMerge.m = function(n: number) { } ExpandoMerge.p4 = 44444; >ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p4 : Symbol(ExpandoMerge.p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) ExpandoMerge.p5 = 555555; >ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p5 : Symbol(ExpandoMerge.p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) ExpandoMerge.p6 = 66666; >ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p6 : Symbol(ExpandoMerge.p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) ExpandoMerge.p7 = 777777; >ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p7 : Symbol(ExpandoMerge.p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) ExpandoMerge.p8 = false; // type error >ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p8 : Symbol(ExpandoMerge.p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) ExpandoMerge.p9 = false; // type error >ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p9 : Symbol(ExpandoMerge.p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); >n : Symbol(n, Decl(expando.ts, 13, 3)) >ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) >ExpandoMerge.p2 : Symbol(ExpandoMerge.p2, Decl(ns.ts, 10, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p2 : Symbol(ExpandoMerge.p2, Decl(ns.ts, 10, 14)) >ExpandoMerge.p3 : Symbol(ExpandoMerge.p3, Decl(ns.ts, 1, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p3 : Symbol(ExpandoMerge.p3, Decl(ns.ts, 1, 14)) >ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p4 : Symbol(ExpandoMerge.p4, Decl(expando.ts, 6, 1), Decl(ns.ts, 2, 14)) >ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p5 : Symbol(ExpandoMerge.p5, Decl(expando.ts, 7, 24), Decl(ns.ts, 3, 14)) >ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p6 : Symbol(ExpandoMerge.p6, Decl(expando.ts, 8, 25), Decl(ns.ts, 4, 14)) >ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p7 : Symbol(ExpandoMerge.p7, Decl(expando.ts, 9, 24), Decl(ns.ts, 5, 14)) >ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p8 : Symbol(ExpandoMerge.p8, Decl(expando.ts, 10, 25), Decl(ns.ts, 6, 14)) >ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >p9 : Symbol(ExpandoMerge.p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) >ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) >m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) === tests/cases/conformance/salsa/ns.ts === namespace ExpandoMerge { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) export var p3 = 333; >p3 : Symbol(p3, Decl(ns.ts, 1, 14)) @@ -110,7 +110,7 @@ namespace ExpandoMerge { >p9 : Symbol(p9, Decl(expando.ts, 11, 24), Decl(ns.ts, 7, 14)) } namespace ExpandoMerge { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1), Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1)) export var p2 = 222; >p2 : Symbol(p2, Decl(ns.ts, 10, 14)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment33.symbols b/tests/baselines/reference/typeFromPropertyAssignment33.symbols index 7b21df91b96..2bdaebbbfdd 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment33.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment33.symbols @@ -1,6 +1,6 @@ === tests/cases/conformance/salsa/ns.ts === namespace ExpandoMerge { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) export var p3 = 333; >p3 : Symbol(p3, Decl(ns.ts, 1, 14)) @@ -24,7 +24,7 @@ namespace ExpandoMerge { >p9 : Symbol(p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) } namespace ExpandoMerge { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) export var p2 = 222; >p2 : Symbol(p2, Decl(ns.ts, 10, 14)) @@ -33,7 +33,7 @@ namespace ExpandoMerge { === tests/cases/conformance/salsa/expando.ts === function ExpandoMerge(n: number) { ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >n : Symbol(n, Decl(expando.ts, 0, 22)) return n; @@ -41,12 +41,12 @@ function ExpandoMerge(n: number) { } ExpandoMerge.p1 = 111 >ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) ExpandoMerge.m = function(n: number) { >ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) >n : Symbol(n, Decl(expando.ts, 4, 26)) @@ -55,66 +55,66 @@ ExpandoMerge.m = function(n: number) { } ExpandoMerge.p4 = 44444; >ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p4 : Symbol(ExpandoMerge.p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) ExpandoMerge.p5 = 555555; >ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p5 : Symbol(ExpandoMerge.p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) ExpandoMerge.p6 = 66666; >ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p6 : Symbol(ExpandoMerge.p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) ExpandoMerge.p7 = 777777; >ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p7 : Symbol(ExpandoMerge.p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) ExpandoMerge.p8 = false; // type error >ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p8 : Symbol(ExpandoMerge.p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) ExpandoMerge.p9 = false; // type error >ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p9 : Symbol(ExpandoMerge.p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) var n = ExpandoMerge.p1 + ExpandoMerge.p2 + ExpandoMerge.p3 + ExpandoMerge.p4 + ExpandoMerge.p5 + ExpandoMerge.p6 + ExpandoMerge.p7 + ExpandoMerge.p8 + ExpandoMerge.p9 + ExpandoMerge.m(12) + ExpandoMerge(1001); >n : Symbol(n, Decl(expando.ts, 13, 3)) >ExpandoMerge.p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p1 : Symbol(ExpandoMerge.p1, Decl(expando.ts, 2, 1)) >ExpandoMerge.p2 : Symbol(ExpandoMerge.p2, Decl(ns.ts, 10, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p2 : Symbol(ExpandoMerge.p2, Decl(ns.ts, 10, 14)) >ExpandoMerge.p3 : Symbol(ExpandoMerge.p3, Decl(ns.ts, 1, 14)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p3 : Symbol(ExpandoMerge.p3, Decl(ns.ts, 1, 14)) >ExpandoMerge.p4 : Symbol(ExpandoMerge.p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p4 : Symbol(ExpandoMerge.p4, Decl(ns.ts, 2, 14), Decl(expando.ts, 6, 1)) >ExpandoMerge.p5 : Symbol(ExpandoMerge.p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p5 : Symbol(ExpandoMerge.p5, Decl(ns.ts, 3, 14), Decl(expando.ts, 7, 24)) >ExpandoMerge.p6 : Symbol(ExpandoMerge.p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p6 : Symbol(ExpandoMerge.p6, Decl(ns.ts, 4, 14), Decl(expando.ts, 8, 25)) >ExpandoMerge.p7 : Symbol(ExpandoMerge.p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p7 : Symbol(ExpandoMerge.p7, Decl(ns.ts, 5, 14), Decl(expando.ts, 9, 24)) >ExpandoMerge.p8 : Symbol(ExpandoMerge.p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p8 : Symbol(ExpandoMerge.p8, Decl(ns.ts, 6, 14), Decl(expando.ts, 10, 25)) >ExpandoMerge.p9 : Symbol(ExpandoMerge.p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >p9 : Symbol(ExpandoMerge.p9, Decl(ns.ts, 7, 14), Decl(expando.ts, 11, 24)) >ExpandoMerge.m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) >m : Symbol(ExpandoMerge.m, Decl(expando.ts, 3, 21)) ->ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 3, 21)) +>ExpandoMerge : Symbol(ExpandoMerge, Decl(ns.ts, 0, 0), Decl(ns.ts, 8, 1), Decl(expando.ts, 0, 0), Decl(expando.ts, 2, 1)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment34.symbols b/tests/baselines/reference/typeFromPropertyAssignment34.symbols new file mode 100644 index 00000000000..fb9984c1a87 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment34.symbols @@ -0,0 +1,24 @@ +=== tests/cases/conformance/salsa/file1.js === +var N = {}; +>N : Symbol(N, Decl(file1.js, 0, 3), Decl(file1.js, 0, 11), Decl(file2.js, 0, 0)) + +N.commands = {}; +>N.commands : Symbol(N.commands, Decl(file1.js, 0, 11), Decl(file2.js, 0, 2)) +>N : Symbol(N, Decl(file1.js, 0, 3), Decl(file1.js, 0, 11), Decl(file2.js, 0, 0)) +>commands : Symbol(N.commands, Decl(file1.js, 0, 11), Decl(file2.js, 0, 2)) + +=== tests/cases/conformance/salsa/file2.js === +N.commands.a = 111; +>N.commands.a : Symbol(N.commands.a, Decl(file2.js, 0, 0)) +>N.commands : Symbol(N.commands, Decl(file1.js, 0, 11), Decl(file2.js, 0, 2)) +>N : Symbol(N, Decl(file1.js, 0, 3), Decl(file1.js, 0, 11), Decl(file2.js, 0, 0)) +>commands : Symbol(N.commands, Decl(file1.js, 0, 11), Decl(file2.js, 0, 2)) +>a : Symbol(N.commands.a, Decl(file2.js, 0, 0)) + +N.commands.b = function () { }; +>N.commands.b : Symbol(N.commands.b, Decl(file2.js, 0, 19)) +>N.commands : Symbol(N.commands, Decl(file1.js, 0, 11), Decl(file2.js, 0, 2)) +>N : Symbol(N, Decl(file1.js, 0, 3), Decl(file1.js, 0, 11), Decl(file2.js, 0, 0)) +>commands : Symbol(N.commands, Decl(file1.js, 0, 11), Decl(file2.js, 0, 2)) +>b : Symbol(N.commands.b, Decl(file2.js, 0, 19)) + diff --git a/tests/baselines/reference/typeFromPropertyAssignment34.types b/tests/baselines/reference/typeFromPropertyAssignment34.types new file mode 100644 index 00000000000..ee59c928322 --- /dev/null +++ b/tests/baselines/reference/typeFromPropertyAssignment34.types @@ -0,0 +1,31 @@ +=== tests/cases/conformance/salsa/file1.js === +var N = {}; +>N : typeof N +>{} : {} + +N.commands = {}; +>N.commands = {} : typeof N.commands +>N.commands : typeof N.commands +>N : typeof N +>commands : typeof N.commands +>{} : {} + +=== tests/cases/conformance/salsa/file2.js === +N.commands.a = 111; +>N.commands.a = 111 : 111 +>N.commands.a : number +>N.commands : typeof N.commands +>N : typeof N +>commands : typeof N.commands +>a : number +>111 : 111 + +N.commands.b = function () { }; +>N.commands.b = function () { } : () => void +>N.commands.b : () => void +>N.commands : typeof N.commands +>N : typeof N +>commands : typeof N.commands +>b : () => void +>function () { } : () => void + diff --git a/tests/cases/conformance/salsa/typeFromPropertyAssignment34.ts b/tests/cases/conformance/salsa/typeFromPropertyAssignment34.ts new file mode 100644 index 00000000000..1c6be8f0171 --- /dev/null +++ b/tests/cases/conformance/salsa/typeFromPropertyAssignment34.ts @@ -0,0 +1,10 @@ +// @noEmit: true +// @allowjs: true +// @checkjs: true +// @Filename: file1.js +var N = {}; +N.commands = {}; + +// @Filename: file2.js +N.commands.a = 111; +N.commands.b = function () { }; diff --git a/tests/cases/fourslash/functionTypes.ts b/tests/cases/fourslash/functionTypes.ts index 6ddba777ae0..5ef931a602d 100644 --- a/tests/cases/fourslash/functionTypes.ts +++ b/tests/cases/fourslash/functionTypes.ts @@ -21,4 +21,10 @@ ////l./*7*/prototype = Object.prototype; verify.noErrors(); -verify.completionsAt(test.markerNames(), ["apply", "call", "bind", "toString", "prototype", "length", "arguments", "caller" ]); +verify.completionsAt('1', ["apply", "call", "bind", "toString", "prototype", "length", "arguments", "caller" ]); +verify.completionsAt('2', ["apply", "call", "bind", "toString", "prototype", "length", "arguments", "caller" ]); +verify.completionsAt('3', ["apply", "call", "bind", "toString", "prototype", "length", "arguments", "caller" ]); +verify.completionsAt('4', ["apply", "call", "bind", "toString", "prototype", "length", "arguments", "caller" ]); +verify.completionsAt('5', ["apply", "call", "bind", "toString", "prototype", "length", "arguments", "caller" ]); +verify.completionsAt('6', ["apply", "call", "bind", "toString", "prototype", "length", "arguments", "caller" ]); +verify.completionsAt('7', ["prototype", "apply", "call", "bind", "toString", "length", "arguments", "caller" ]); diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames7.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames7.ts index 01e6d424673..98a6dc2ac47 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames7.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames7.ts @@ -6,7 +6,7 @@ ////var x = { "[|{| "isWriteAccess": true, "isDefinition": true |}someProperty|]": 0 } ////x["[|someProperty|]"] = 3; -////x.[|{| "isWriteAccess": true, "isDefinition": false |}someProperty|] = 5; +////x.[|{| "isWriteAccess": true, "isDefinition": true |}someProperty|] = 5; const ranges = test.ranges(); const [r0, r1, r2] = ranges; From 06774962eda2abc72115f25018e2be9aac3371e4 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 5 Sep 2018 11:19:32 -0700 Subject: [PATCH 150/163] Properly handle JS enum symbols (#26893) --- src/compiler/binder.ts | 11 +++++---- src/compiler/checker.ts | 10 +++++---- tests/cases/fourslash/quickInfoJsdocEnum.ts | 25 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 tests/cases/fourslash/quickInfoJsdocEnum.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1fe5605b498..5e7ce50a86f 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1731,10 +1731,6 @@ namespace ts { } } - function bindBlockScopedVariableDeclaration(node: Declaration) { - bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes); - } - function delayedBindJSDocTypedefTag() { if (!delayedTypeAliases) { return; @@ -2659,8 +2655,11 @@ namespace ts { } if (!isBindingPattern(node.name)) { + const isEnum = !!getJSDocEnumTag(node); + const enumFlags = (isEnum ? SymbolFlags.RegularEnum : SymbolFlags.None); + const enumExcludes = (isEnum ? SymbolFlags.RegularEnumExcludes : SymbolFlags.None); if (isBlockOrCatchScoped(node)) { - bindBlockScopedVariableDeclaration(node); + bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable | enumFlags, SymbolFlags.BlockScopedVariableExcludes | enumExcludes); } else if (isParameterDeclaration(node)) { // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration @@ -2675,7 +2674,7 @@ namespace ts { declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes); } else { - declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes); + declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable | enumFlags, SymbolFlags.FunctionScopedVariableExcludes | enumExcludes); } } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ec880fc0cc4..efe1061a531 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8208,6 +8208,12 @@ namespace ts { return type; } + // JS are 'string' or 'number', not an enum type. + const enumTag = symbol.valueDeclaration && getJSDocEnumTag(symbol.valueDeclaration); + if (enumTag) { + return enumTag.typeExpression ? getTypeFromTypeNode(enumTag.typeExpression) : errorType; + } + // Get type from reference to named type that cannot be generic (enum or type parameter) const res = tryGetDeclaredTypeOfSymbol(symbol); if (res) { @@ -8243,10 +8249,6 @@ namespace ts { // TODO: GH#18217 (should the `|| assignedType` be at a lower precedence?) return (referenceType && assignedType ? getIntersectionType([assignedType, referenceType]) : referenceType || assignedType)!; } - const enumTag = getJSDocEnumTag(symbol.valueDeclaration); - if (enumTag && enumTag.typeExpression) { - return getTypeFromTypeNode(enumTag.typeExpression); - } } function getTypeReferenceTypeWorker(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type | undefined { diff --git a/tests/cases/fourslash/quickInfoJsdocEnum.ts b/tests/cases/fourslash/quickInfoJsdocEnum.ts new file mode 100644 index 00000000000..de67cacc7d2 --- /dev/null +++ b/tests/cases/fourslash/quickInfoJsdocEnum.ts @@ -0,0 +1,25 @@ +/// + +// @allowJs: true +// @noLib: true + +// @Filename: /a.js +/////** +//// * Doc +//// * @enum {number} +//// */ +////const E = { +//// A: 0, +////} +//// +/////** @type {/**/E} */ +////const x = E.A; + +verify.noErrors(); + +verify.quickInfoAt("", +`enum E +const E: { + A: number; +}`, +"Doc"); From bcb815b3acee0e25baca58b0d95160f8265e5714 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 5 Sep 2018 11:19:56 -0700 Subject: [PATCH 151/163] Remove duplicate function createTextRange (#23346) * Remove duplicate function createTextRange * Always allow end=-1 * Put noAssert back, pending #23370 * Use getRangeUnion helper * Update API (#24966) --- src/compiler/transformers/es2015.ts | 20 ++++++++++++----- src/compiler/utilities.ts | 9 ++------ src/services/codefixes/convertToEs6Module.ts | 2 +- src/services/getEditsForFileRename.ts | 2 +- src/services/textChanges.ts | 16 +++++++------- src/services/utilities.ts | 4 ++-- ...ationDestructuringVariableStatement.js.map | 2 +- ...structuringVariableStatement.sourcemap.txt | 6 ++--- ...tionDestructuringVariableStatement1.js.map | 2 +- ...tructuringVariableStatement1.sourcemap.txt | 6 ++--- ...ariableStatementArrayBindingPattern.js.map | 2 +- ...StatementArrayBindingPattern.sourcemap.txt | 6 ++--- ...riableStatementArrayBindingPattern2.js.map | 2 +- ...tatementArrayBindingPattern2.sourcemap.txt | 12 +++++----- ...riableStatementArrayBindingPattern5.js.map | 2 +- ...tatementArrayBindingPattern5.sourcemap.txt | 6 ++--- ...riableStatementArrayBindingPattern7.js.map | 2 +- ...tatementArrayBindingPattern7.sourcemap.txt | 6 ++--- ...entArrayBindingPatternDefaultValues.js.map | 2 +- ...yBindingPatternDefaultValues.sourcemap.txt | 6 ++--- ...ntArrayBindingPatternDefaultValues2.js.map | 2 +- ...BindingPatternDefaultValues2.sourcemap.txt | 12 +++++----- ...uringVariableStatementDefaultValues.js.map | 2 +- ...riableStatementDefaultValues.sourcemap.txt | 6 ++--- ...StatementNestedObjectBindingPattern.js.map | 2 +- ...ntNestedObjectBindingPattern.sourcemap.txt | 18 +++++++-------- ...jectBindingPatternWithDefaultValues.js.map | 2 +- ...dingPatternWithDefaultValues.sourcemap.txt | 22 +++++++++---------- ...iableStatementObjectBindingPattern2.js.map | 2 +- ...atementObjectBindingPattern2.sourcemap.txt | 6 ++--- ...iableStatementObjectBindingPattern4.js.map | 2 +- ...atementObjectBindingPattern4.sourcemap.txt | 6 ++--- 32 files changed, 100 insertions(+), 97 deletions(-) diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index bffdc5809b0..dcb0d9ac208 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2060,14 +2060,11 @@ namespace ts { setTextRange(declarationList, node); setCommentRange(declarationList, node); + // If the first or last declaration is a binding pattern, we need to modify + // the source map range for the declaration list. if (node.transformFlags & TransformFlags.ContainsBindingPattern && (isBindingPattern(node.declarations[0].name) || isBindingPattern(last(node.declarations).name))) { - // If the first or last declaration is a binding pattern, we need to modify - // the source map range for the declaration list. - const firstDeclaration = firstOrUndefined(declarations); - if (firstDeclaration) { - setSourceMapRange(declarationList, createRange(firstDeclaration.pos, last(declarations).end)); - } + setSourceMapRange(declarationList, getRangeUnion(declarations)); } return declarationList; @@ -2075,6 +2072,17 @@ namespace ts { return visitEachChild(node, visitor, context); } + function getRangeUnion(declarations: ReadonlyArray): TextRange { + // declarations may not be sorted by position. + // pos should be the minimum* position over all nodes (that's not -1), end should be the maximum end over all nodes. + let pos = -1, end = -1; + for (const node of declarations) { + pos = pos === -1 ? node.pos : node.pos === -1 ? pos : Math.min(pos, node.pos); + end = Math.max(end, node.end); + } + return createRange(pos, end); + } + /** * Gets a value indicating whether we should emit an explicit initializer for a variable * declaration in a `let` declaration list. diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3d5893d0a03..b05e45bd13d 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4056,7 +4056,8 @@ namespace ts { * @param pos The start position. * @param end The end position. */ - export function createRange(pos: number, end: number): TextRange { + export function createRange(pos: number, end: number = pos): TextRange { + Debug.assert(end >= pos || end === -1); return { pos, end }; } @@ -4520,12 +4521,6 @@ namespace ts { return { start, length }; } - /* @internal */ - export function createTextRange(pos: number, end: number = pos): TextRange { - Debug.assert(end >= pos); - return { pos, end }; - } - export function createTextSpanFromBounds(start: number, end: number) { return createTextSpan(start, end - start); } diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index 87a1f49cc48..65ea757d060 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -208,7 +208,7 @@ namespace ts.codefix { return replacement[1]; } else { - changes.replaceRangeWithText(sourceFile, createTextRange(left.getStart(sourceFile), right.pos), "export default"); + changes.replaceRangeWithText(sourceFile, createRange(left.getStart(sourceFile), right.pos), "export default"); return true; } } diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 4fe024787f3..07c3eb7ad22 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -221,7 +221,7 @@ namespace ts { } function createStringRange(node: StringLiteralLike, sourceFile: SourceFileLike): TextRange { - return createTextRange(node.getStart(sourceFile) + 1, node.end - 1); + return createRange(node.getStart(sourceFile) + 1, node.end - 1); } function forEachProperty(objectLiteral: Expression, cb: (property: PropertyAssignment, propertyName: string) => void) { diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 51e60d08741..32d6360e90c 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -291,7 +291,7 @@ namespace ts.textChanges { } public insertNodeAt(sourceFile: SourceFile, pos: number, newNode: Node, options: InsertNodeOptions = {}) { - this.replaceRange(sourceFile, createTextRange(pos), newNode, options); + this.replaceRange(sourceFile, createRange(pos), newNode, options); } private insertNodesAt(sourceFile: SourceFile, pos: number, newNodes: ReadonlyArray, options: ReplaceWithMultipleNodesOptions = {}): void { @@ -334,7 +334,7 @@ namespace ts.textChanges { } public insertText(sourceFile: SourceFile, pos: number, text: string): void { - this.replaceRangeWithText(sourceFile, createTextRange(pos), text); + this.replaceRangeWithText(sourceFile, createRange(pos), text); } /** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */ @@ -456,7 +456,7 @@ namespace ts.textChanges { // check if previous statement ends with semicolon // if not - insert semicolon to preserve the code from changing the meaning due to ASI if (sourceFile.text.charCodeAt(after.end - 1) !== CharacterCodes.semicolon) { - this.replaceRange(sourceFile, createTextRange(after.end), createToken(SyntaxKind.SemicolonToken)); + this.replaceRange(sourceFile, createRange(after.end), createToken(SyntaxKind.SemicolonToken)); } } const endPosition = getAdjustedEndPosition(sourceFile, after, {}); @@ -595,7 +595,7 @@ namespace ts.textChanges { // write separator and leading trivia of the next element as suffix const suffix = `${tokenToString(nextToken.kind)}${sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile))}`; - this.replaceRange(sourceFile, createTextRange(startPos, containingList[index + 1].getStart(sourceFile)), newNode, { prefix, suffix }); + this.replaceRange(sourceFile, createRange(startPos, containingList[index + 1].getStart(sourceFile)), newNode, { prefix, suffix }); } } else { @@ -629,7 +629,7 @@ namespace ts.textChanges { } if (multilineList) { // insert separator immediately following the 'after' node to preserve comments in trailing trivia - this.replaceRange(sourceFile, createTextRange(end), createToken(separator)); + this.replaceRange(sourceFile, createRange(end), createToken(separator)); // use the same indentation as 'after' item const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options); // insert element before the line break on the line that contains 'after' element @@ -637,10 +637,10 @@ namespace ts.textChanges { if (insertPos !== end && isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) { insertPos--; } - this.replaceRange(sourceFile, createTextRange(insertPos), newNode, { indentation, prefix: this.newLineCharacter }); + this.replaceRange(sourceFile, createRange(insertPos), newNode, { indentation, prefix: this.newLineCharacter }); } else { - this.replaceRange(sourceFile, createTextRange(end), newNode, { prefix: `${tokenToString(separator)} ` }); + this.replaceRange(sourceFile, createRange(end), newNode, { prefix: `${tokenToString(separator)} ` }); } } return this; @@ -652,7 +652,7 @@ namespace ts.textChanges { const [openBraceEnd, closeBraceEnd] = getClassBraceEnds(cls, sourceFile); // For `class C { }` remove the whitespace inside the braces. if (positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) { - this.deleteRange(sourceFile, createTextRange(openBraceEnd, closeBraceEnd - 1)); + this.deleteRange(sourceFile, createRange(openBraceEnd, closeBraceEnd - 1)); } }); } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9e7b823fe54..c3d4cd9a390 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1165,7 +1165,7 @@ namespace ts { } export function createTextRangeFromNode(node: Node, sourceFile: SourceFile): TextRange { - return createTextRange(node.getStart(sourceFile), node.end); + return createRange(node.getStart(sourceFile), node.end); } export function createTextSpanFromRange(range: TextRange): TextSpan { @@ -1173,7 +1173,7 @@ namespace ts { } export function createTextRangeFromSpan(span: TextSpan): TextRange { - return createTextRange(span.start, span.start + span.length); + return createRange(span.start, span.start + span.length); } export function createTextChangeFromStartLength(start: number, length: number, newText: string): TextChange { diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement.js.map index 0dff86fd1d4..1f97726f1a7 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatement.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatement.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatement.ts"],"names":[],"mappings":"AAOA,IAAI,KAAK,GAAG,OAAO,CAAC;AACpB,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACvD,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACrD,IAAA,mBAAW,CAAY;AACvB,IAAA,mBAAW,EAAE,qBAAa,CAAY;AACxC,IAAA,8CAA0E,EAAxE,eAAW,EAAE,iBAAa,CAA+C;AAC/E,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatement.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatement.ts"],"names":[],"mappings":"AAOA,IAAI,KAAK,GAAG,OAAO,CAAC;AACpB,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACvD,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACrD,IAAA,mBAAW,CAAY;AACvB,IAAA,mBAAW,EAAE,qBAAa,CAAY;AACxC,IAAA,8CAA0E,EAAxE,eAAW,EAAE,iBAA2D,CAAC;AAC/E,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement.sourcemap.txt index c00af2dfdbc..5ff8c099993 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement.sourcemap.txt @@ -181,15 +181,15 @@ sourceFile:sourceMapValidationDestructuringVariableStatement.ts 4 > 5 > name: nameC 6 > , -7 > skill: skillC -8 > } = { name: "Edger", skill: "cutting edges" }; +7 > skill: skillC } = { name: "Edger", skill: "cutting edges" } +8 > ; 1->Emitted(6, 1) Source(13, 5) + SourceIndex(0) 2 >Emitted(6, 5) Source(13, 5) + SourceIndex(0) 3 >Emitted(6, 51) Source(13, 79) + SourceIndex(0) 4 >Emitted(6, 53) Source(13, 7) + SourceIndex(0) 5 >Emitted(6, 68) Source(13, 18) + SourceIndex(0) 6 >Emitted(6, 70) Source(13, 20) + SourceIndex(0) -7 >Emitted(6, 87) Source(13, 33) + SourceIndex(0) +7 >Emitted(6, 87) Source(13, 79) + SourceIndex(0) 8 >Emitted(6, 88) Source(13, 80) + SourceIndex(0) --- >>>if (nameA == nameB) { diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement1.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement1.js.map index 5b9c754af1b..76680cf4481 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement1.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement1.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatement1.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatement1.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatement1.ts"],"names":[],"mappings":"AAOA,IAAI,KAAK,GAAG,OAAO,CAAC;AACpB,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACvD,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACvD,IAAA,CAAS,EAAI,mBAAW,CAAY;AACpC,IAAA,CAAS,EAAI,mBAAW,EAAE,qBAAa,CAAY;AACnD,IAAA,CAAS,EAAE,8CAA0E,EAAxE,eAAW,EAAE,iBAAa,CAA+C;AAEpF,IAAA,mBAAW,EAAa,CAAC,GAAG,KAAK,CAAC;AAClC,IAAA,mBAAW,EAAE,qBAAa,EAAa,CAAC,GAAG,QAAQ,CAAC;AACtD,IAAA,8CAA0E,EAAxE,eAAW,EAAE,iBAAa,EAAgD,CAAC,GAAG,KAAK,CAAC;AAE1F,IAAI,CAAC,GAAG,KAAK,EAAI,mBAAW,EAAa,EAAE,GAAE,OAAO,CAAC;AACrD,IAAI,CAAC,GAAG,KAAK,EAAI,mBAAW,EAAE,qBAAa,EAAa,EAAE,GAAG,OAAO,CAAC;AACrE,IAAI,CAAC,GAAG,KAAK,EAAE,8CAA0E,EAAxE,eAAW,EAAE,iBAAa,EAAgD,EAAE,GAAG,KAAK,CAAC;AACtG,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatement1.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatement1.ts"],"names":[],"mappings":"AAOA,IAAI,KAAK,GAAG,OAAO,CAAC;AACpB,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACvD,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACvD,IAAA,CAAS,EAAI,mBAAW,CAAY;AACpC,IAAA,CAAS,EAAI,mBAAW,EAAE,qBAAa,CAAY;AACnD,IAAA,CAAS,EAAE,8CAA0E,EAAxE,eAAW,EAAE,iBAA2D,CAAC;AAEpF,IAAA,mBAAW,EAAa,CAAC,GAAG,KAAK,CAAC;AAClC,IAAA,mBAAW,EAAE,qBAAa,EAAa,CAAC,GAAG,QAAQ,CAAC;AACtD,IAAA,8CAA0E,EAAxE,eAAW,EAAE,iBAAa,EAAgD,CAAC,GAAG,KAAK,CAAC;AAE1F,IAAI,CAAC,GAAG,KAAK,EAAI,mBAAW,EAAa,EAAE,GAAE,OAAO,CAAC;AACrD,IAAI,CAAC,GAAG,KAAK,EAAI,mBAAW,EAAE,qBAAa,EAAa,EAAE,GAAG,OAAO,CAAC;AACrE,IAAI,CAAC,GAAG,KAAK,EAAE,8CAA0E,EAAxE,eAAW,EAAE,iBAAa,EAAgD,EAAE,GAAG,KAAK,CAAC;AACtG,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement1.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement1.sourcemap.txt index 16a63b61c34..bddfdd1c4d2 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement1.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatement1.sourcemap.txt @@ -197,8 +197,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatement1.ts 6 > 7 > name: nameC 8 > , -9 > skill: skillC -10> } = { name: "Edger", skill: "cutting edges" }; +9 > skill: skillC } = { name: "Edger", skill: "cutting edges" } +10> ; 1->Emitted(6, 1) Source(13, 5) + SourceIndex(0) 2 >Emitted(6, 5) Source(13, 5) + SourceIndex(0) 3 >Emitted(6, 6) Source(13, 14) + SourceIndex(0) @@ -207,7 +207,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatement1.ts 6 >Emitted(6, 56) Source(13, 18) + SourceIndex(0) 7 >Emitted(6, 71) Source(13, 29) + SourceIndex(0) 8 >Emitted(6, 73) Source(13, 31) + SourceIndex(0) -9 >Emitted(6, 90) Source(13, 44) + SourceIndex(0) +9 >Emitted(6, 90) Source(13, 90) + SourceIndex(0) 10>Emitted(6, 91) Source(13, 91) + SourceIndex(0) --- >>>var nameA = robotA.name, a = hello; diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern.js.map index 919575fe393..d619484eefe 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementArrayBindingPattern.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPattern.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPattern.ts"],"names":[],"mappings":"AAIA,IAAI,MAAM,GAAU,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3C,IAAI,MAAM,GAAU,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAGxC,IAAA,iBAAK,CAAW;AAClB,IAAA,mBAAO,CAAW;AAClB,IAAA,oBAAQ,EAAE,kBAAM,EAAE,mBAAO,CAAW;AAEpC,IAAA,6CAAQ,CAAoC;AAC7C,IAAA,oCAA0D,EAAzD,eAAO,EAAE,aAAK,EAAE,cAAM,CAAoC;AAE1D,IAAA,oBAAQ,EAAE,4BAAa,CAAW;AAEvC,IAAI,KAAK,IAAI,MAAM,EAAE;IACjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;CACxB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPattern.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPattern.ts"],"names":[],"mappings":"AAIA,IAAI,MAAM,GAAU,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3C,IAAI,MAAM,GAAU,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAGxC,IAAA,iBAAK,CAAW;AAClB,IAAA,mBAAO,CAAW;AAClB,IAAA,oBAAQ,EAAE,kBAAM,EAAE,mBAAO,CAAW;AAEpC,IAAA,6CAAQ,CAAoC;AAC7C,IAAA,oCAA0D,EAAzD,eAAO,EAAE,aAAK,EAAE,cAAyC,CAAC;AAE1D,IAAA,oBAAQ,EAAE,4BAAa,CAAW;AAEvC,IAAI,KAAK,IAAI,MAAM,EAAE;IACjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;CACxB"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern.sourcemap.txt index da763a77037..308e55de910 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern.sourcemap.txt @@ -188,8 +188,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern. 6 > , 7 > nameC 8 > , -9 > skillC -10> ] = [3, "edging", "Trimming edges"]; +9 > skillC] = [3, "edging", "Trimming edges"] +10> ; 1->Emitted(7, 1) Source(14, 5) + SourceIndex(0) 2 >Emitted(7, 5) Source(14, 5) + SourceIndex(0) 3 >Emitted(7, 41) Source(14, 63) + SourceIndex(0) @@ -198,7 +198,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern. 6 >Emitted(7, 60) Source(14, 15) + SourceIndex(0) 7 >Emitted(7, 73) Source(14, 20) + SourceIndex(0) 8 >Emitted(7, 75) Source(14, 22) + SourceIndex(0) -9 >Emitted(7, 89) Source(14, 28) + SourceIndex(0) +9 >Emitted(7, 89) Source(14, 63) + SourceIndex(0) 10>Emitted(7, 90) Source(14, 64) + SourceIndex(0) --- >>>var numberA3 = robotA[0], robotAInfo = robotA.slice(1); diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.js.map index f33092aef99..59de11c1256 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.ts"],"names":[],"mappings":"AAIA,IAAI,WAAW,GAAsB,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/D,IAAI,WAAW,GAAsB,CAAC,SAAS,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAElE,IAAA,uBAAM,CAAgB;AACxB,IAAA,uBAAM,CAAgB;AACtB,IAAA,uBAAM,EAAE,mBAAgC,EAA/B,qBAAa,EAAE,uBAAe,CAAiB;AAExD,IAAA,6CAAM,CAAsC;AAC7C,IAAA,sCAA+E,EAA9E,eAAO,EAAE,UAAgC,EAA/B,qBAAa,EAAE,uBAAe,CAAuC;AAE/E,IAAA,sCAAkB,CAAgB;AAEvC,IAAI,MAAM,IAAI,MAAM,EAAE;IAClB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.ts"],"names":[],"mappings":"AAIA,IAAI,WAAW,GAAsB,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/D,IAAI,WAAW,GAAsB,CAAC,SAAS,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAElE,IAAA,uBAAM,CAAgB;AACxB,IAAA,uBAAM,CAAgB;AACtB,IAAA,uBAAM,EAAE,mBAAgC,EAA/B,qBAAa,EAAE,uBAAgB,CAAgB;AAExD,IAAA,6CAAM,CAAsC;AAC7C,IAAA,sCAA+E,EAA9E,eAAO,EAAE,UAAgC,EAA/B,qBAAa,EAAE,uBAAqD,CAAC;AAE/E,IAAA,sCAAkB,CAAgB;AAEvC,IAAI,MAAM,IAAI,MAAM,EAAE;IAClB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.sourcemap.txt index d445ea559c9..12f78509a8e 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern2.sourcemap.txt @@ -155,8 +155,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern2 6 > 7 > primarySkillA 8 > , -9 > secondarySkillA -10> ]] = multiRobotA; +9 > secondarySkillA] +10> ] = multiRobotA; 1->Emitted(5, 1) Source(10, 6) + SourceIndex(0) 2 >Emitted(5, 5) Source(10, 6) + SourceIndex(0) 3 >Emitted(5, 28) Source(10, 12) + SourceIndex(0) @@ -165,7 +165,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern2 6 >Emitted(5, 51) Source(10, 15) + SourceIndex(0) 7 >Emitted(5, 72) Source(10, 28) + SourceIndex(0) 8 >Emitted(5, 74) Source(10, 30) + SourceIndex(0) -9 >Emitted(5, 97) Source(10, 45) + SourceIndex(0) +9 >Emitted(5, 97) Source(10, 46) + SourceIndex(0) 10>Emitted(5, 98) Source(10, 62) + SourceIndex(0) --- >>>var nameMC = ["roomba", ["vaccum", "mopping"]][0]; @@ -209,8 +209,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern2 8 > 9 > primarySkillC 10> , -11> secondarySkillC -12> ]] = ["roomba", ["vaccum", "mopping"]]; +11> secondarySkillC]] = ["roomba", ["vaccum", "mopping"]] +12> ; 1->Emitted(7, 1) Source(13, 5) + SourceIndex(0) 2 >Emitted(7, 5) Source(13, 5) + SourceIndex(0) 3 >Emitted(7, 43) Source(13, 84) + SourceIndex(0) @@ -221,7 +221,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern2 8 >Emitted(7, 74) Source(13, 16) + SourceIndex(0) 9 >Emitted(7, 95) Source(13, 29) + SourceIndex(0) 10>Emitted(7, 97) Source(13, 31) + SourceIndex(0) -11>Emitted(7, 120) Source(13, 46) + SourceIndex(0) +11>Emitted(7, 120) Source(13, 84) + SourceIndex(0) 12>Emitted(7, 121) Source(13, 85) + SourceIndex(0) --- >>>var multiRobotAInfo = multiRobotA.slice(0); diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.js.map index 456a64e7f34..96ea969b41a 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.ts"],"names":[],"mappings":"AAAK,IAAA,aAAC,CAAW;AACb,IAAA,WAAe,EAAd,SAAC,EAAE,SAAC,CAAW"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.ts"],"names":[],"mappings":"AAAK,IAAA,aAAC,CAAW;AACb,IAAA,WAAe,EAAd,SAAC,EAAE,SAAW,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.sourcemap.txt index 2603b53c456..834b62af310 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.sourcemap.txt @@ -40,15 +40,15 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern5 4 > 5 > y 6 > , -7 > z -8 > ] = [1, 2]; +7 > z] = [1, 2] +8 > ; 1->Emitted(2, 1) Source(2, 5) + SourceIndex(0) 2 >Emitted(2, 5) Source(2, 5) + SourceIndex(0) 3 >Emitted(2, 16) Source(2, 20) + SourceIndex(0) 4 >Emitted(2, 18) Source(2, 6) + SourceIndex(0) 5 >Emitted(2, 27) Source(2, 7) + SourceIndex(0) 6 >Emitted(2, 29) Source(2, 9) + SourceIndex(0) -7 >Emitted(2, 38) Source(2, 10) + SourceIndex(0) +7 >Emitted(2, 38) Source(2, 20) + SourceIndex(0) 8 >Emitted(2, 39) Source(2, 21) + SourceIndex(0) --- >>>//# sourceMappingURL=sourceMapValidationDestructuringVariableStatementArrayBindingPattern5.js.map \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.js.map index 94422f76145..0b43806d517 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.ts"],"names":[],"mappings":"AAAI,IAAA,WAAoB,EAAnB,UAAM,EAAN,2BAAM,EAAE,SAAC,CAAW"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.ts"],"names":[],"mappings":"AAAI,IAAA,WAAoB,EAAnB,UAAM,EAAN,2BAAM,EAAE,SAAW,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.sourcemap.txt index 2a088a1dc82..db14204bda7 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.sourcemap.txt @@ -28,8 +28,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern7 6 > 7 > x = 20 8 > , -9 > j -10> ] = [1, 2]; +9 > j] = [1, 2] +10> ; 1 >Emitted(1, 1) Source(1, 5) + SourceIndex(0) 2 >Emitted(1, 5) Source(1, 5) + SourceIndex(0) 3 >Emitted(1, 16) Source(1, 25) + SourceIndex(0) @@ -38,7 +38,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPattern7 6 >Emitted(1, 30) Source(1, 6) + SourceIndex(0) 7 >Emitted(1, 57) Source(1, 12) + SourceIndex(0) 8 >Emitted(1, 59) Source(1, 14) + SourceIndex(0) -9 >Emitted(1, 68) Source(1, 15) + SourceIndex(0) +9 >Emitted(1, 68) Source(1, 25) + SourceIndex(0) 10>Emitted(1, 69) Source(1, 26) + SourceIndex(0) --- >>>//# sourceMappingURL=sourceMapValidationDestructuringVariableStatementArrayBindingPattern7.js.map \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.js.map index a35c7f2596f..ec1321b8a91 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.ts"],"names":[],"mappings":"AAIA,IAAI,MAAM,GAAU,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3C,IAAI,MAAM,GAAU,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAExC,IAAA,cAAgB,EAAhB,qCAAgB,CAAW;AAC7B,IAAA,cAAY,EAAZ,iCAAY,CAAW;AACvB,IAAA,cAAa,EAAb,kCAAa,EAAE,cAAiB,EAAjB,sCAAiB,EAAE,cAAmB,EAAnB,wCAAmB,CAAW;AAEhE,IAAA,uCAAa,EAAb,kCAAa,CAAoC;AAClD,IAAA,oCAAsF,EAArF,UAAY,EAAZ,iCAAY,EAAE,UAAgB,EAAhB,qCAAgB,EAAE,UAAkB,EAAlB,uCAAkB,CAAoC;AAEtF,IAAA,cAAa,EAAb,kCAAa,EAAE,4BAAa,CAAW;AAE5C,IAAI,KAAK,IAAI,MAAM,EAAE;IACjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;CACxB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.ts"],"names":[],"mappings":"AAIA,IAAI,MAAM,GAAU,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3C,IAAI,MAAM,GAAU,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAExC,IAAA,cAAgB,EAAhB,qCAAgB,CAAW;AAC7B,IAAA,cAAY,EAAZ,iCAAY,CAAW;AACvB,IAAA,cAAa,EAAb,kCAAa,EAAE,cAAiB,EAAjB,sCAAiB,EAAE,cAAmB,EAAnB,wCAAmB,CAAW;AAEhE,IAAA,uCAAa,EAAb,kCAAa,CAAoC;AAClD,IAAA,oCAAsF,EAArF,UAAY,EAAZ,iCAAY,EAAE,UAAgB,EAAhB,qCAAgB,EAAE,UAAkB,EAAlB,uCAAqD,CAAC;AAEtF,IAAA,cAAa,EAAb,kCAAa,EAAE,4BAAa,CAAW;AAE5C,IAAI,KAAK,IAAI,MAAM,EAAE;IACjB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;CACxB"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.sourcemap.txt index dfa51e18e6e..32db2f848c0 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues.sourcemap.txt @@ -235,8 +235,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPatternD 12> , 13> skillC = "noSkill" 14> -15> skillC = "noSkill" -16> ] = [3, "edging", "Trimming edges"]; +15> skillC = "noSkill"] = [3, "edging", "Trimming edges"] +16> ; 1->Emitted(7, 1) Source(13, 5) + SourceIndex(0) 2 >Emitted(7, 5) Source(13, 5) + SourceIndex(0) 3 >Emitted(7, 41) Source(13, 91) + SourceIndex(0) @@ -251,7 +251,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPatternD 12>Emitted(7, 141) Source(13, 38) + SourceIndex(0) 13>Emitted(7, 151) Source(13, 56) + SourceIndex(0) 14>Emitted(7, 153) Source(13, 38) + SourceIndex(0) -15>Emitted(7, 192) Source(13, 56) + SourceIndex(0) +15>Emitted(7, 192) Source(13, 91) + SourceIndex(0) 16>Emitted(7, 193) Source(13, 92) + SourceIndex(0) --- >>>var _l = robotA[0], numberA3 = _l === void 0 ? -1 : _l, robotAInfo = robotA.slice(1); diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.js.map index 844b6f3169f..1a6d2dd6a67 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.ts"],"names":[],"mappings":"AAIA,IAAI,WAAW,GAAsB,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/D,IAAI,WAAW,GAAsB,CAAC,SAAS,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAElE,IAAA,mBAA+B,EAA/B,oDAA+B,CAAgB;AACjD,IAAA,mBAAiB,EAAjB,sCAAiB,CAAiB;AAClC,IAAA,mBAAiB,EAAjB,sCAAiB,EAAE,mBAAiF,EAAjF,gDAAiF,EAAhF,UAAyB,EAAzB,8CAAyB,EAAE,UAA2B,EAA3B,gDAA2B,CAA0C;AAEpH,IAAA,yCAAiB,EAAjB,sCAAiB,CAAuC;AACzD,IAAA,sCAA2I,EAA1I,UAAkB,EAAlB,uCAAkB,EAAE,UAAiF,EAAjF,gDAAiF,EAAhF,UAAyB,EAAzB,8CAAyB,EAAE,UAA2B,EAA3B,gDAA2B,CAAgE;AAEhJ,IAAI,MAAM,IAAI,MAAM,EAAE;IAClB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.ts"],"names":[],"mappings":"AAIA,IAAI,WAAW,GAAsB,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/D,IAAI,WAAW,GAAsB,CAAC,SAAS,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAElE,IAAA,mBAA+B,EAA/B,oDAA+B,CAAgB;AACjD,IAAA,mBAAiB,EAAjB,sCAAiB,CAAiB;AAClC,IAAA,mBAAiB,EAAjB,sCAAiB,EAAE,mBAAiF,EAAjF,gDAAiF,EAAhF,UAAyB,EAAzB,8CAAyB,EAAE,UAA2B,EAA3B,gDAAqD,CAAgB;AAEpH,IAAA,yCAAiB,EAAjB,sCAAiB,CAAuC;AACzD,IAAA,sCAA2I,EAA1I,UAAkB,EAAlB,uCAAkB,EAAE,UAAiF,EAAjF,gDAAiF,EAAhF,UAAyB,EAAzB,8CAAyB,EAAE,UAA2B,EAA3B,gDAA0F,CAAC;AAEhJ,IAAI,MAAM,IAAI,MAAM,EAAE;IAClB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.sourcemap.txt index 99d2e65cfe7..6cf78caf44a 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementArrayBindingPatternDefaultValues2.sourcemap.txt @@ -183,8 +183,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPatternD 14> , 15> secondarySkillA = "noSkill" 16> -17> secondarySkillA = "noSkill" -18> ] = ["noSkill", "noSkill"]] = multiRobotA; +17> secondarySkillA = "noSkill"] = ["noSkill", "noSkill"] +18> ] = multiRobotA; 1->Emitted(5, 1) Source(10, 6) + SourceIndex(0) 2 >Emitted(5, 5) Source(10, 6) + SourceIndex(0) 3 >Emitted(5, 24) Source(10, 23) + SourceIndex(0) @@ -201,7 +201,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPatternD 14>Emitted(5, 197) Source(10, 53) + SourceIndex(0) 15>Emitted(5, 207) Source(10, 80) + SourceIndex(0) 16>Emitted(5, 209) Source(10, 53) + SourceIndex(0) -17>Emitted(5, 257) Source(10, 80) + SourceIndex(0) +17>Emitted(5, 257) Source(10, 106) + SourceIndex(0) 18>Emitted(5, 258) Source(10, 122) + SourceIndex(0) --- >>>var _h = ["roomba", ["vaccum", "mopping"]][0], nameMC = _h === void 0 ? "noName" : _h; @@ -267,8 +267,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPatternD 16> , 17> secondarySkillC = "noSkill" 18> -19> secondarySkillC = "noSkill" -20> ] = ["noSkill", "noSkill"]] = ["roomba", ["vaccum", "mopping"]]; +19> secondarySkillC = "noSkill"] = ["noSkill", "noSkill"]] = ["roomba", ["vaccum", "mopping"]] +20> ; 1->Emitted(7, 1) Source(13, 5) + SourceIndex(0) 2 >Emitted(7, 5) Source(13, 5) + SourceIndex(0) 3 >Emitted(7, 43) Source(13, 144) + SourceIndex(0) @@ -287,7 +287,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementArrayBindingPatternD 16>Emitted(7, 220) Source(13, 54) + SourceIndex(0) 17>Emitted(7, 230) Source(13, 81) + SourceIndex(0) 18>Emitted(7, 232) Source(13, 54) + SourceIndex(0) -19>Emitted(7, 280) Source(13, 81) + SourceIndex(0) +19>Emitted(7, 280) Source(13, 144) + SourceIndex(0) 20>Emitted(7, 281) Source(13, 145) + SourceIndex(0) --- >>>if (nameMB == nameMA) { diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementDefaultValues.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementDefaultValues.js.map index 4c0852ad1d2..5ce5dc6ff54 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementDefaultValues.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementDefaultValues.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementDefaultValues.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementDefaultValues.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementDefaultValues.ts"],"names":[],"mappings":"AAOA,IAAI,KAAK,GAAG,OAAO,CAAC;AACpB,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACvD,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACrD,IAAA,gBAAwB,EAAxB,uCAAwB,CAAY;AACpC,IAAA,gBAAwB,EAAxB,uCAAwB,EAAE,iBAAoC,EAApC,kDAAoC,CAAY;AAC5E,IAAA,8CAA8G,EAA5G,YAAwB,EAAxB,uCAAwB,EAAE,aAAoC,EAApC,kDAAoC,CAA+C;AACnH,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementDefaultValues.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementDefaultValues.ts"],"names":[],"mappings":"AAOA,IAAI,KAAK,GAAG,OAAO,CAAC;AACpB,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACvD,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AACrD,IAAA,gBAAwB,EAAxB,uCAAwB,CAAY;AACpC,IAAA,gBAAwB,EAAxB,uCAAwB,EAAE,iBAAoC,EAApC,kDAAoC,CAAY;AAC5E,IAAA,8CAA8G,EAA5G,YAAwB,EAAxB,uCAAwB,EAAE,aAAoC,EAApC,kDAAkF,CAAC;AACnH,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementDefaultValues.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementDefaultValues.sourcemap.txt index c426313b33c..fe0843d56a9 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementDefaultValues.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementDefaultValues.sourcemap.txt @@ -208,8 +208,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementDefaultValues.ts 8 > , 9 > skill: skillC = "" 10> -11> skill: skillC = "" -12> } = { name: "Edger", skill: "cutting edges" }; +11> skill: skillC = "" } = { name: "Edger", skill: "cutting edges" } +12> ; 1->Emitted(6, 1) Source(13, 5) + SourceIndex(0) 2 >Emitted(6, 5) Source(13, 5) + SourceIndex(0) 3 >Emitted(6, 51) Source(13, 115) + SourceIndex(0) @@ -220,7 +220,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementDefaultValues.ts 8 >Emitted(6, 108) Source(13, 33) + SourceIndex(0) 9 >Emitted(6, 121) Source(13, 69) + SourceIndex(0) 10>Emitted(6, 123) Source(13, 33) + SourceIndex(0) -11>Emitted(6, 173) Source(13, 69) + SourceIndex(0) +11>Emitted(6, 173) Source(13, 115) + SourceIndex(0) 12>Emitted(6, 174) Source(13, 116) + SourceIndex(0) --- >>>if (nameA == nameB) { diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.js.map index ed0fe05cb3c..6294c6af22b 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.ts"],"names":[],"mappings":"AAUA,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;AACxF,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;AAExF,IAAA,kBAAoD,EAA1C,qBAAiB,EAAE,yBAAqB,CAAc;AAChE,IAAA,mBAAW,EAAE,kBAAoD,EAA1C,qBAAiB,EAAE,yBAAqB,CAAc;AAC/E,IAAA,mFAAsJ,EAApJ,eAAW,EAAE,cAAoD,EAA1C,qBAAiB,EAAE,yBAAqB,CAAsF;AAE3J,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.ts"],"names":[],"mappings":"AAUA,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;AACxF,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;AAExF,IAAA,kBAAoD,EAA1C,qBAAiB,EAAE,yBAAuB,CAAY;AAChE,IAAA,mBAAW,EAAE,kBAAoD,EAA1C,qBAAiB,EAAE,yBAAuB,CAAY;AAC/E,IAAA,mFAAsJ,EAApJ,eAAW,EAAE,cAAoD,EAA1C,qBAAiB,EAAE,yBAA0G,CAAC;AAE3J,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.sourcemap.txt index 1779c517c68..0e8c1c437a2 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPattern.sourcemap.txt @@ -174,15 +174,15 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP 4 > 5 > primary: primaryA 6 > , -7 > secondary: secondaryA -8 > } } = robotA; +7 > secondary: secondaryA } +8 > } = robotA; 1 >Emitted(3, 1) Source(14, 7) + SourceIndex(0) 2 >Emitted(3, 5) Source(14, 7) + SourceIndex(0) 3 >Emitted(3, 23) Source(14, 59) + SourceIndex(0) 4 >Emitted(3, 25) Source(14, 17) + SourceIndex(0) 5 >Emitted(3, 46) Source(14, 34) + SourceIndex(0) 6 >Emitted(3, 48) Source(14, 36) + SourceIndex(0) -7 >Emitted(3, 73) Source(14, 57) + SourceIndex(0) +7 >Emitted(3, 73) Source(14, 59) + SourceIndex(0) 8 >Emitted(3, 74) Source(14, 71) + SourceIndex(0) --- >>>var nameB = robotB.name, _b = robotB.skills, primaryB = _b.primary, secondaryB = _b.secondary; @@ -206,8 +206,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP 6 > 7 > primary: primaryB 8 > , -9 > secondary: secondaryB -10> } } = robotB; +9 > secondary: secondaryB } +10> } = robotB; 1->Emitted(4, 1) Source(15, 7) + SourceIndex(0) 2 >Emitted(4, 5) Source(15, 7) + SourceIndex(0) 3 >Emitted(4, 24) Source(15, 18) + SourceIndex(0) @@ -216,7 +216,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP 6 >Emitted(4, 46) Source(15, 30) + SourceIndex(0) 7 >Emitted(4, 67) Source(15, 47) + SourceIndex(0) 8 >Emitted(4, 69) Source(15, 49) + SourceIndex(0) -9 >Emitted(4, 94) Source(15, 70) + SourceIndex(0) +9 >Emitted(4, 94) Source(15, 72) + SourceIndex(0) 10>Emitted(4, 95) Source(15, 84) + SourceIndex(0) --- >>>var _c = { name: "Edger", skills: { primary: "edging", secondary: "branch trimming" } }, nameC = _c.name, _d = _c.skills, primaryB = _d.primary, secondaryB = _d.secondary; @@ -243,8 +243,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP 8 > 9 > primary: primaryB 10> , -11> secondary: secondaryB -12> } } = { name: "Edger", skills: { primary: "edging", secondary: "branch trimming" } }; +11> secondary: secondaryB } } = { name: "Edger", skills: { primary: "edging", secondary: "branch trimming" } } +12> ; 1->Emitted(5, 1) Source(16, 5) + SourceIndex(0) 2 >Emitted(5, 5) Source(16, 5) + SourceIndex(0) 3 >Emitted(5, 88) Source(16, 155) + SourceIndex(0) @@ -255,7 +255,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP 8 >Emitted(5, 123) Source(16, 30) + SourceIndex(0) 9 >Emitted(5, 144) Source(16, 47) + SourceIndex(0) 10>Emitted(5, 146) Source(16, 49) + SourceIndex(0) -11>Emitted(5, 171) Source(16, 70) + SourceIndex(0) +11>Emitted(5, 171) Source(16, 155) + SourceIndex(0) 12>Emitted(5, 172) Source(16, 156) + SourceIndex(0) --- >>>if (nameB == nameB) { diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.js.map index 73e04a6e433..d718d679cd7 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.ts"],"names":[],"mappings":"AAUA,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;AACxF,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;AAG1F,IAAA,kBAGgD,EAHhD,sEAGgD,EAF5C,eAA6B,EAA7B,yCAA6B,EAC7B,iBAAiC,EAAjC,2CAAiC,CAE9B;AAEP,IAAA,gBAA+B,EAA/B,8CAA+B,EAC/B,kBAGgD,EAHhD,sEAGgD,EAF5C,eAA6B,EAA7B,yCAA6B,EAC7B,iBAAiC,EAAjC,2CAAiC,CAE9B;AACP,IAAA,mFAMqF,EALrF,YAA+B,EAA/B,8CAA+B,EAC/B,cAGgD,EAHhD,sEAGgD,EAF5C,eAA6B,EAA7B,yCAA6B,EAC7B,iBAAiC,EAAjC,2CAAiC,CAEiD;AAE1F,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.ts"],"names":[],"mappings":"AAUA,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;AACxF,IAAI,MAAM,GAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC;AAG1F,IAAA,kBAGgD,EAHhD,sEAGgD,EAF5C,eAA6B,EAA7B,yCAA6B,EAC7B,iBAAiC,EAAjC,2CAC4C,CACzC;AAEP,IAAA,gBAA+B,EAA/B,8CAA+B,EAC/B,kBAGgD,EAHhD,sEAGgD,EAF5C,eAA6B,EAA7B,yCAA6B,EAC7B,iBAAiC,EAAjC,2CAC4C,CACzC;AACP,IAAA,mFAMqF,EALrF,YAA+B,EAA/B,8CAA+B,EAC/B,cAGgD,EAHhD,sEAGgD,EAF5C,eAA6B,EAA7B,yCAA6B,EAC7B,iBAAiC,EAAjC,2CAEiF,CAAC;AAE1F,IAAI,KAAK,IAAI,KAAK,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB;KACI;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;CACtB"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.sourcemap.txt index 1051abf21b6..6b119b8d222 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementNestedObjectBindingPatternWithDefaultValues.sourcemap.txt @@ -195,9 +195,9 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP > 11> secondary: secondaryA = "noSkill" 12> -13> secondary: secondaryA = "noSkill" +13> secondary: secondaryA = "noSkill" + > } = { primary: "noSkill", secondary: "noSkill" } 14> - > } = { primary: "noSkill", secondary: "noSkill" } > } = robotA; 1->Emitted(3, 1) Source(15, 5) + SourceIndex(0) 2 >Emitted(3, 5) Source(15, 5) + SourceIndex(0) @@ -211,7 +211,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP 10>Emitted(3, 157) Source(17, 9) + SourceIndex(0) 11>Emitted(3, 174) Source(17, 42) + SourceIndex(0) 12>Emitted(3, 176) Source(17, 9) + SourceIndex(0) -13>Emitted(3, 219) Source(17, 42) + SourceIndex(0) +13>Emitted(3, 219) Source(18, 53) + SourceIndex(0) 14>Emitted(3, 220) Source(19, 12) + SourceIndex(0) --- >>>var _e = robotB.name, nameB = _e === void 0 ? "noNameSpecified" : _e, _f = robotB.skills, _g = _f === void 0 ? { primary: "noSkill", secondary: "noSkill" } : _f, _h = _g.primary, primaryB = _h === void 0 ? "noSkill" : _h, _j = _g.secondary, secondaryB = _j === void 0 ? "noSkill" : _j; @@ -260,9 +260,9 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP > 15> secondary: secondaryB = "noSkill" 16> -17> secondary: secondaryB = "noSkill" +17> secondary: secondaryB = "noSkill" + > } = { primary: "noSkill", secondary: "noSkill" } 18> - > } = { primary: "noSkill", secondary: "noSkill" } > } = robotB; 1->Emitted(4, 1) Source(21, 5) + SourceIndex(0) 2 >Emitted(4, 5) Source(21, 5) + SourceIndex(0) @@ -280,7 +280,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP 14>Emitted(4, 223) Source(24, 9) + SourceIndex(0) 15>Emitted(4, 240) Source(24, 42) + SourceIndex(0) 16>Emitted(4, 242) Source(24, 9) + SourceIndex(0) -17>Emitted(4, 285) Source(24, 42) + SourceIndex(0) +17>Emitted(4, 285) Source(25, 53) + SourceIndex(0) 18>Emitted(4, 286) Source(26, 12) + SourceIndex(0) --- >>>var _k = { name: "Edger", skills: { primary: "edging", secondary: "branch trimming" } }, _l = _k.name, nameC = _l === void 0 ? "noNameSpecified" : _l, _m = _k.skills, _o = _m === void 0 ? { primary: "noSkill", secondary: "noSkill" } : _m, _p = _o.primary, primaryB = _p === void 0 ? "noSkill" : _p, _q = _o.secondary, secondaryB = _q === void 0 ? "noSkill" : _q; @@ -337,10 +337,10 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP > 17> secondary: secondaryB = "noSkill" 18> -19> secondary: secondaryB = "noSkill" -20> - > } = { primary: "noSkill", secondary: "noSkill" } - > } = { name: "Edger", skills: { primary: "edging", secondary: "branch trimming" } }; +19> secondary: secondaryB = "noSkill" + > } = { primary: "noSkill", secondary: "noSkill" } + > } = { name: "Edger", skills: { primary: "edging", secondary: "branch trimming" } } +20> ; 1->Emitted(5, 1) Source(27, 5) + SourceIndex(0) 2 >Emitted(5, 5) Source(27, 5) + SourceIndex(0) 3 >Emitted(5, 88) Source(33, 90) + SourceIndex(0) @@ -359,7 +359,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementNestedObjectBindingP 16>Emitted(5, 300) Source(31, 9) + SourceIndex(0) 17>Emitted(5, 317) Source(31, 42) + SourceIndex(0) 18>Emitted(5, 319) Source(31, 9) + SourceIndex(0) -19>Emitted(5, 362) Source(31, 42) + SourceIndex(0) +19>Emitted(5, 362) Source(33, 90) + SourceIndex(0) 20>Emitted(5, 363) Source(33, 91) + SourceIndex(0) --- >>>if (nameB == nameB) { diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.js.map index eb36a3b9022..b7086032ef0 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.ts"],"names":[],"mappings":"AAAK,IAAA,eAAC,CAAc;AAChB,IAAA,qBAA2B,EAAzB,QAAC,EAAE,QAAC,CAAsB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.ts"],"names":[],"mappings":"AAAK,IAAA,eAAC,CAAc;AAChB,IAAA,qBAA2B,EAAzB,QAAC,EAAE,QAAsB,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.sourcemap.txt index 2390f91a8b1..d3d28db4017 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.sourcemap.txt @@ -40,15 +40,15 @@ sourceFile:sourceMapValidationDestructuringVariableStatementObjectBindingPattern 4 > 5 > a 6 > , -7 > b -8 > } = { a: 30, b: 40 }; +7 > b } = { a: 30, b: 40 } +8 > ; 1->Emitted(2, 1) Source(2, 5) + SourceIndex(0) 2 >Emitted(2, 5) Source(2, 5) + SourceIndex(0) 3 >Emitted(2, 26) Source(2, 32) + SourceIndex(0) 4 >Emitted(2, 28) Source(2, 7) + SourceIndex(0) 5 >Emitted(2, 36) Source(2, 8) + SourceIndex(0) 6 >Emitted(2, 38) Source(2, 10) + SourceIndex(0) -7 >Emitted(2, 46) Source(2, 11) + SourceIndex(0) +7 >Emitted(2, 46) Source(2, 32) + SourceIndex(0) 8 >Emitted(2, 47) Source(2, 33) + SourceIndex(0) --- >>>//# sourceMappingURL=sourceMapValidationDestructuringVariableStatementObjectBindingPattern2.js.map \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.js.map b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.js.map index 2b6cd16157d..261e0ec708e 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.js.map +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.js.map @@ -1,2 +1,2 @@ //// [sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.js.map] -{"version":3,"file":"sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.ts"],"names":[],"mappings":"AAAI,IAAA,uBACwB,EADvB,SAAO,EAAP,4BAAO,EACP,QAAC,CAAuB"} \ No newline at end of file +{"version":3,"file":"sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.js","sourceRoot":"","sources":["sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.ts"],"names":[],"mappings":"AAAI,IAAA,uBACwB,EADvB,SAAO,EAAP,4BAAO,EACP,QAAuB,CAAC"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.sourcemap.txt index 68d24cb1b32..064a9f6fe58 100644 --- a/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.sourcemap.txt @@ -30,8 +30,8 @@ sourceFile:sourceMapValidationDestructuringVariableStatementObjectBindingPattern 7 > x = 500 8 > , > -9 > y -10> } = { x: 20, y: "hi" }; +9 > y} = { x: 20, y: "hi" } +10> ; 1 >Emitted(1, 1) Source(1, 5) + SourceIndex(0) 2 >Emitted(1, 5) Source(1, 5) + SourceIndex(0) 3 >Emitted(1, 28) Source(2, 29) + SourceIndex(0) @@ -40,7 +40,7 @@ sourceFile:sourceMapValidationDestructuringVariableStatementObjectBindingPattern 6 >Emitted(1, 41) Source(1, 6) + SourceIndex(0) 7 >Emitted(1, 69) Source(1, 13) + SourceIndex(0) 8 >Emitted(1, 71) Source(2, 6) + SourceIndex(0) -9 >Emitted(1, 79) Source(2, 7) + SourceIndex(0) +9 >Emitted(1, 79) Source(2, 29) + SourceIndex(0) 10>Emitted(1, 80) Source(2, 30) + SourceIndex(0) --- >>>//# sourceMappingURL=sourceMapValidationDestructuringVariableStatementObjectBindingPattern4.js.map \ No newline at end of file From 62d8b85f1dcd7588696383eae84c4b81e7b854fc Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 5 Sep 2018 11:30:05 -0700 Subject: [PATCH 152/163] Allow literal initializers of readonly properties in declaration files (#26313) * Allow literal initializers of readonly properties in declaration files * Move some conditions a bit --- src/compiler/checker.ts | 44 ++++++------ src/compiler/utilities.ts | 4 ++ .../reference/ambientErrors.errors.txt | 8 +-- .../reference/ambientErrors1.errors.txt | 4 +- .../reference/ambientStatement1.errors.txt | 4 +- ...onstDeclarations-ambient-errors.errors.txt | 20 +++--- .../declarationEmitConstantNoWidening.js | 24 +++++++ .../declarationEmitConstantNoWidening.symbols | 11 +++ .../declarationEmitConstantNoWidening.types | 12 ++++ .../reference/externSemantics.errors.txt | 8 +-- .../initializersInDeclarations.errors.txt | 12 ++-- .../missingRequiredDeclare.d.errors.txt | 4 +- ...rserModifierOnStatementInBlock2.errors.txt | 4 +- .../parserVariableStatement1.d.errors.txt | 4 +- tests/baselines/reference/varBlock.errors.txt | 68 +++++++++---------- .../declarationEmitConstantNoWidening.ts | 5 ++ 16 files changed, 147 insertions(+), 89 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitConstantNoWidening.js create mode 100644 tests/baselines/reference/declarationEmitConstantNoWidening.symbols create mode 100644 tests/baselines/reference/declarationEmitConstantNoWidening.types create mode 100644 tests/cases/compiler/declarationEmitConstantNoWidening.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index efe1061a531..a5e810c3972 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21708,7 +21708,7 @@ namespace ts { const initializer = getEffectiveInitializer(declaration)!; const type = getTypeOfExpression(initializer, /*cache*/ true); const widened = getCombinedNodeFlags(declaration) & NodeFlags.Const || - (getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration)) || + isDeclarationReadonly(declaration) || isTypeAssertion(initializer) ? type : getWidenedLiteralType(type); if (isInJavaScriptFile(declaration)) { if (widened.flags & TypeFlags.Nullable) { @@ -28082,7 +28082,7 @@ namespace ts { } function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean { - if (isVariableDeclaration(node) && isVarConst(node)) { + if (isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node)) { const type = getTypeOfSymbol(getSymbolOfNode(node)); return !!(type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral); } @@ -29420,26 +29420,28 @@ namespace ts { (expr).operand.kind === SyntaxKind.NumericLiteral; } + function checkAmbientInitializer(node: VariableDeclaration | PropertyDeclaration | PropertySignature) { + if (node.initializer) { + const isInvalidInitializer = !isStringOrNumberLiteralExpression(node.initializer); + const isConstOrReadonly = isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node); + if (isConstOrReadonly && !node.type) { + if (isInvalidInitializer) { + return grammarErrorOnNode(node.initializer!, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal); + } + } + else { + return grammarErrorOnNode(node.initializer!, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + } + if (!isConstOrReadonly || isInvalidInitializer) { + return grammarErrorOnNode(node.initializer!, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + } + } + } + function checkGrammarVariableDeclaration(node: VariableDeclaration) { if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) { if (node.flags & NodeFlags.Ambient) { - if (node.initializer) { - if (isVarConst(node) && !node.type) { - if (!isStringOrNumberLiteralExpression(node.initializer)) { - return grammarErrorOnNode(node.initializer, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal); - } - } - else { - // Error on equals token which immediate precedes the initializer - const equalsTokenLength = "=".length; - return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); - } - } - if (node.initializer && !(isVarConst(node) && isStringOrNumberLiteralExpression(node.initializer))) { - // Error on equals token which immediate precedes the initializer - const equalsTokenLength = "=".length; - return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); - } + checkAmbientInitializer(node); } else if (!node.initializer) { if (isBindingPattern(node.name) && !isBindingPattern(node.parent)) { @@ -29632,8 +29634,8 @@ namespace ts { } } - if (node.flags & NodeFlags.Ambient && node.initializer) { - return grammarErrorOnFirstToken(node.initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); + if (node.flags & NodeFlags.Ambient) { + checkAmbientInitializer(node); } if (isPropertyDeclaration(node) && node.exclamationToken && (!isClassLike(node.parent) || !node.type || node.initializer || diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b05e45bd13d..ca9923c4dbb 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -922,6 +922,10 @@ namespace ts { return !!(getCombinedModifierFlags(node) & ModifierFlags.Const); } + export function isDeclarationReadonly(declaration: Declaration): boolean { + return !!(getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration)); + } + export function isVarConst(node: VariableDeclaration | VariableDeclarationList): boolean { return !!(getCombinedNodeFlags(node) & NodeFlags.Const); } diff --git a/tests/baselines/reference/ambientErrors.errors.txt b/tests/baselines/reference/ambientErrors.errors.txt index 7b42085e0c2..05e72ccc879 100644 --- a/tests/baselines/reference/ambientErrors.errors.txt +++ b/tests/baselines/reference/ambientErrors.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/ambient/ambientErrors.ts(2,15): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/conformance/ambient/ambientErrors.ts(2,17): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/ambient/ambientErrors.ts(17,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. tests/cases/conformance/ambient/ambientErrors.ts(20,24): error TS1183: An implementation cannot be declared in ambient contexts. tests/cases/conformance/ambient/ambientErrors.ts(29,9): error TS1066: In ambient enum declarations member initializer must be constant expression. -tests/cases/conformance/ambient/ambientErrors.ts(34,11): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/conformance/ambient/ambientErrors.ts(34,13): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/ambient/ambientErrors.ts(35,19): error TS1183: An implementation cannot be declared in ambient contexts. tests/cases/conformance/ambient/ambientErrors.ts(37,20): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/ambient/ambientErrors.ts(38,13): error TS1039: Initializers are not allowed in ambient contexts. @@ -17,7 +17,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export ==== tests/cases/conformance/ambient/ambientErrors.ts (14 errors) ==== // Ambient variable with an initializer declare var x = 4; - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. // Ambient functions with invalid overloads @@ -57,7 +57,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export // Ambient module with initializers for values, bodies for functions / classes declare module M1 { var x = 3; - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. function fn() { } ~ diff --git a/tests/baselines/reference/ambientErrors1.errors.txt b/tests/baselines/reference/ambientErrors1.errors.txt index db7a155cc3f..5ae2b615eec 100644 --- a/tests/baselines/reference/ambientErrors1.errors.txt +++ b/tests/baselines/reference/ambientErrors1.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/ambientErrors1.ts(1,15): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/ambientErrors1.ts(1,17): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/compiler/ambientErrors1.ts (1 errors) ==== declare var x = 4; - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file diff --git a/tests/baselines/reference/ambientStatement1.errors.txt b/tests/baselines/reference/ambientStatement1.errors.txt index be7c7bb750c..1a5fb644113 100644 --- a/tests/baselines/reference/ambientStatement1.errors.txt +++ b/tests/baselines/reference/ambientStatement1.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/ambientStatement1.ts(2,6): error TS1036: Statements are not allowed in ambient contexts. -tests/cases/compiler/ambientStatement1.ts(4,20): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/ambientStatement1.ts(4,22): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/compiler/ambientStatement1.ts (2 errors) ==== @@ -9,6 +9,6 @@ tests/cases/compiler/ambientStatement1.ts(4,20): error TS1039: Initializers are !!! error TS1036: Statements are not allowed in ambient contexts. export var v1 = () => false; - ~ + ~~~~~~~~~~~ !!! error TS1039: Initializers are not allowed in ambient contexts. } \ No newline at end of file diff --git a/tests/baselines/reference/constDeclarations-ambient-errors.errors.txt b/tests/baselines/reference/constDeclarations-ambient-errors.errors.txt index 979448abf72..8d2b9d67ed8 100644 --- a/tests/baselines/reference/constDeclarations-ambient-errors.errors.txt +++ b/tests/baselines/reference/constDeclarations-ambient-errors.errors.txt @@ -1,30 +1,30 @@ -tests/cases/compiler/constDeclarations-ambient-errors.ts(2,27): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/constDeclarations-ambient-errors.ts(3,26): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(2,29): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(3,28): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/compiler/constDeclarations-ambient-errors.ts(4,20): error TS1254: A 'const' initializer in an ambient context must be a string or numeric literal. -tests/cases/compiler/constDeclarations-ambient-errors.ts(4,37): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/constDeclarations-ambient-errors.ts(4,51): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/constDeclarations-ambient-errors.ts(8,22): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(4,39): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(4,53): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/constDeclarations-ambient-errors.ts(8,24): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/compiler/constDeclarations-ambient-errors.ts (6 errors) ==== // error: no intialization expected in ambient declarations declare const c1: boolean = true; - ~ + ~~~~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare const c2: number = 0; - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare const c3 = null, c4 :string = "", c5: any = 0; ~~~~ !!! error TS1254: A 'const' initializer in an ambient context must be a string or numeric literal. - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare module M { const c6 = 0; const c7: number = 7; - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitConstantNoWidening.js b/tests/baselines/reference/declarationEmitConstantNoWidening.js new file mode 100644 index 00000000000..268f0776543 --- /dev/null +++ b/tests/baselines/reference/declarationEmitConstantNoWidening.js @@ -0,0 +1,24 @@ +//// [declarationEmitConstantNoWidening.ts] +export const FOO = 'FOO'; +export class Bar { + readonly type = FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO" +} + +//// [declarationEmitConstantNoWidening.js] +"use strict"; +exports.__esModule = true; +exports.FOO = 'FOO'; +var Bar = /** @class */ (function () { + function Bar() { + this.type = exports.FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO" + } + return Bar; +}()); +exports.Bar = Bar; + + +//// [declarationEmitConstantNoWidening.d.ts] +export declare const FOO = "FOO"; +export declare class Bar { + readonly type = "FOO"; +} diff --git a/tests/baselines/reference/declarationEmitConstantNoWidening.symbols b/tests/baselines/reference/declarationEmitConstantNoWidening.symbols new file mode 100644 index 00000000000..17ab38272b9 --- /dev/null +++ b/tests/baselines/reference/declarationEmitConstantNoWidening.symbols @@ -0,0 +1,11 @@ +=== tests/cases/compiler/declarationEmitConstantNoWidening.ts === +export const FOO = 'FOO'; +>FOO : Symbol(FOO, Decl(declarationEmitConstantNoWidening.ts, 0, 12)) + +export class Bar { +>Bar : Symbol(Bar, Decl(declarationEmitConstantNoWidening.ts, 0, 25)) + + readonly type = FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO" +>type : Symbol(Bar.type, Decl(declarationEmitConstantNoWidening.ts, 1, 18)) +>FOO : Symbol(FOO, Decl(declarationEmitConstantNoWidening.ts, 0, 12)) +} diff --git a/tests/baselines/reference/declarationEmitConstantNoWidening.types b/tests/baselines/reference/declarationEmitConstantNoWidening.types new file mode 100644 index 00000000000..5a7a11728a5 --- /dev/null +++ b/tests/baselines/reference/declarationEmitConstantNoWidening.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/declarationEmitConstantNoWidening.ts === +export const FOO = 'FOO'; +>FOO : "FOO" +>'FOO' : "FOO" + +export class Bar { +>Bar : Bar + + readonly type = FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO" +>type : "FOO" +>FOO : "FOO" +} diff --git a/tests/baselines/reference/externSemantics.errors.txt b/tests/baselines/reference/externSemantics.errors.txt index b58e2a4950c..db6ce0f6acd 100644 --- a/tests/baselines/reference/externSemantics.errors.txt +++ b/tests/baselines/reference/externSemantics.errors.txt @@ -1,13 +1,13 @@ -tests/cases/compiler/externSemantics.ts(1,14): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/externSemantics.ts(3,21): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/externSemantics.ts(1,15): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/externSemantics.ts(3,22): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/compiler/externSemantics.ts (2 errors) ==== declare var x=10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare var v; declare var y:number=3; - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file diff --git a/tests/baselines/reference/initializersInDeclarations.errors.txt b/tests/baselines/reference/initializersInDeclarations.errors.txt index 34a7b67e5d5..d7f2847286b 100644 --- a/tests/baselines/reference/initializersInDeclarations.errors.txt +++ b/tests/baselines/reference/initializersInDeclarations.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/externalModules/file1.d.ts(4,9): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/externalModules/file1.d.ts(5,16): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/externalModules/file1.d.ts(6,16): error TS1183: An implementation cannot be declared in ambient contexts. -tests/cases/conformance/externalModules/file1.d.ts(11,15): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/conformance/externalModules/file1.d.ts(12,15): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/conformance/externalModules/file1.d.ts(11,17): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/conformance/externalModules/file1.d.ts(12,17): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/conformance/externalModules/file1.d.ts(15,2): error TS1036: Statements are not allowed in ambient contexts. -tests/cases/conformance/externalModules/file1.d.ts(17,16): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/conformance/externalModules/file1.d.ts(17,18): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/conformance/externalModules/file1.d.ts (7 errors) ==== @@ -25,10 +25,10 @@ tests/cases/conformance/externalModules/file1.d.ts(17,16): error TS1039: Initial } declare var x = []; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare var y = {}; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare module M1 { @@ -37,6 +37,6 @@ tests/cases/conformance/externalModules/file1.d.ts(17,16): error TS1039: Initial !!! error TS1036: Statements are not allowed in ambient contexts. export var v1 = () => false; - ~ + ~~~~~~~~~~~ !!! error TS1039: Initializers are not allowed in ambient contexts. } \ No newline at end of file diff --git a/tests/baselines/reference/missingRequiredDeclare.d.errors.txt b/tests/baselines/reference/missingRequiredDeclare.d.errors.txt index dc713c86d89..a673c948a48 100644 --- a/tests/baselines/reference/missingRequiredDeclare.d.errors.txt +++ b/tests/baselines/reference/missingRequiredDeclare.d.errors.txt @@ -1,10 +1,10 @@ tests/cases/compiler/missingRequiredDeclare.d.ts(1,1): error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. -tests/cases/compiler/missingRequiredDeclare.d.ts(1,7): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/missingRequiredDeclare.d.ts(1,9): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/compiler/missingRequiredDeclare.d.ts (2 errors) ==== var x = 1; ~~~ !!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file diff --git a/tests/baselines/reference/parserModifierOnStatementInBlock2.errors.txt b/tests/baselines/reference/parserModifierOnStatementInBlock2.errors.txt index d863bf7143e..c990b08efc1 100644 --- a/tests/baselines/reference/parserModifierOnStatementInBlock2.errors.txt +++ b/tests/baselines/reference/parserModifierOnStatementInBlock2.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,4): error TS1184: Modifiers cannot appear here. -tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,18): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,20): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts (2 errors) ==== @@ -7,7 +7,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStateme declare var x = this; ~~~~~~~ !!! error TS1184: Modifiers cannot appear here. - ~ + ~~~~ !!! error TS1039: Initializers are not allowed in ambient contexts. } \ No newline at end of file diff --git a/tests/baselines/reference/parserVariableStatement1.d.errors.txt b/tests/baselines/reference/parserVariableStatement1.d.errors.txt index de0bef5288c..eb6f799df74 100644 --- a/tests/baselines/reference/parserVariableStatement1.d.errors.txt +++ b/tests/baselines/reference/parserVariableStatement1.d.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts(1,1): error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. -tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts(1,7): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts(1,9): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts (2 errors) ==== var v = 1; ~~~ !!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. - ~ + ~ !!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file diff --git a/tests/baselines/reference/varBlock.errors.txt b/tests/baselines/reference/varBlock.errors.txt index 6746a760a44..12e3fc6a629 100644 --- a/tests/baselines/reference/varBlock.errors.txt +++ b/tests/baselines/reference/varBlock.errors.txt @@ -1,23 +1,23 @@ -tests/cases/compiler/varBlock.ts(8,16): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(8,18): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/compiler/varBlock.ts(11,22): error TS2369: A parameter property is only allowed in a constructor implementation. tests/cases/compiler/varBlock.ts(11,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation. -tests/cases/compiler/varBlock.ts(15,15): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(21,16): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(22,20): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(25,19): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(26,24): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(26,33): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(27,27): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(28,33): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(28,43): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(32,11): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(33,16): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(33,25): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(34,19): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(35,25): error TS1039: Initializers are not allowed in ambient contexts. -tests/cases/compiler/varBlock.ts(35,35): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(15,17): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(21,18): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(22,22): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(25,21): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(26,26): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(26,35): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(27,29): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(28,35): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(28,45): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(32,13): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(33,18): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(33,26): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(34,21): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(35,27): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(35,37): error TS1039: Initializers are not allowed in ambient contexts. tests/cases/compiler/varBlock.ts(39,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. -tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allowed in ambient contexts. +tests/cases/compiler/varBlock.ts(39,17): error TS1039: Initializers are not allowed in ambient contexts. ==== tests/cases/compiler/varBlock.ts (20 errors) ==== @@ -29,7 +29,7 @@ tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allo declare module m3 { var a, b, c; var a1, b1 = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. class C { @@ -42,7 +42,7 @@ tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allo } declare var b = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare var a2, b2, c2; @@ -50,47 +50,47 @@ tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allo declare var da = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare var d3, d4 = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. module m3 { declare var d = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. declare var d2, d3 = 10, d4 = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. export declare var dE = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. export declare var d2E, d3E = 10, d4E = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. } declare module m4 { var d = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. var d2, d3 = 10, d4 =10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. export var dE = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. export var d2E, d3E = 10, d4E = 10; - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. } @@ -98,5 +98,5 @@ tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allo declare var c = 10; ~ !!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'. - ~ + ~~ !!! error TS1039: Initializers are not allowed in ambient contexts. \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitConstantNoWidening.ts b/tests/cases/compiler/declarationEmitConstantNoWidening.ts new file mode 100644 index 00000000000..6bf6e92c7d4 --- /dev/null +++ b/tests/cases/compiler/declarationEmitConstantNoWidening.ts @@ -0,0 +1,5 @@ +// @declaration: true +export const FOO = 'FOO'; +export class Bar { + readonly type = FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO" +} \ No newline at end of file From 1eb3082387d72016b72876a8e64ffaa00c7b5dd7 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 5 Sep 2018 11:34:27 -0700 Subject: [PATCH 153/163] Support completions inside JSDoc before EndOfFileToken (#25568) --- src/services/utilities.ts | 12 ++++------ tests/cases/fourslash/completionsPaths.ts | 6 +++-- .../fourslash/completionsPaths_importType.ts | 23 +++++++++++++++++++ .../fourslash/importTypeModuleCompletions.ts | 13 ----------- 4 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 tests/cases/fourslash/completionsPaths_importType.ts delete mode 100644 tests/cases/fourslash/importTypeModuleCompletions.ts diff --git a/src/services/utilities.ts b/src/services/utilities.ts index c3d4cd9a390..b8a235bbeb4 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -755,7 +755,7 @@ namespace ts { return result; function find(n: Node): Node | undefined { - if (isNonWhitespaceToken(n)) { + if (isNonWhitespaceToken(n) && n.kind !== SyntaxKind.EndOfFileToken) { return n; } @@ -786,16 +786,14 @@ namespace ts { } } - Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile || isJSDocCommentContainingNode(n)); + Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile || n.kind === SyntaxKind.EndOfFileToken || isJSDocCommentContainingNode(n)); // Here we know that none of child token nodes embrace the position, // the only known case is when position is at the end of the file. // Try to find the rightmost token in the file without filtering. // Namely we are skipping the check: 'position < node.end' - if (children.length) { - const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile); - return candidate && findRightmostToken(candidate, sourceFile); - } + const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile); + return candidate && findRightmostToken(candidate, sourceFile); } } @@ -1048,7 +1046,7 @@ namespace ts { function nodeHasTokens(n: Node, sourceFile: SourceFileLike): boolean { // If we have a token or node that has a non-zero width, it must have tokens. // Note: getWidth() does not take trivia into account. - return n.getWidth(sourceFile) !== 0; + return n.kind === SyntaxKind.EndOfFileToken ? !!(n as EndOfFileToken).jsDoc : n.getWidth(sourceFile) !== 0; } export function getNodeModifiers(node: Node): string { diff --git a/tests/cases/fourslash/completionsPaths.ts b/tests/cases/fourslash/completionsPaths.ts index e120b3dcb14..e875e3e2147 100644 --- a/tests/cases/fourslash/completionsPaths.ts +++ b/tests/cases/fourslash/completionsPaths.ts @@ -23,5 +23,7 @@ // @Filename: /src/folder/4.ts ////const foo = require(`x//*4*/`); -verify.completionsAt("1", ["y", "x"], { isNewIdentifierLocation: true }); -verify.completionsAt(["2", "3", "4"], ["bar", "foo"], { isNewIdentifierLocation: true }); +verify.completions( + { marker: "1", exact: ["y", "x"], isNewIdentifierLocation: true }, + { marker: ["2", "3", "4"], exact: ["bar", "foo"], isNewIdentifierLocation: true }, +); diff --git a/tests/cases/fourslash/completionsPaths_importType.ts b/tests/cases/fourslash/completionsPaths_importType.ts new file mode 100644 index 00000000000..4d351f2494e --- /dev/null +++ b/tests/cases/fourslash/completionsPaths_importType.ts @@ -0,0 +1,23 @@ +/// + +// @allowJs: true +// @moduleResolution: node + +// @Filename: /ns.ts +////file content not read + +// @Filename: /node_modules/package/index.ts +////file content not read + +// @Filename: /usage.ts +////type A = typeof import("p/*1*/"); +////type B = import(".//*2*/"); + +// @Filename: /user.js +/////** @type {import("/*3*/")} */ + +verify.completions( + { marker: "1", exact: "package", isNewIdentifierLocation: true }, + { marker: "2", exact: ["lib", "ns", "user", "node_modules"], isNewIdentifierLocation: true }, + { marker: "3", exact: ["package"], isNewIdentifierLocation: true }, +); diff --git a/tests/cases/fourslash/importTypeModuleCompletions.ts b/tests/cases/fourslash/importTypeModuleCompletions.ts deleted file mode 100644 index 2a2f17818d4..00000000000 --- a/tests/cases/fourslash/importTypeModuleCompletions.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// - -// @moduleResolution: node - -// @Filename: /ns.ts -////file content not read -// @Filename: /node_modules/package/index.ts -////file content not read -// @Filename: /usage.ts -////type A = typeof import("p/*1*/"); -////type B = typeof import(".//*2*/"); -verify.completionsAt("1", ["package"], { isNewIdentifierLocation: true }); -verify.completionsAt("2", ["lib", "ns", "node_modules"], { isNewIdentifierLocation: true }); From 69c7e67c88af4428e88261f3beb1fdec63ff441a Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 5 Sep 2018 13:49:38 -0700 Subject: [PATCH 154/163] Check privateness when emittign readonly/const props (#26920) --- src/compiler/transformers/declarations.ts | 5 ++-- .../declarationEmitPrivateReadonlyLiterals.js | 28 +++++++++++++++++++ ...arationEmitPrivateReadonlyLiterals.symbols | 17 +++++++++++ ...clarationEmitPrivateReadonlyLiterals.types | 21 ++++++++++++++ .../declarationEmitPrivateReadonlyLiterals.ts | 8 ++++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.js create mode 100644 tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.symbols create mode 100644 tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.types create mode 100644 tests/cases/compiler/declarationEmitPrivateReadonlyLiterals.ts diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 9974b60875b..f31058743a2 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1324,12 +1324,13 @@ namespace ts { } type CanHaveLiteralInitializer = VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration; - function canHaveLiteralInitializer(node: Node): node is CanHaveLiteralInitializer { + function canHaveLiteralInitializer(node: Node): boolean { switch (node.kind) { - case SyntaxKind.VariableDeclaration: case SyntaxKind.PropertyDeclaration: case SyntaxKind.PropertySignature: + return !hasModifier(node, ModifierFlags.Private); case SyntaxKind.Parameter: + case SyntaxKind.VariableDeclaration: return true; } return false; diff --git a/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.js b/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.js new file mode 100644 index 00000000000..c7e1d1e8ee6 --- /dev/null +++ b/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.js @@ -0,0 +1,28 @@ +//// [declarationEmitPrivateReadonlyLiterals.ts] +class Foo { + private static readonly A = "a"; + private readonly B = "b"; + private static readonly C = 42; + private readonly D = 42; +} + + +//// [declarationEmitPrivateReadonlyLiterals.js] +var Foo = /** @class */ (function () { + function Foo() { + this.B = "b"; + this.D = 42; + } + Foo.A = "a"; + Foo.C = 42; + return Foo; +}()); + + +//// [declarationEmitPrivateReadonlyLiterals.d.ts] +declare class Foo { + private static readonly A; + private readonly B; + private static readonly C; + private readonly D; +} diff --git a/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.symbols b/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.symbols new file mode 100644 index 00000000000..ac3d42abf3a --- /dev/null +++ b/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/declarationEmitPrivateReadonlyLiterals.ts === +class Foo { +>Foo : Symbol(Foo, Decl(declarationEmitPrivateReadonlyLiterals.ts, 0, 0)) + + private static readonly A = "a"; +>A : Symbol(Foo.A, Decl(declarationEmitPrivateReadonlyLiterals.ts, 0, 11)) + + private readonly B = "b"; +>B : Symbol(Foo.B, Decl(declarationEmitPrivateReadonlyLiterals.ts, 1, 36)) + + private static readonly C = 42; +>C : Symbol(Foo.C, Decl(declarationEmitPrivateReadonlyLiterals.ts, 2, 29)) + + private readonly D = 42; +>D : Symbol(Foo.D, Decl(declarationEmitPrivateReadonlyLiterals.ts, 3, 35)) +} + diff --git a/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.types b/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.types new file mode 100644 index 00000000000..10fdff00b2e --- /dev/null +++ b/tests/baselines/reference/declarationEmitPrivateReadonlyLiterals.types @@ -0,0 +1,21 @@ +=== tests/cases/compiler/declarationEmitPrivateReadonlyLiterals.ts === +class Foo { +>Foo : Foo + + private static readonly A = "a"; +>A : "a" +>"a" : "a" + + private readonly B = "b"; +>B : "b" +>"b" : "b" + + private static readonly C = 42; +>C : 42 +>42 : 42 + + private readonly D = 42; +>D : 42 +>42 : 42 +} + diff --git a/tests/cases/compiler/declarationEmitPrivateReadonlyLiterals.ts b/tests/cases/compiler/declarationEmitPrivateReadonlyLiterals.ts new file mode 100644 index 00000000000..3471929a2f7 --- /dev/null +++ b/tests/cases/compiler/declarationEmitPrivateReadonlyLiterals.ts @@ -0,0 +1,8 @@ +// @declaration: true + +class Foo { + private static readonly A = "a"; + private readonly B = "b"; + private static readonly C = 42; + private readonly D = 42; +} From 0b1183a4611bbf7568cecebc39d7e60128c4ec00 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 5 Sep 2018 14:52:47 -0700 Subject: [PATCH 155/163] Allow isSymbolAccessible to paint object literal declarations as visible (#24668) * Dont use resolveEntityName for computed property name symbol resolution - use checkExpression and resolvedSymbol instead * Fix lint --- src/compiler/checker.ts | 13 ++++++++- ...ctLiteralComputedNameNoDeclarationError.js | 29 +++++++++++++++++++ ...eralComputedNameNoDeclarationError.symbols | 18 ++++++++++++ ...iteralComputedNameNoDeclarationError.types | 23 +++++++++++++++ ...ctLiteralComputedNameNoDeclarationError.ts | 8 +++++ 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.js create mode 100644 tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.symbols create mode 100644 tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.types create mode 100644 tests/cases/compiler/objectLiteralComputedNameNoDeclarationError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db040abdd52..5211abef285 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2871,7 +2871,18 @@ namespace ts { // we are going to see if c can be accessed in scope directly. // But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible // It is accessible if the parent m is accessible because then m.c can be accessed through qualification - const parentResult = isAnySymbolAccessible(getContainersOfSymbol(symbol, enclosingDeclaration), enclosingDeclaration, initialSymbol, initialSymbol === symbol ? getQualifiedLeftMeaning(meaning) : meaning, shouldComputeAliasesToMakeVisible); + + let containers = getContainersOfSymbol(symbol, enclosingDeclaration); + // If we're trying to reference some object literal in, eg `var a = { x: 1 }`, the symbol for the literal, `__object`, is distinct + // from the symbol of the declaration it is being assigned to. Since we can use the declaration to refer to the literal, however, + // we'd like to make that connection here - potentially causing us to paint the declararation's visibiility, and therefore the literal. + const firstDecl: Node = first(symbol.declarations); + if (!length(containers) && meaning & SymbolFlags.Value && firstDecl && isObjectLiteralExpression(firstDecl)) { + if (firstDecl.parent && isVariableDeclaration(firstDecl.parent) && firstDecl === firstDecl.parent.initializer) { + containers = [getSymbolOfNode(firstDecl.parent)]; + } + } + const parentResult = isAnySymbolAccessible(containers, enclosingDeclaration, initialSymbol, initialSymbol === symbol ? getQualifiedLeftMeaning(meaning) : meaning, shouldComputeAliasesToMakeVisible); if (parentResult) { return parentResult; } diff --git a/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.js b/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.js new file mode 100644 index 00000000000..5c5e5feccd8 --- /dev/null +++ b/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.js @@ -0,0 +1,29 @@ +//// [objectLiteralComputedNameNoDeclarationError.ts] +const Foo = { + BANANA: 'banana' as 'banana', +} + +export const Baa = { + [Foo.BANANA]: 1 +}; + +//// [objectLiteralComputedNameNoDeclarationError.js] +"use strict"; +exports.__esModule = true; +var _a; +var Foo = { + BANANA: 'banana' +}; +exports.Baa = (_a = {}, + _a[Foo.BANANA] = 1, + _a); + + +//// [objectLiteralComputedNameNoDeclarationError.d.ts] +declare const Foo: { + BANANA: "banana"; +}; +export declare const Baa: { + [Foo.BANANA]: number; +}; +export {}; diff --git a/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.symbols b/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.symbols new file mode 100644 index 00000000000..dce3f633b10 --- /dev/null +++ b/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/objectLiteralComputedNameNoDeclarationError.ts === +const Foo = { +>Foo : Symbol(Foo, Decl(objectLiteralComputedNameNoDeclarationError.ts, 0, 5)) + + BANANA: 'banana' as 'banana', +>BANANA : Symbol(BANANA, Decl(objectLiteralComputedNameNoDeclarationError.ts, 0, 13)) +} + +export const Baa = { +>Baa : Symbol(Baa, Decl(objectLiteralComputedNameNoDeclarationError.ts, 4, 12)) + + [Foo.BANANA]: 1 +>[Foo.BANANA] : Symbol([Foo.BANANA], Decl(objectLiteralComputedNameNoDeclarationError.ts, 4, 20)) +>Foo.BANANA : Symbol(BANANA, Decl(objectLiteralComputedNameNoDeclarationError.ts, 0, 13)) +>Foo : Symbol(Foo, Decl(objectLiteralComputedNameNoDeclarationError.ts, 0, 5)) +>BANANA : Symbol(BANANA, Decl(objectLiteralComputedNameNoDeclarationError.ts, 0, 13)) + +}; diff --git a/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.types b/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.types new file mode 100644 index 00000000000..17ef7ff584d --- /dev/null +++ b/tests/baselines/reference/objectLiteralComputedNameNoDeclarationError.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/objectLiteralComputedNameNoDeclarationError.ts === +const Foo = { +>Foo : { BANANA: "banana"; } +>{ BANANA: 'banana' as 'banana',} : { BANANA: "banana"; } + + BANANA: 'banana' as 'banana', +>BANANA : "banana" +>'banana' as 'banana' : "banana" +>'banana' : "banana" +} + +export const Baa = { +>Baa : { [Foo.BANANA]: number; } +>{ [Foo.BANANA]: 1} : { [Foo.BANANA]: number; } + + [Foo.BANANA]: 1 +>[Foo.BANANA] : number +>Foo.BANANA : "banana" +>Foo : { BANANA: "banana"; } +>BANANA : "banana" +>1 : 1 + +}; diff --git a/tests/cases/compiler/objectLiteralComputedNameNoDeclarationError.ts b/tests/cases/compiler/objectLiteralComputedNameNoDeclarationError.ts new file mode 100644 index 00000000000..93755f5e5d5 --- /dev/null +++ b/tests/cases/compiler/objectLiteralComputedNameNoDeclarationError.ts @@ -0,0 +1,8 @@ +// @declaration: true +const Foo = { + BANANA: 'banana' as 'banana', +} + +export const Baa = { + [Foo.BANANA]: 1 +}; \ No newline at end of file From ddedfd44f7a743d8766277920a154a6834fa4a80 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 5 Sep 2018 15:22:39 -0700 Subject: [PATCH 156/163] Update user baselines (#26903) --- .../user/chrome-devtools-frontend.log | 143 ++++++------------ tests/baselines/reference/user/npm.log | 3 + 2 files changed, 48 insertions(+), 98 deletions(-) diff --git a/tests/baselines/reference/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index 1331e636ac0..6085bb91b9e 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -11,7 +11,6 @@ Standard output: ../../../../built/local/lib.dom.d.ts(11899,13): error TS2300: Duplicate identifier 'Request'. ../../../../built/local/lib.dom.d.ts(16316,11): error TS2300: Duplicate identifier 'Window'. ../../../../built/local/lib.dom.d.ts(16447,13): error TS2300: Duplicate identifier 'Window'. -../../../../built/local/lib.dom.d.ts(17190,15): error TS2451: Cannot redeclare block-scoped variable 'name'. ../../../../built/local/lib.es5.d.ts(1346,11): error TS2300: Duplicate identifier 'ArrayLike'. ../../../../built/local/lib.es5.d.ts(1382,6): error TS2300: Duplicate identifier 'Record'. ../../../../node_modules/@types/node/index.d.ts(150,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'module' must be of type '{}', but here has type 'NodeModule'. @@ -555,7 +554,6 @@ node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/cate node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/category-renderer.js(483,32): error TS2503: Cannot find namespace 'ReportRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/category-renderer.js(507,24): error TS2339: Property 'open' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/category-renderer.js(554,8): error TS2339: Property 'CategoryRenderer' does not exist on type 'Window'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/category-renderer.js(560,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/category-renderer.js(566,18): error TS2339: Property 'PerfHintExtendedInfo' does not exist on type 'typeof CategoryRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(43,45): error TS2694: Namespace 'CriticalRequestChainRenderer' has no exported member 'CRCSegment'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(71,15): error TS2304: Cannot find name 'DOM'. @@ -571,12 +569,9 @@ node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc- node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(158,9): error TS2304: Cannot find name 'Util'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(161,9): error TS2304: Cannot find name 'Util'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(184,8): error TS2339: Property 'CriticalRequestChainRenderer' does not exist on type 'Window'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(188,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(194,30): error TS2339: Property 'CRCDetailsJSON' does not exist on type 'typeof CriticalRequestChainRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(197,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(204,30): error TS2339: Property 'CRCRequest' does not exist on type 'typeof CriticalRequestChainRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(216,42): error TS2694: Namespace 'CriticalRequestChainRenderer' has no exported member 'CRCRequest'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(220,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/crc-details-renderer.js(228,30): error TS2339: Property 'CRCSegment' does not exist on type 'typeof CriticalRequestChainRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(12,15): error TS2304: Cannot find name 'DOM'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(29,31): error TS2694: Namespace 'DetailsRenderer' has no exported member 'DetailsJSON'. @@ -603,35 +598,19 @@ node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/deta node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(268,18): error TS2304: Cannot find name 'Util'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(285,31): error TS2694: Namespace 'DetailsRenderer' has no exported member 'DetailsJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(298,8): error TS2339: Property 'DetailsRenderer' does not exist on type 'Window'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(303,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(303,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(307,17): error TS2339: Property 'DetailsJSON' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(311,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(311,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(316,17): error TS2339: Property 'ListDetailsJSON' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(320,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(320,8): error TS2300: Duplicate identifier 'type'. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(327,17): error TS2300: Duplicate identifier 'NodeDetailsJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(327,17): error TS2339: Property 'NodeDetailsJSON' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(330,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(330,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(335,17): error TS2339: Property 'CardsDetailsJSON' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(339,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(339,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(344,17): error TS2339: Property 'TableHeaderJSON' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(348,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(348,8): error TS2300: Duplicate identifier 'type'. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(355,17): error TS2300: Duplicate identifier 'NodeDetailsJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(355,17): error TS2339: Property 'NodeDetailsJSON' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(358,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(358,8): error TS2300: Duplicate identifier 'type'. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(360,46): error TS2694: Namespace 'DetailsRenderer' has no exported member 'DetailsJSON'. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(361,45): error TS2694: Namespace 'DetailsRenderer' has no exported member 'TableHeaderJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(364,17): error TS2339: Property 'TableDetailsJSON' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(367,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(367,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(372,17): error TS2339: Property 'ThumbnailDetails' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(375,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(375,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(380,17): error TS2339: Property 'LinkDetailsJSON' does not exist on type 'typeof DetailsRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(383,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(383,8): error TS2300: Duplicate identifier 'type'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/details-renderer.js(388,17): error TS2339: Property 'FilmstripDetails' does not exist on type 'typeof DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/dom.js(63,67): error TS2339: Property 'querySelector' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/dom.js(76,43): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'. @@ -650,13 +629,13 @@ node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/repo node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(119,30): error TS2694: Namespace 'ReportRenderer' has no exported member 'ReportJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(138,30): error TS2694: Namespace 'ReportRenderer' has no exported member 'ReportJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(172,8): error TS2339: Property 'ReportRenderer' does not exist on type 'Window'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(177,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(193,21): error TS2503: Cannot find namespace 'DetailsRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(197,16): error TS2339: Property 'AuditJSON' does not exist on type 'typeof ReportRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(201,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(206,39): error TS2694: Namespace 'ReportRenderer' has no exported member 'AuditJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(209,16): error TS2339: Property 'CategoryJSON' does not exist on type 'typeof ReportRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(213,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(217,16): error TS2339: Property 'GroupJSON' does not exist on type 'typeof ReportRenderer'. -node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(221,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(229,49): error TS2694: Namespace 'ReportRenderer' has no exported member 'CategoryJSON'. +node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(230,54): error TS2694: Namespace 'ReportRenderer' has no exported member 'GroupJSON'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/report-renderer.js(237,16): error TS2339: Property 'ReportJSON' does not exist on type 'typeof ReportRenderer'. node_modules/chrome-devtools-frontend/front_end/audits2/lighthouse/renderer/util.js(124,5): error TS2322: Type '{}' is not assignable to type '{ numPathParts: number; preserveQuery: boolean; preserveHost: boolean; }'. Property 'numPathParts' is missing in type '{}'. @@ -3182,7 +3161,6 @@ node_modules/chrome-devtools-frontend/front_end/bindings/TempFile.js(85,5): erro node_modules/chrome-devtools-frontend/front_end/bindings/TempFile.js(91,25): error TS2304: Cannot find name 'FileError'. node_modules/chrome-devtools-frontend/front_end/bindings/TempFile.js(96,42): error TS2304: Cannot find name 'FileError'. node_modules/chrome-devtools-frontend/front_end/bindings/TempFile.js(176,25): error TS2304: Cannot find name 'FileError'. -node_modules/chrome-devtools-frontend/front_end/bindings/TempFile.js(185,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/bindings/TempFile.js(189,33): error TS2339: Property 'Chunk' does not exist on type 'typeof TempFileBackingStorage'. node_modules/chrome-devtools-frontend/front_end/bindings_test_runner/AutomappingTestRunner.js(48,26): error TS2554: Expected 5 arguments, but got 4. node_modules/chrome-devtools-frontend/front_end/bindings_test_runner/AutomappingTestRunner.js(71,80): error TS2345: Argument of type 'Promise' is not assignable to parameter of type '() => Promise'. @@ -3209,7 +3187,11 @@ node_modules/chrome-devtools-frontend/front_end/bindings_test_runner/Persistence Type 'TestMapping' is not assignable to type '{ dispose: () => void; }'. Property '_onBindingAdded' does not exist on type '{ dispose: () => void; }'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(7,51): error TS2694: Namespace 'Changes.ChangesView' has no exported member 'Row'. -node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(9,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(9,56): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. +node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(10,75): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. +node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(11,53): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. +node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(12,53): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. +node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(12,91): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(22,42): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(47,11): error TS1345: An expression of type 'void' cannot be tested for truthiness node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(47,11): error TS1345: An expression of type 'void' cannot be tested for truthiness @@ -3228,8 +3210,7 @@ node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(14 node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(155,44): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(156,45): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(162,53): error TS2694: Namespace 'Changes.ChangesHighlighter' has no exported member 'DiffState'. -node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(169,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(181,28): error TS2339: Property 'DiffState' does not exist on type '(config: any, parserConfig: { diffRows: any[]; baselineLines: string[]; currentLines: string[]; mimeType: string; }) => {}'. +node_modules/chrome-devtools-frontend/front_end/changes/ChangesHighlighter.js(181,28): error TS2339: Property 'DiffState' does not exist on type '(config: any, parserConfig: { diffRows: any[]; baselineLines: string[]; currentLines: string[]; mimeType: string; }) => { startState: () => any; token: (arg0: { backUp: (n: any) => void; column: () => void; current: () => void; ... 10 more ...; sol: () => void; } & StringStream, arg1: any) => string; blankLine: (arg...'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesSidebar.js(30,90): error TS2339: Property 'uiSourceCode' does not exist on type 'TreeElement'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesSidebar.js(38,22): error TS2694: Namespace 'Common' has no exported member 'Event'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesView.js(26,44): error TS2694: Namespace 'Changes.ChangesView' has no exported member 'Row'. @@ -3256,7 +3237,6 @@ node_modules/chrome-devtools-frontend/front_end/changes/ChangesView.js(215,15): node_modules/chrome-devtools-frontend/front_end/changes/ChangesView.js(216,19): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/changes/ChangesView.js(239,45): error TS2694: Namespace 'Changes.ChangesView' has no exported member 'Row'. node_modules/chrome-devtools-frontend/front_end/changes/ChangesView.js(270,38): error TS2694: Namespace 'Changes.ChangesView' has no exported member 'Row'. -node_modules/chrome-devtools-frontend/front_end/changes/ChangesView.js(308,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/changes/ChangesView.js(314,21): error TS2339: Property 'Row' does not exist on type 'typeof ChangesView'. node_modules/chrome-devtools-frontend/front_end/cm/activeline.js(6,17): error TS2307: Cannot find module '../../lib/codemirror'. node_modules/chrome-devtools-frontend/front_end/cm/activeline.js(7,19): error TS2304: Cannot find name 'define'. @@ -3659,7 +3639,7 @@ node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(13,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(20,29): error TS2694: Namespace 'Common.Renderer' has no exported member 'Options'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(27,15): error TS2339: Property 'runtime' does not exist on type 'Window'. -node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(39,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(40,17): error TS2300: Duplicate identifier 'Options'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(40,17): error TS2339: Property 'Options' does not exist on type '{ (): void; prototype: { render(object: any, options: any): Promise; }; renderPromise(object: any, options?: any): Promise; }'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(63,15): error TS2339: Property 'runtime' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/common/ModuleExtensionInterfaces.js(81,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. @@ -3815,8 +3795,6 @@ node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(572,16): node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(580,16): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(587,16): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(616,5): error TS2322: Type '({ section: string; title: any; handler: () => void; } | { section: string; title: string; handler: any; })[]' is not assignable to type '{ title: string; handler: () => any; }[]'. -node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(631,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(646,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(666,22): error TS2551: Property 'LinkHandler' does not exist on type 'typeof Linkifier'. Did you mean '_linkHandlers'? node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(668,47): error TS2694: Namespace 'Components.Linkifier' has no exported member 'LinkHandler'. node_modules/chrome-devtools-frontend/front_end/components/Linkifier.js(675,1): error TS8022: JSDoc '@extends' is not attached to a class. @@ -4392,8 +4370,6 @@ node_modules/chrome-devtools-frontend/front_end/cookie_table/CookiesTable.js(416 node_modules/chrome-devtools-frontend/front_end/cookie_table/CookiesTable.js(461,42): error TS2339: Property 'asParsedURL' does not exist on type 'string'. node_modules/chrome-devtools-frontend/front_end/cookie_table/CookiesTable.js(470,51): error TS2339: Property 'asParsedURL' does not exist on type 'string'. node_modules/chrome-devtools-frontend/front_end/cookie_table/CookiesTable.js(489,49): error TS2555: Expected at least 2 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(7,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(7,7): error TS2300: Duplicate identifier 'id'. node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(50,68): error TS2339: Property 'get' does not exist on type 'Multimap'. node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(115,45): error TS2339: Property 'set' does not exist on type 'Multimap'. node_modules/chrome-devtools-frontend/front_end/coverage/CoverageDecorationManager.js(135,32): error TS2694: Namespace 'Coverage' has no exported member 'RawLocation'. @@ -4642,8 +4618,6 @@ node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1162,54): node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1170,23): error TS2339: Property 'offsetWidth' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1175,40): error TS2339: Property '__position' does not exist on type 'Element | { __index: number; __position: number; }'. Property '__position' does not exist on type 'Element'. -node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1200,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1200,6): error TS2300: Duplicate identifier 'id'. node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1214,19): error TS2339: Property 'ColumnDescriptor' does not exist on type 'typeof DataGrid'. node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1324,19): error TS2339: Property '_dataGridNode' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/data_grid/DataGrid.js(1334,14): error TS2551: Property 'dirty' does not exist on type 'DataGridNode'. Did you mean '_dirty'? @@ -6213,14 +6187,10 @@ node_modules/chrome-devtools-frontend/front_end/externs.js(79,17): error TS2551: node_modules/chrome-devtools-frontend/front_end/externs.js(82,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(86,17): error TS2339: Property 'rotate' does not exist on type 'any[]'. node_modules/chrome-devtools-frontend/front_end/externs.js(90,17): error TS2339: Property 'sortNumbers' does not exist on type 'any[]'. -node_modules/chrome-devtools-frontend/front_end/externs.js(92,13): error TS2304: Cannot find name 'S'. node_modules/chrome-devtools-frontend/front_end/externs.js(96,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(100,17): error TS2339: Property 'lowerBound' does not exist on type 'any[]'. -node_modules/chrome-devtools-frontend/front_end/externs.js(102,13): error TS2304: Cannot find name 'S'. node_modules/chrome-devtools-frontend/front_end/externs.js(106,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(110,17): error TS2339: Property 'upperBound' does not exist on type 'any[]'. -node_modules/chrome-devtools-frontend/front_end/externs.js(112,13): error TS2304: Cannot find name 'S'. -node_modules/chrome-devtools-frontend/front_end/externs.js(113,22): error TS2304: Cannot find name 'S'. node_modules/chrome-devtools-frontend/front_end/externs.js(114,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(118,17): error TS2339: Property 'binaryIndexOf' does not exist on type 'any[]'. node_modules/chrome-devtools-frontend/front_end/externs.js(125,13): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. @@ -6258,7 +6228,8 @@ node_modules/chrome-devtools-frontend/front_end/externs.js(278,13): error TS2355 node_modules/chrome-devtools-frontend/front_end/externs.js(328,175): error TS2694: Namespace 'Adb' has no exported member 'Page'. node_modules/chrome-devtools-frontend/front_end/externs.js(330,88): error TS2694: Namespace 'Adb' has no exported member 'Browser'. node_modules/chrome-devtools-frontend/front_end/externs.js(338,36): error TS2694: Namespace 'Adb' has no exported member 'DevicePortForwardingStatus'. -node_modules/chrome-devtools-frontend/front_end/externs.js(344,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/externs.js(346,33): error TS2694: Namespace 'Adb' has no exported member 'PortForwardingConfig'. +node_modules/chrome-devtools-frontend/front_end/externs.js(348,35): error TS2694: Namespace 'Adb' has no exported member 'NetworkDiscoveryConfig'. node_modules/chrome-devtools-frontend/front_end/externs.js(366,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(395,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/externs.js(443,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. @@ -6524,7 +6495,6 @@ node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapsho node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1083,14): error TS2339: Property 'key' does not exist on type '(arg0: HeapSnapshotNode) => boolean'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1086,14): error TS2339: Property 'key' does not exist on type '(arg0: HeapSnapshotNode) => boolean'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1143,31): error TS2339: Property 'key' does not exist on type '(arg0: HeapSnapshotNode) => boolean'. -node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1195,53): error TS2551: Property 'aggregatesByClassIndex' does not exist on type '{ aggregatesByClassName: { [x: string]: any; }; }'. Did you mean 'aggregatesByClassName'? node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1230,33): error TS2339: Property 'traceNodeId' does not exist on type 'void'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1253,14): error TS2339: Property 'nodeIndex' does not exist on type 'void'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1254,23): error TS2339: Property 'id' does not exist on type 'void'. @@ -6532,9 +6502,7 @@ node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapsho node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1345,12): error TS2339: Property 'nodeIndex' does not exist on type 'void'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1355,31): error TS2345: Argument of type 'void' is not assignable to parameter of type 'HeapSnapshotNode'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1369,89): error TS2694: Namespace 'HeapSnapshotWorker.HeapSnapshot' has no exported member 'AggregatedInfo'. -node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1370,4): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1424,59): error TS2322: Type '{ aggregatesByClassName: {}; aggregatesByClassIndex: {}; }' is not assignable to type '{ aggregatesByClassName: { [x: string]: any; }; }'. - Object literal may only specify known properties, but 'aggregatesByClassIndex' does not exist in type '{ aggregatesByClassName: { [x: string]: any; }; }'. Did you mean to write 'aggregatesByClassName'? +node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1370,83): error TS2694: Namespace 'HeapSnapshotWorker.HeapSnapshot' has no exported member 'AggregatedInfo'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1428,63): error TS2694: Namespace 'HeapSnapshotWorker.HeapSnapshot' has no exported member 'AggregatedInfo'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1447,12): error TS2339: Property 'nodeIndex' does not exist on type 'void'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(1448,29): error TS2339: Property 'classIndex' does not exist on type 'void'. @@ -6579,7 +6547,6 @@ node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapsho Type '(index: number) => HeapSnapshotRetainerEdge' is not assignable to type '(newIndex: number) => { itemIndex(): number; serialize(): any; }'. Type 'HeapSnapshotRetainerEdge' is not assignable to type '{ itemIndex(): number; serialize(): any; }'. Property '_snapshot' does not exist on type '{ itemIndex(): number; serialize(): any; }'. -node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(2118,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(2126,33): error TS2339: Property 'AggregatedInfo' does not exist on type 'typeof HeapSnapshot'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(2205,12): error TS2339: Property 'sort' does not exist on type 'HeapSnapshotItemProvider'. node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker/HeapSnapshot.js(2244,13): error TS2345: Argument of type 'HeapSnapshotEdgeIterator' is not assignable to parameter of type '{ hasNext(): boolean; item(): { itemIndex(): number; serialize(): any; }; next(): void; }'. @@ -6637,7 +6604,6 @@ node_modules/chrome-devtools-frontend/front_end/heap_snapshot_worker.js(6,8): er node_modules/chrome-devtools-frontend/front_end/help/Help.js(6,19): error TS2694: Namespace 'Help' has no exported member 'ReleaseNote'. node_modules/chrome-devtools-frontend/front_end/help/Help.js(10,22): error TS2694: Namespace 'Help' has no exported member 'ReleaseNote'. node_modules/chrome-devtools-frontend/front_end/help/Help.js(61,74): error TS2694: Namespace 'Help' has no exported member 'ReleaseNoteHighlight'. -node_modules/chrome-devtools-frontend/front_end/help/Help.js(62,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/help/ReleaseNoteText.js(12,25): error TS2694: Namespace 'Help' has no exported member 'ReleaseNote'. node_modules/chrome-devtools-frontend/front_end/help/ReleaseNoteView.js(10,42): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/help/ReleaseNoteView.js(11,30): error TS2555: Expected at least 2 arguments, but got 1. @@ -6662,6 +6628,7 @@ node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(27 Index signature is missing in type '{}'. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(407,19): error TS2694: Namespace 'Adb' has no exported member 'Config'. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(445,48): error TS2694: Namespace 'InspectorFrontendHostAPI' has no exported member 'ContextMenuDescriptor'. +node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(471,12): error TS2538: Type 'string[]' cannot be used as an index type. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(521,8): error TS2339: Property 'InspectorFrontendHost' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(527,14): error TS2339: Property 'InspectorFrontendHost' does not exist on type 'Window'. node_modules/chrome-devtools-frontend/front_end/host/InspectorFrontendHost.js(557,10): error TS2339: Property 'InspectorFrontendAPI' does not exist on type 'Window'. @@ -7155,9 +7122,9 @@ node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingMana node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingManager.js(218,82): error TS2339: Property 'selectedIndex' does not exist on type 'EventTarget'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingManager.js(224,32): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingManager.js(266,15): error TS2339: Property 'singleton' does not exist on type 'Window'. -node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(14,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(14,6): error TS2300: Duplicate identifier 'title'. -node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(14,6): error TS2300: Duplicate identifier 'title'. +node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(16,35): error TS2694: Namespace 'SDK.NetworkManager' has no exported member 'Conditions'. +node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(17,43): error TS2694: Namespace 'MobileThrottling' has no exported member 'CPUThrottlingRates'. +node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(20,18): error TS2300: Duplicate identifier 'Conditions'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(22,30): error TS2694: Namespace 'MobileThrottling' has no exported member 'Conditions'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(25,16): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(30,30): error TS2694: Namespace 'MobileThrottling' has no exported member 'Conditions'. @@ -7168,8 +7135,6 @@ node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPres node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(46,30): error TS2694: Namespace 'MobileThrottling' has no exported member 'Conditions'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(48,10): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(49,16): error TS2555: Expected at least 2 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(56,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(56,6): error TS2300: Duplicate identifier 'title'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(62,30): error TS2694: Namespace 'MobileThrottling' has no exported member 'PlaceholderConditions'. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(64,10): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/mobile_throttling/ThrottlingPresets.js(65,16): error TS2555: Expected at least 2 arguments, but got 1. @@ -7456,8 +7421,7 @@ node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(481,66): error TS2694: Namespace 'Network.NetworkLogViewColumns' has no exported member 'Descriptor'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(522,19): error TS2694: Namespace 'UI' has no exported member 'PopoverRequest'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(531,31): error TS2339: Property 'enclosingNodeOrSelfWithClass' does not exist on type 'EventTarget'. -node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(601,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(601,8): error TS2300: Duplicate identifier 'id'. +node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(616,31): error TS2300: Duplicate identifier 'Descriptor'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(616,31): error TS2339: Property 'Descriptor' does not exist on type 'typeof NetworkLogViewColumns'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(640,50): error TS2694: Namespace 'Network.NetworkLogViewColumns' has no exported member 'Descriptor'. node_modules/chrome-devtools-frontend/front_end/network/NetworkLogViewColumns.js(645,12): error TS2555: Expected at least 2 arguments, but got 1. @@ -8021,10 +7985,8 @@ node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1167,15): node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1169,70): error TS2339: Property 'peekLast' does not exist on type 'any[]'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1273,25): error TS2339: Property 'style' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1286,19): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'. -node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1387,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1387,8): error TS2451: Cannot redeclare block-scoped variable 'name'. +node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1390,34): error TS2694: Namespace 'PerfUI.FlameChart' has no exported member 'GroupStyle'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1393,19): error TS2339: Property 'Group' does not exist on type 'typeof FlameChart'. -node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1397,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1410,19): error TS2339: Property 'GroupStyle' does not exist on type 'typeof FlameChart'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1420,40): error TS2694: Namespace 'PerfUI.FlameChart' has no exported member 'Group'. node_modules/chrome-devtools-frontend/front_end/perf_ui/FlameChart.js(1438,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. @@ -8219,7 +8181,7 @@ node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemMa node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemManager.js(154,72): error TS2694: Namespace 'Persistence.IsolatedFileSystemManager' has no exported member 'FileSystem'. node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemManager.js(171,22): error TS2694: Namespace 'Common' has no exported member 'Event'. node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemManager.js(185,22): error TS2694: Namespace 'Common' has no exported member 'Event'. -node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemManager.js(211,37): error TS2345: Argument of type 'string' is not assignable to parameter of type 'V'. +node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemManager.js(211,21): error TS2345: Argument of type 'string' is not assignable to parameter of type 'K'. node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemManager.js(222,30): error TS2339: Property 'valuesArray' does not exist on type 'Map'. node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemManager.js(284,22): error TS2694: Namespace 'Common' has no exported member 'Event'. node_modules/chrome-devtools-frontend/front_end/persistence/IsolatedFileSystemManager.js(297,22): error TS2694: Namespace 'Common' has no exported member 'Event'. @@ -8326,13 +8288,6 @@ node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1164,15): node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1169,24): error TS2304: Cannot find name 'KEY'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1169,30): error TS2304: Cannot find name 'VALUE'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1171,15): error TS2339: Property 'inverse' does not exist on type 'Map'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1191,14): error TS2304: Cannot find name 'K'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1204,14): error TS2304: Cannot find name 'K'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1215,14): error TS2304: Cannot find name 'K'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1223,14): error TS2304: Cannot find name 'K'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1242,14): error TS2304: Cannot find name 'K'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1257,14): error TS2304: Cannot find name 'K'. -node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1264,23): error TS2304: Cannot find name 'K'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1277,14): error TS2339: Property 'pushAll' does not exist on type 'any[]'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1277,40): error TS2339: Property 'valuesArray' does not exist on type 'Set'. node_modules/chrome-devtools-frontend/front_end/platform/utilities.js(1299,35): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. @@ -8983,7 +8938,6 @@ node_modules/chrome-devtools-frontend/front_end/profiler/TopDownProfileDataGrid. node_modules/chrome-devtools-frontend/front_end/protocol/InspectorBackend.js(168,40): error TS2345: Argument of type 'S' is not assignable to parameter of type 'S'. node_modules/chrome-devtools-frontend/front_end/protocol/InspectorBackend.js(170,24): error TS2345: Argument of type 'S' is not assignable to parameter of type 'T'. node_modules/chrome-devtools-frontend/front_end/protocol/InspectorBackend.js(194,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. -node_modules/chrome-devtools-frontend/front_end/protocol/InspectorBackend.js(201,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/protocol/InspectorBackend.js(205,38): error TS2339: Property 'Params' does not exist on type '{ (): void; prototype: { sendMessage(message: string): void; disconnect(): Promise; }; }'. node_modules/chrome-devtools-frontend/front_end/protocol/InspectorBackend.js(208,61): error TS2694: Namespace 'Protocol.InspectorBackend.Connection' has no exported member 'Params'. node_modules/chrome-devtools-frontend/front_end/protocol/InspectorBackend.js(210,38): error TS2339: Property 'Factory' does not exist on type '{ (): void; prototype: { sendMessage(message: string): void; disconnect(): Promise; }; }'. @@ -9232,7 +9186,7 @@ node_modules/chrome-devtools-frontend/front_end/resources/DatabaseTableView.js(1 node_modules/chrome-devtools-frontend/front_end/resources/IndexedDBModel.js(41,12): error TS2339: Property 'registerStorageDispatcher' does not exist on type 'Target'. node_modules/chrome-devtools-frontend/front_end/resources/IndexedDBModel.js(43,35): error TS2339: Property 'indexedDBAgent' does not exist on type 'Target'. node_modules/chrome-devtools-frontend/front_end/resources/IndexedDBModel.js(44,33): error TS2339: Property 'storageAgent' does not exist on type 'Target'. -node_modules/chrome-devtools-frontend/front_end/resources/IndexedDBModel.js(58,4): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/resources/IndexedDBModel.js(62,24): error TS2694: Namespace 'Protocol' has no exported member 'IndexedDB'. node_modules/chrome-devtools-frontend/front_end/resources/IndexedDBModel.js(94,37): error TS2694: Namespace 'Protocol' has no exported member 'IndexedDB'. node_modules/chrome-devtools-frontend/front_end/resources/IndexedDBModel.js(100,25): error TS2694: Namespace 'Protocol' has no exported member 'IndexedDB'. node_modules/chrome-devtools-frontend/front_end/resources/IndexedDBModel.js(112,24): error TS2694: Namespace 'Protocol' has no exported member 'IndexedDB'. @@ -9818,7 +9772,7 @@ node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(838,24): er node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(839,31): error TS2694: Namespace 'Common' has no exported member 'Event'. node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(899,22): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(908,19): error TS2339: Property 'FunctionDetails' does not exist on type 'typeof DebuggerModel'. -node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(967,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(967,31): error TS2694: Namespace 'Protocol' has no exported member 'Debugger'. node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(971,19): error TS2339: Property 'SetBreakpointResult' does not exist on type 'typeof DebuggerModel'. node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(987,32): error TS2694: Namespace 'Protocol' has no exported member 'Debugger'. node_modules/chrome-devtools-frontend/front_end/sdk/DebuggerModel.js(991,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. @@ -9918,7 +9872,7 @@ node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(154,5): er Index signature is missing in type '{}'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(166,22): error TS2694: Namespace 'Common' has no exported member 'Event'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(199,20): error TS2339: Property 'Message' does not exist on type 'typeof NetworkManager'. -node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(214,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(220,20): error TS2300: Duplicate identifier 'Conditions'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(220,20): error TS2339: Property 'Conditions' does not exist on type 'typeof NetworkManager'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(222,32): error TS2694: Namespace 'SDK.NetworkManager' has no exported member 'Conditions'. node_modules/chrome-devtools-frontend/front_end/sdk/NetworkManager.js(224,10): error TS2555: Expected at least 2 arguments, but got 1. @@ -10300,16 +10254,17 @@ node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(449,24): err node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(458,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(484,54): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(485,18): error TS2339: Property 'ExceptionWithTimestamp' does not exist on type 'typeof RuntimeModel'. -node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(488,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(488,27): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. +node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(489,36): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(492,18): error TS2339: Property 'CompileScriptResult' does not exist on type 'typeof RuntimeModel'. -node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(495,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(503,18): error TS2339: Property 'EvaluationOptions' does not exist on type 'typeof RuntimeModel'. -node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(506,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(506,7): error TS2457: Type alias name cannot be 'object'. +node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(507,36): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. +node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(508,25): error TS2694: Namespace 'Protocol' has no exported member 'Error'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(511,18): error TS2339: Property 'EvaluationResult' does not exist on type 'typeof RuntimeModel'. -node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(514,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(515,25): error TS2694: Namespace 'Protocol' has no exported member 'Error'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(518,18): error TS2339: Property 'QueryObjectResult' does not exist on type 'typeof RuntimeModel'. -node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(522,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(523,30): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. +node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(526,30): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(529,18): error TS2339: Property 'ConsoleAPICall' does not exist on type 'typeof RuntimeModel'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(545,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. node_modules/chrome-devtools-frontend/front_end/sdk/RuntimeModel.js(553,24): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. @@ -11006,7 +10961,8 @@ node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js( node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(379,13): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(382,13): error TS2555: Expected at least 2 arguments, but got 1. node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(415,52): error TS2694: Namespace 'UI.KeyboardShortcut' has no exported member 'Descriptor'. -node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(429,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(431,36): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. +node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(435,30): error TS2300: Duplicate identifier 'Item'. node_modules/chrome-devtools-frontend/front_end/sources/CallStackSidebarPane.js(435,30): error TS2339: Property 'Item' does not exist on type 'typeof CallStackSidebarPane'. node_modules/chrome-devtools-frontend/front_end/sources/DebuggerPausedMessage.js(11,33): error TS2339: Property 'createChild' does not exist on type 'DocumentFragment'. node_modules/chrome-devtools-frontend/front_end/sources/DebuggerPausedMessage.js(54,37): error TS2555: Expected at least 2 arguments, but got 1. @@ -11720,11 +11676,10 @@ node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(337,33 node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(338,37): error TS2339: Property 'profilerAgent' does not exist on type 'Target'. node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(339,36): error TS2339: Property 'runtimeAgent' does not exist on type 'Target'. node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(340,35): error TS2339: Property 'targetAgent' does not exist on type 'Target'. -node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(363,62): error TS2339: Property 'result' does not exist on type '{ response: RemoteObject; }'. +node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(363,62): error TS2339: Property 'result' does not exist on type '{ response: RemoteObject; exceptionDetails: any; }'. node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(368,34): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. -node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(372,42): error TS2339: Property 'result' does not exist on type '{ response: RemoteObject; }'. -node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(372,65): error TS2339: Property 'exceptionDetails' does not exist on type '{ response: RemoteObject; }'. -node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(381,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(372,42): error TS2339: Property 'result' does not exist on type '{ response: RemoteObject; exceptionDetails: any; }'. +node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(381,35): error TS2694: Namespace 'Protocol' has no exported member 'Runtime'. node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(503,30): error TS2345: Argument of type 'Function' is not assignable to parameter of type '(value: [any, any, any, any, any, any, any, any, any, any]) => [any, any, any, any, any, any, any, any, any, any] | PromiseLike<[any, any, any, any, any, any, any, any, any, any]>'. Type 'Function' provides no match for the signature '(value: [any, any, any, any, any, any, any, any, any, any]): [any, any, any, any, any, any, any, any, any, any] | PromiseLike<[any, any, any, any, any, any, any, any, any, any]>'. node_modules/chrome-devtools-frontend/front_end/test_runner/TestRunner.js(641,59): error TS2339: Property 'testRunner' does not exist on type 'Window'. @@ -11845,7 +11800,6 @@ node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1637,12): error TS1345: An expression of type 'void' cannot be tested for truthiness node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1637,61): error TS2339: Property 'line' does not exist on type 'void'. node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1637,71): error TS2339: Property 'ch' does not exist on type 'void'. -node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1645,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1650,33): error TS2339: Property 'Decoration' does not exist on type 'typeof CodeMirrorTextEditor'. node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorTextEditor.js(1659,29): error TS2694: Namespace 'UI.TextEditor' has no exported member 'Options'. node_modules/chrome-devtools-frontend/front_end/text_editor/CodeMirrorUtils.js(53,24): error TS2694: Namespace 'CodeMirror' has no exported member 'ChangeObject'. @@ -11987,11 +11941,8 @@ node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(2 node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(295,43): error TS2694: Namespace 'Timeline.PerformanceMonitor' has no exported member 'MetricInfo'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(320,41): error TS2339: Property 'peekLast' does not exist on type '{ timestamp: number; metrics: Map; }[]'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(330,24): error TS2339: Property 'constrain' does not exist on type 'NumberConstructor'. -node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(394,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(394,6): error TS2300: Duplicate identifier 'title'. +node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(395,51): error TS2694: Namespace 'Timeline.PerformanceMonitor' has no exported member 'MetricInfo'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(402,29): error TS2339: Property 'ChartInfo' does not exist on type 'typeof PerformanceMonitor'. -node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(406,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(406,6): error TS2451: Cannot redeclare block-scoped variable 'name'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(411,29): error TS2339: Property 'MetricInfo' does not exist on type 'typeof PerformanceMonitor'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(419,27): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/PerformanceMonitor.js(427,52): error TS2694: Namespace 'Timeline.PerformanceMonitor' has no exported member 'ChartInfo'. @@ -12016,7 +11967,6 @@ node_modules/chrome-devtools-frontend/front_end/timeline/TimelineController.js(2 node_modules/chrome-devtools-frontend/front_end/timeline/TimelineController.js(214,58): error TS2694: Namespace 'SDK.TracingManager' has no exported member 'EventPayload'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineController.js(233,96): error TS2339: Property 'peekLast' does not exist on type 'Event[]'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineController.js(272,1): error TS8022: JSDoc '@extends' is not attached to a class. -node_modules/chrome-devtools-frontend/front_end/timeline/TimelineController.js(283,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineController.js(288,29): error TS2339: Property 'RecordingOptions' does not exist on type 'typeof TimelineController'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineDetailsView.js(29,44): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineDetailsView.js(31,37): error TS2555: Expected at least 2 arguments, but got 1. @@ -12657,8 +12607,6 @@ node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2057 node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2059,21): error TS2339: Property 'createTextChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2078,23): error TS2339: Property 'createTextChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2078,39): error TS2555: Expected at least 2 arguments, but got 1. -node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2146,2): error TS1131: Property or signature expected. -node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2146,8): error TS2300: Duplicate identifier 'title'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2167,15): error TS2339: Property 'colSpan' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2186,10): error TS2339: Property 'createTextChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js(2191,5): error TS2322: Type 'string | number' is not assignable to type 'string'. @@ -12898,11 +12846,10 @@ node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(171,22): error TS node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(174,21): error TS2339: Property 'remove' does not exist on type 'Node'. node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(179,27): error TS2694: Namespace 'UI.Fragment' has no exported member '_Template'. node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(247,24): error TS2488: Type 'NodeListOf' must have a '[Symbol.iterator]()' method that returns an iterator. -node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(272,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(273,33): error TS2694: Namespace 'UI.Fragment' has no exported member '_Bind'. node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(276,13): error TS2551: Property '_Template' does not exist on type 'typeof Fragment'. Did you mean '_template'? -node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(280,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(286,13): error TS2339: Property '_State' does not exist on type 'typeof Fragment'. -node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(290,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(292,2): error TS1131: Property or signature expected. node_modules/chrome-devtools-frontend/front_end/ui/Fragment.js(307,13): error TS2339: Property '_Bind' does not exist on type 'typeof Fragment'. node_modules/chrome-devtools-frontend/front_end/ui/Geometry.js(210,15): error TS2304: Cannot find name 'CSSMatrix'. node_modules/chrome-devtools-frontend/front_end/ui/Geometry.js(272,13): error TS2304: Cannot find name 'CSSMatrix'. @@ -13346,9 +13293,9 @@ node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(47,15): error T node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(58,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(70,18): error TS2694: Namespace 'UI' has no exported member 'AutocompleteConfig'. node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(79,15): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. -node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(91,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(101,15): error TS2300: Duplicate identifier 'Options'. node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(101,15): error TS2339: Property 'Options' does not exist on type '{ (): void; prototype: { widget(): Widget; fullRange(): TextRange; selection(): TextRange; setSelection(selection: TextRange): void; text(textRange?: TextRange): string; setText(text: string): void; ... 5 more ...; tokenAtTextPosition(lineNumber: number, columnNumber: number): { ...; }; }; Events: { ...; }; }'. -node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(105,2): error TS1131: Property or signature expected. +node_modules/chrome-devtools-frontend/front_end/ui/TextEditor.js(106,119): error TS2694: Namespace 'UI.SuggestBox' has no exported member 'Suggestions'. node_modules/chrome-devtools-frontend/front_end/ui/TextPrompt.js(52,74): error TS2694: Namespace 'UI.SuggestBox' has no exported member 'Suggestions'. node_modules/chrome-devtools-frontend/front_end/ui/TextPrompt.js(113,39): error TS2339: Property 'createChild' does not exist on type 'DocumentFragment'. node_modules/chrome-devtools-frontend/front_end/ui/TextPrompt.js(115,24): error TS2339: Property 'style' does not exist on type 'Element'. diff --git a/tests/baselines/reference/user/npm.log b/tests/baselines/reference/user/npm.log index d808deab385..f2db4a09546 100644 --- a/tests/baselines/reference/user/npm.log +++ b/tests/baselines/reference/user/npm.log @@ -498,6 +498,9 @@ node_modules/npm/lib/ls.js(260,16): error TS2339: Property 'problems' does not e Property 'problems' does not exist on type 'string'. node_modules/npm/lib/ls.js(262,54): error TS2339: Property 'problems' does not exist on type 'string | { name: any; version: any; extraneous: boolean; problems: any; invalid: boolean; from: any; resolved: any; peerInvalid: boolean; dependencies: {}; } | { required: any; missing: boolean; } | { ...; }'. Property 'problems' does not exist on type 'string'. +node_modules/npm/lib/ls.js(264,12): error TS2538: Type '{ name: any; version: any; extraneous: boolean; problems: any; invalid: boolean; from: any; resolved: any; peerInvalid: boolean; dependencies: {}; }' cannot be used as an index type. +node_modules/npm/lib/ls.js(264,12): error TS2538: Type '{ required: any; missing: boolean; }' cannot be used as an index type. +node_modules/npm/lib/ls.js(264,12): error TS2538: Type '{ required: any; peerMissing: boolean; }' cannot be used as an index type. node_modules/npm/lib/ls.js(357,40): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/ls.js(362,26): error TS2339: Property 'config' does not exist on type 'typeof EventEmitter'. node_modules/npm/lib/ls.js(365,15): error TS2339: Property 'color' does not exist on type 'typeof EventEmitter'. From d8f736d319aead69fcf9541877ac2919638103b9 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 6 Sep 2018 00:41:09 -0700 Subject: [PATCH 157/163] Change `typeof` narrowing to narrow selected union members (#25243) * For typeof narrow all union members prior to filtering * Revise narrowTypeByTypeof to both narrow unions and applicable union members * Add repros from issue --- src/compiler/checker.ts | 46 ++++++------ .../reference/controlFlowIfStatement.types | 2 +- .../reference/recursiveTypeRelations.types | 4 +- .../reference/strictTypeofUnionNarrowing.js | 32 +++++++++ .../strictTypeofUnionNarrowing.symbols | 47 ++++++++++++ .../strictTypeofUnionNarrowing.types | 71 +++++++++++++++++++ ...ypeGuardOfFormTypeOfPrimitiveSubtype.types | 12 ++-- .../reference/typeGuardTypeOfUndefined.types | 36 +++++----- .../compiler/strictTypeofUnionNarrowing.ts | 16 +++++ 9 files changed, 218 insertions(+), 48 deletions(-) create mode 100644 tests/baselines/reference/strictTypeofUnionNarrowing.js create mode 100644 tests/baselines/reference/strictTypeofUnionNarrowing.symbols create mode 100644 tests/baselines/reference/strictTypeofUnionNarrowing.types create mode 100644 tests/cases/compiler/strictTypeofUnionNarrowing.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ef173a2c667..5709b1b1616 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14963,30 +14963,34 @@ namespace ts { if (type.flags & TypeFlags.Any && literal.text === "function") { return type; } - if (assumeTrue && !(type.flags & TypeFlags.Union)) { - if (type.flags & TypeFlags.Unknown && literal.text === "object") { - return getUnionType([nonPrimitiveType, nullType]); - } - // We narrow a non-union type to an exact primitive type if the non-union type - // is a supertype of that primitive type. For example, type 'any' can be narrowed - // to one of the primitive types. - const targetType = literal.text === "function" ? globalFunctionType : typeofTypesByName.get(literal.text); - if (targetType) { - if (isTypeSubtypeOf(targetType, type)) { - return targetType; - } - if (type.flags & TypeFlags.Instantiable) { - const constraint = getBaseConstraintOfType(type) || anyType; - if (isTypeSubtypeOf(targetType, constraint)) { - return getIntersectionType([type, targetType]); - } - } - } - } const facts = assumeTrue ? typeofEQFacts.get(literal.text) || TypeFacts.TypeofEQHostObject : typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject; - return getTypeWithFacts(type, facts); + return getTypeWithFacts(assumeTrue ? mapType(type, narrowTypeForTypeof) : type, facts); + + function narrowTypeForTypeof(type: Type) { + if (assumeTrue && !(type.flags & TypeFlags.Union)) { + if (type.flags & TypeFlags.Unknown && literal.text === "object") { + return getUnionType([nonPrimitiveType, nullType]); + } + // We narrow a non-union type to an exact primitive type if the non-union type + // is a supertype of that primitive type. For example, type 'any' can be narrowed + // to one of the primitive types. + const targetType = literal.text === "function" ? globalFunctionType : typeofTypesByName.get(literal.text); + if (targetType) { + if (isTypeSubtypeOf(targetType, type)) { + return isTypeAny(type) ? targetType : getIntersectionType([type, targetType]); // Intersection to handle `string` being a subtype of `keyof T` + } + if (type.flags & TypeFlags.Instantiable) { + const constraint = getBaseConstraintOfType(type) || anyType; + if (isTypeSubtypeOf(targetType, constraint)) { + return getIntersectionType([type, targetType]); + } + } + } + } + return type; + } } function narrowTypeBySwitchOnDiscriminant(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) { diff --git a/tests/baselines/reference/controlFlowIfStatement.types b/tests/baselines/reference/controlFlowIfStatement.types index 39083598ee2..03141e26185 100644 --- a/tests/baselines/reference/controlFlowIfStatement.types +++ b/tests/baselines/reference/controlFlowIfStatement.types @@ -104,7 +104,7 @@ function c(data: string | T): T { >JSON.parse : (text: string, reviver?: (key: any, value: any) => any) => any >JSON : JSON >parse : (text: string, reviver?: (key: any, value: any) => any) => any ->data : string +>data : string | (T & string) } else { return data; diff --git a/tests/baselines/reference/recursiveTypeRelations.types b/tests/baselines/reference/recursiveTypeRelations.types index 893986d2dab..3ca21ccd8e5 100644 --- a/tests/baselines/reference/recursiveTypeRelations.types +++ b/tests/baselines/reference/recursiveTypeRelations.types @@ -58,9 +58,9 @@ export function css(styles: S, ...classNam >"string" : "string" return styles[arg]; ->styles[arg] : S[keyof S] +>styles[arg] : S[keyof S & string] >styles : S ->arg : keyof S +>arg : keyof S & string } if (typeof arg == "object") { >typeof arg == "object" : boolean diff --git a/tests/baselines/reference/strictTypeofUnionNarrowing.js b/tests/baselines/reference/strictTypeofUnionNarrowing.js new file mode 100644 index 00000000000..93b9c7d4330 --- /dev/null +++ b/tests/baselines/reference/strictTypeofUnionNarrowing.js @@ -0,0 +1,32 @@ +//// [strictTypeofUnionNarrowing.ts] +function stringify1(anything: { toString(): string } | undefined): string { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} + +function stringify2(anything: {} | undefined): string { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} + +function stringify3(anything: unknown | undefined): string { // should simplify to just `unknown` which should narrow fine + return typeof anything === "string" ? anything.toUpperCase() : ""; +} + +function stringify4(anything: { toString?(): string } | undefined): string { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} + + +//// [strictTypeofUnionNarrowing.js] +"use strict"; +function stringify1(anything) { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} +function stringify2(anything) { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} +function stringify3(anything) { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} +function stringify4(anything) { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} diff --git a/tests/baselines/reference/strictTypeofUnionNarrowing.symbols b/tests/baselines/reference/strictTypeofUnionNarrowing.symbols new file mode 100644 index 00000000000..83a602eeaf1 --- /dev/null +++ b/tests/baselines/reference/strictTypeofUnionNarrowing.symbols @@ -0,0 +1,47 @@ +=== tests/cases/compiler/strictTypeofUnionNarrowing.ts === +function stringify1(anything: { toString(): string } | undefined): string { +>stringify1 : Symbol(stringify1, Decl(strictTypeofUnionNarrowing.ts, 0, 0)) +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 0, 20)) +>toString : Symbol(toString, Decl(strictTypeofUnionNarrowing.ts, 0, 31)) + + return typeof anything === "string" ? anything.toUpperCase() : ""; +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 0, 20)) +>anything.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 0, 20)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +} + +function stringify2(anything: {} | undefined): string { +>stringify2 : Symbol(stringify2, Decl(strictTypeofUnionNarrowing.ts, 2, 1)) +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 4, 20)) + + return typeof anything === "string" ? anything.toUpperCase() : ""; +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 4, 20)) +>anything.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 4, 20)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +} + +function stringify3(anything: unknown | undefined): string { // should simplify to just `unknown` which should narrow fine +>stringify3 : Symbol(stringify3, Decl(strictTypeofUnionNarrowing.ts, 6, 1)) +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 8, 20)) + + return typeof anything === "string" ? anything.toUpperCase() : ""; +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 8, 20)) +>anything.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 8, 20)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +} + +function stringify4(anything: { toString?(): string } | undefined): string { +>stringify4 : Symbol(stringify4, Decl(strictTypeofUnionNarrowing.ts, 10, 1)) +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 12, 20)) +>toString : Symbol(toString, Decl(strictTypeofUnionNarrowing.ts, 12, 31)) + + return typeof anything === "string" ? anything.toUpperCase() : ""; +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 12, 20)) +>anything.toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +>anything : Symbol(anything, Decl(strictTypeofUnionNarrowing.ts, 12, 20)) +>toUpperCase : Symbol(String.toUpperCase, Decl(lib.es5.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/strictTypeofUnionNarrowing.types b/tests/baselines/reference/strictTypeofUnionNarrowing.types new file mode 100644 index 00000000000..3039ece15d6 --- /dev/null +++ b/tests/baselines/reference/strictTypeofUnionNarrowing.types @@ -0,0 +1,71 @@ +=== tests/cases/compiler/strictTypeofUnionNarrowing.ts === +function stringify1(anything: { toString(): string } | undefined): string { +>stringify1 : (anything: { toString(): string; } | undefined) => string +>anything : { toString(): string; } | undefined +>toString : () => string + + return typeof anything === "string" ? anything.toUpperCase() : ""; +>typeof anything === "string" ? anything.toUpperCase() : "" : string +>typeof anything === "string" : boolean +>typeof anything : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>anything : { toString(): string; } | undefined +>"string" : "string" +>anything.toUpperCase() : string +>anything.toUpperCase : () => string +>anything : { toString(): string; } & string +>toUpperCase : () => string +>"" : "" +} + +function stringify2(anything: {} | undefined): string { +>stringify2 : (anything: {} | undefined) => string +>anything : {} | undefined + + return typeof anything === "string" ? anything.toUpperCase() : ""; +>typeof anything === "string" ? anything.toUpperCase() : "" : string +>typeof anything === "string" : boolean +>typeof anything : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>anything : {} | undefined +>"string" : "string" +>anything.toUpperCase() : string +>anything.toUpperCase : () => string +>anything : string & {} +>toUpperCase : () => string +>"" : "" +} + +function stringify3(anything: unknown | undefined): string { // should simplify to just `unknown` which should narrow fine +>stringify3 : (anything: unknown) => string +>anything : unknown + + return typeof anything === "string" ? anything.toUpperCase() : ""; +>typeof anything === "string" ? anything.toUpperCase() : "" : string +>typeof anything === "string" : boolean +>typeof anything : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>anything : unknown +>"string" : "string" +>anything.toUpperCase() : string +>anything.toUpperCase : () => string +>anything : string +>toUpperCase : () => string +>"" : "" +} + +function stringify4(anything: { toString?(): string } | undefined): string { +>stringify4 : (anything: {} | undefined) => string +>anything : {} | undefined +>toString : (() => string) | undefined + + return typeof anything === "string" ? anything.toUpperCase() : ""; +>typeof anything === "string" ? anything.toUpperCase() : "" : string +>typeof anything === "string" : boolean +>typeof anything : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>anything : {} | undefined +>"string" : "string" +>anything.toUpperCase() : string +>anything.toUpperCase : () => string +>anything : {} & string +>toUpperCase : () => string +>"" : "" +} + diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfPrimitiveSubtype.types b/tests/baselines/reference/typeGuardOfFormTypeOfPrimitiveSubtype.types index 4787c07d758..6510b73d44d 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfPrimitiveSubtype.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfPrimitiveSubtype.types @@ -14,7 +14,7 @@ if (typeof a === "number") { let c: number = a; >c : number ->a : number +>a : number & {} } if (typeof a === "string") { >typeof a === "string" : boolean @@ -24,7 +24,7 @@ if (typeof a === "string") { let c: string = a; >c : string ->a : string +>a : string & {} } if (typeof a === "boolean") { >typeof a === "boolean" : boolean @@ -34,7 +34,7 @@ if (typeof a === "boolean") { let c: boolean = a; >c : boolean ->a : boolean +>a : (false & {}) | (true & {}) } if (typeof b === "number") { @@ -45,7 +45,7 @@ if (typeof b === "number") { let c: number = b; >c : number ->b : number +>b : { toString(): string; } & number } if (typeof b === "string") { >typeof b === "string" : boolean @@ -55,7 +55,7 @@ if (typeof b === "string") { let c: string = b; >c : string ->b : string +>b : { toString(): string; } & string } if (typeof b === "boolean") { >typeof b === "boolean" : boolean @@ -65,6 +65,6 @@ if (typeof b === "boolean") { let c: boolean = b; >c : boolean ->b : boolean +>b : ({ toString(): string; } & false) | ({ toString(): string; } & true) } diff --git a/tests/baselines/reference/typeGuardTypeOfUndefined.types b/tests/baselines/reference/typeGuardTypeOfUndefined.types index a28dab04490..00777ac0eae 100644 --- a/tests/baselines/reference/typeGuardTypeOfUndefined.types +++ b/tests/baselines/reference/typeGuardTypeOfUndefined.types @@ -134,7 +134,7 @@ function test5(a: boolean | void) { } else { a; ->a : boolean | void +>a : undefined } } @@ -151,15 +151,15 @@ function test6(a: boolean | void) { if (typeof a === "boolean") { >typeof a === "boolean" : boolean >typeof a : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ->a : boolean | void +>a : undefined >"boolean" : "boolean" a; ->a : boolean +>a : never } else { a; ->a : void +>a : undefined } } else { @@ -184,7 +184,7 @@ function test7(a: boolean | void) { >"boolean" : "boolean" a; ->a : boolean | void +>a : boolean } else { a; @@ -212,7 +212,7 @@ function test8(a: boolean | void) { } else { a; ->a : boolean | void +>a : undefined } } @@ -242,7 +242,7 @@ function test9(a: boolean | number) { } else { a; ->a : number | boolean +>a : undefined } } @@ -259,15 +259,15 @@ function test10(a: boolean | number) { if (typeof a === "boolean") { >typeof a === "boolean" : boolean >typeof a : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ->a : number | boolean +>a : undefined >"boolean" : "boolean" a; ->a : boolean +>a : never } else { a; ->a : number +>a : undefined } } else { @@ -292,7 +292,7 @@ function test11(a: boolean | number) { >"boolean" : "boolean" a; ->a : number | boolean +>a : boolean } else { a; @@ -320,7 +320,7 @@ function test12(a: boolean | number) { } else { a; ->a : number | boolean +>a : number } } @@ -350,7 +350,7 @@ function test13(a: boolean | number | void) { } else { a; ->a : number | boolean | void +>a : undefined } } @@ -367,15 +367,15 @@ function test14(a: boolean | number | void) { if (typeof a === "boolean") { >typeof a === "boolean" : boolean >typeof a : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ->a : number | boolean | void +>a : undefined >"boolean" : "boolean" a; ->a : boolean +>a : never } else { a; ->a : number | void +>a : undefined } } else { @@ -400,7 +400,7 @@ function test15(a: boolean | number | void) { >"boolean" : "boolean" a; ->a : number | boolean | void +>a : boolean } else { a; @@ -428,7 +428,7 @@ function test16(a: boolean | number | void) { } else { a; ->a : number | boolean | void +>a : number } } diff --git a/tests/cases/compiler/strictTypeofUnionNarrowing.ts b/tests/cases/compiler/strictTypeofUnionNarrowing.ts new file mode 100644 index 00000000000..f2bddf3f939 --- /dev/null +++ b/tests/cases/compiler/strictTypeofUnionNarrowing.ts @@ -0,0 +1,16 @@ +// @strict: true +function stringify1(anything: { toString(): string } | undefined): string { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} + +function stringify2(anything: {} | undefined): string { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} + +function stringify3(anything: unknown | undefined): string { // should simplify to just `unknown` which should narrow fine + return typeof anything === "string" ? anything.toUpperCase() : ""; +} + +function stringify4(anything: { toString?(): string } | undefined): string { + return typeof anything === "string" ? anything.toUpperCase() : ""; +} From 3173cfee97529ea9b4e5a93df33b243c108c7609 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Thu, 6 Sep 2018 09:45:22 +0100 Subject: [PATCH 158/163] Update narrowing baseline --- .../reference/narrowingByTypeofInSwitch.types | 49 ------------------- 1 file changed, 49 deletions(-) diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.types b/tests/baselines/reference/narrowingByTypeofInSwitch.types index a2aef98feb4..000eea75f79 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.types +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.types @@ -42,7 +42,6 @@ function assertSymbol(x: symbol) { function assertFunction(x: Function) { >assertFunction : (x: Function) => Function >x : Function ->Function : Function return x; >x : Function @@ -67,7 +66,6 @@ function assertUndefined(x: undefined) { function assertAll(x: Basic) { >assertAll : (x: Basic) => Basic >x : Basic ->Basic : Basic return x; >x : Basic @@ -91,12 +89,10 @@ function assertBooleanOrObject(x: boolean | object) { type Basic = number | boolean | string | symbol | object | Function | undefined; >Basic : Basic ->Function : Function function testUnion(x: Basic) { >testUnion : (x: Basic) => void >x : Basic ->Basic : Basic switch (typeof x) { >typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -152,10 +148,7 @@ function testUnion(x: Basic) { function testExtendsUnion(x: T) { >testExtendsUnion : (x: T) => void ->T : T ->Basic : Basic >x : T ->T : T switch (typeof x) { >typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -276,7 +269,6 @@ function a1(x: string | object | undefined) { function testUnionExplicitDefault(x: Basic) { >testUnionExplicitDefault : (x: Basic) => void >x : Basic ->Basic : Basic switch (typeof x) { >typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -316,7 +308,6 @@ function testUnionExplicitDefault(x: Basic) { function testUnionImplicitDefault(x: Basic) { >testUnionImplicitDefault : (x: Basic) => string | object | undefined >x : Basic ->Basic : Basic switch (typeof x) { >typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -354,10 +345,7 @@ function testUnionImplicitDefault(x: Basic) { function testExtendsExplicitDefault(x: T) { >testExtendsExplicitDefault : (x: T) => void ->T : T ->Basic : Basic >x : T ->T : T switch (typeof x) { >typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -397,10 +385,7 @@ function testExtendsExplicitDefault(x: T) { function testExtendsImplicitDefault(x: T) { >testExtendsImplicitDefault : (x: T) => string | number | boolean | symbol | object | undefined ->T : T ->Basic : Basic >x : T ->T : T switch (typeof x) { >typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -448,8 +433,6 @@ type R = { x: string, y: number } function exhaustiveChecks(x: number | string | L | R): string { >exhaustiveChecks : (x: string | number | R | L) => string >x : string | number | R | L ->L : L ->R : R switch (typeof x) { >typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -483,11 +466,7 @@ function exhaustiveChecks(x: number | string | L | R): string { function exhaustiveChecksGenerics(x: T): string { >exhaustiveChecksGenerics : (x: T) => string ->T : T ->L : L ->R : R >x : T ->T : T switch (typeof x) { >typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -511,7 +490,6 @@ function exhaustiveChecksGenerics(x: T): stri >(x as L) : L >x as L : L >x : T ->L : L >42 : 42 case 'object': return (x as R).x; // Can't narrow generic @@ -520,22 +498,13 @@ function exhaustiveChecksGenerics(x: T): stri >(x as R) : R >x as R : R >x : T ->R : R >x : string } } function multipleGeneric(xy: X | Y): [X, string] | [Y, number] { >multipleGeneric : (xy: X | Y) => [X, string] | [Y, number] ->X : X ->L : L ->Y : Y ->R : R >xy : X | Y ->X : X ->Y : Y ->X : X ->Y : Y switch (typeof xy) { >typeof xy : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -566,17 +535,7 @@ function multipleGeneric(xy: X | Y): [X, string] | [Y, function multipleGenericFuse(xy: X | Y): [X, number] | [Y, string] | [(X | Y)] { >multipleGenericFuse : (xy: X | Y) => [X, number] | [Y, string] | [X | Y] ->X : X ->L : L ->Y : Y ->R : R >xy : X | Y ->X : X ->Y : Y ->X : X ->Y : Y ->X : X ->Y : Y switch (typeof xy) { >typeof xy : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -603,15 +562,7 @@ function multipleGenericFuse(xy: X | function multipleGenericExhaustive(xy: X | Y): [X, string] | [Y, number] { >multipleGenericExhaustive : (xy: X | Y) => [X, string] | [Y, number] ->X : X ->L : L ->Y : Y ->R : R >xy : X | Y ->X : X ->Y : Y ->X : X ->Y : Y switch (typeof xy) { >typeof xy : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" From 8c22770ea8ce739faf6deb25e2ba022cd1c9af6e Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 6 Sep 2018 10:44:32 -0700 Subject: [PATCH 159/163] Improve 'isWriteAccess' for findAllReferences (#26889) --- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 28 +++++---- src/services/findAllReferences.ts | 62 ++++++++++++++++++- .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../findAllReferencesJsDocTypeLiteral.ts | 2 +- .../findAllRefsDestructureGeneric.ts | 2 +- .../findAllRefsForComputedProperties.ts | 2 +- .../findAllRefsForComputedProperties2.ts | 2 +- .../fourslash/findAllRefsForMappedType.ts | 2 +- .../fourslash/findAllRefsForObjectSpread.ts | 4 +- tests/cases/fourslash/findAllRefsForRest.ts | 2 +- .../fourslash/findAllRefsInClassExpression.ts | 2 +- .../findAllRefsIndexedAccessTypes.ts | 4 +- .../findAllRefsInheritedProperties1.ts | 2 +- .../findAllRefsInheritedProperties2.ts | 4 +- .../findAllRefsInheritedProperties3.ts | 8 +-- .../findAllRefsInheritedProperties4.ts | 6 +- .../findAllRefsInheritedProperties5.ts | 6 +- .../cases/fourslash/findAllRefsMappedType.ts | 2 +- ...lRefsObjectBindingElementPropertyName01.ts | 2 +- ...lRefsObjectBindingElementPropertyName02.ts | 2 +- ...lRefsObjectBindingElementPropertyName03.ts | 2 +- ...lRefsObjectBindingElementPropertyName04.ts | 2 +- ...lRefsObjectBindingElementPropertyName06.ts | 2 +- ...lRefsObjectBindingElementPropertyName10.ts | 2 +- ...sPropertyContextuallyTypedByTypeParam01.ts | 2 +- .../fourslash/findAllRefsReExportLocal.ts | 2 +- ...efsRedeclaredPropertyInDerivedInterface.ts | 4 +- .../cases/fourslash/findAllRefsRootSymbols.ts | 4 +- tests/cases/fourslash/findAllRefsTypedef.ts | 2 +- .../fourslash/findAllRefsUnionProperty.ts | 4 +- .../findAllRefsWithLeadingUnderscoreNames5.ts | 2 +- .../findAllRefsWithLeadingUnderscoreNames6.ts | 2 +- ...AllRefsWithShorthandPropertyAssignment2.ts | 2 +- .../findReferencesAcrossMultipleProjects.ts | 2 +- .../fourslash/findReferencesAfterEdit.ts | 2 +- .../fourslash/findReferencesJSXTagName3.ts | 2 +- ...currencesIsDefinitionOfComputedProperty.ts | 2 +- .../fourslash/referencesForClassMembers.ts | 4 +- ...esForClassMembersExtendingAbstractClass.ts | 6 +- ...cesForClassMembersExtendingGenericClass.ts | 4 +- ...ontextuallyTypedObjectLiteralProperties.ts | 2 +- ...ncesForContextuallyTypedUnionProperties.ts | 4 +- ...cesForContextuallyTypedUnionProperties2.ts | 2 +- .../referencesForFunctionOverloads.ts | 2 +- .../fourslash/referencesForIndexProperty.ts | 2 +- .../fourslash/referencesForIndexProperty3.ts | 2 +- .../referencesForInheritedProperties.ts | 4 +- .../referencesForInheritedProperties2.ts | 4 +- .../referencesForInheritedProperties3.ts | 4 +- .../referencesForInheritedProperties4.ts | 2 +- .../referencesForInheritedProperties5.ts | 8 +-- .../referencesForInheritedProperties7.ts | 8 +-- .../referencesForInheritedProperties8.ts | 6 +- .../referencesForInheritedProperties9.ts | 4 +- ...eferencesForNumericLiteralPropertyNames.ts | 2 +- .../cases/fourslash/referencesForOverrides.ts | 20 +++--- .../referencesForPropertiesOfGenericType.ts | 2 +- ...rencesForStaticsAndMembersWithSameNames.ts | 4 +- ...referencesForStringLiteralPropertyNames.ts | 2 +- .../fourslash/referencesForUnionProperties.ts | 6 +- .../renameImportAndExportInDiffFiles.ts | 2 +- .../cases/fourslash/tsxFindAllReferences10.ts | 2 +- .../cases/fourslash/tsxFindAllReferences3.ts | 2 +- .../cases/fourslash/tsxFindAllReferences7.ts | 2 +- .../cases/fourslash/tsxFindAllReferences9.ts | 2 +- 67 files changed, 183 insertions(+), 118 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f6927925428..279fef73d5e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -739,6 +739,7 @@ namespace ts { } export interface ComputedPropertyName extends Node { + parent: Declaration; kind: SyntaxKind.ComputedPropertyName; expression: Expression; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 47bf4193bd6..7a128a41c69 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2384,29 +2384,33 @@ namespace ts { } // See GH#16030 - export function isAnyDeclarationName(name: Node): boolean { + export function getDeclarationFromName(name: Node): Declaration | undefined { + const parent = name.parent; switch (name.kind) { - case SyntaxKind.Identifier: case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: { - const parent = name.parent; + case SyntaxKind.NumericLiteral: + if (isComputedPropertyName(parent)) return parent.parent; + // falls through + + case SyntaxKind.Identifier: if (isDeclaration(parent)) { - return parent.name === name; + return parent.name === name ? parent : undefined; } - else if (isQualifiedName(name.parent)) { - const tag = name.parent.parent; - return isJSDocParameterTag(tag) && tag.name === name.parent; + else if (isQualifiedName(parent)) { + const tag = parent.parent; + return isJSDocParameterTag(tag) && tag.name === parent ? tag : undefined; } else { - const binExp = name.parent.parent; + const binExp = parent.parent; return isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None && (binExp.left.symbol || binExp.symbol) && - getNameOfDeclaration(binExp) === name; + getNameOfDeclaration(binExp) === name + ? binExp + : undefined; } - } default: - return false; + return undefined; } } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 81da5a0d82f..bcc68162746 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -154,7 +154,7 @@ namespace ts.FindAllReferences { textSpan: getTextSpan(node, sourceFile), isWriteAccess: isWriteAccessForReference(node), isDefinition: node.kind === SyntaxKind.DefaultKeyword - || isAnyDeclarationName(node) + || !!getDeclarationFromName(node) || isLiteralComputedPropertyDeclarationName(node), isInString, }; @@ -223,7 +223,65 @@ namespace ts.FindAllReferences { /** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */ function isWriteAccessForReference(node: Node): boolean { - return node.kind === SyntaxKind.DefaultKeyword || isAnyDeclarationName(node) || isWriteAccess(node); + const decl = getDeclarationFromName(node); + return !!decl && declarationIsWriteAccess(decl) || node.kind === SyntaxKind.DefaultKeyword || isWriteAccess(node); + } + + /** + * True if 'decl' provides a value, as in `function f() {}`; + * false if 'decl' is just a location for a future write, as in 'let x;' + */ + function declarationIsWriteAccess(decl: Declaration): boolean { + // Consider anything in an ambient declaration to be a write access since it may be coming from JS. + if (!!(decl.flags & NodeFlags.Ambient)) return true; + + switch (decl.kind) { + case SyntaxKind.BinaryExpression: + case SyntaxKind.BindingElement: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + case SyntaxKind.DefaultKeyword: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.EnumMember: + case SyntaxKind.ExportSpecifier: + case SyntaxKind.ImportClause: // default import + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.ImportSpecifier: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.JSDocCallbackTag: + case SyntaxKind.JSDocTypedefTag: + case SyntaxKind.JsxAttribute: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.NamespaceExportDeclaration: + case SyntaxKind.NamespaceImport: + case SyntaxKind.Parameter: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.TypeAliasDeclaration: + case SyntaxKind.TypeParameter: + return true; + + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.Constructor: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return !!(decl as FunctionDeclaration | FunctionExpression | ConstructorDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration).body; + + case SyntaxKind.VariableDeclaration: + case SyntaxKind.PropertyDeclaration: + return !!(decl as VariableDeclaration | PropertyDeclaration).initializer || isCatchClause(decl.parent); + + case SyntaxKind.MethodSignature: + case SyntaxKind.PropertySignature: + case SyntaxKind.JSDocPropertyTag: + case SyntaxKind.JSDocParameterTag: + return false; + + default: + return Debug.failBadSyntaxKind(decl); + } } } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3e54190429b..2fa23f14a7b 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -536,6 +536,7 @@ declare namespace ts { name?: Identifier | StringLiteral | NumericLiteral; } interface ComputedPropertyName extends Node { + parent: Declaration; kind: SyntaxKind.ComputedPropertyName; expression: Expression; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8d8690781d0..8290cb96236 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -536,6 +536,7 @@ declare namespace ts { name?: Identifier | StringLiteral | NumericLiteral; } interface ComputedPropertyName extends Node { + parent: Declaration; kind: SyntaxKind.ComputedPropertyName; expression: Expression; } diff --git a/tests/cases/fourslash/findAllReferencesJsDocTypeLiteral.ts b/tests/cases/fourslash/findAllReferencesJsDocTypeLiteral.ts index 48befe13442..25059d028ed 100644 --- a/tests/cases/fourslash/findAllReferencesJsDocTypeLiteral.ts +++ b/tests/cases/fourslash/findAllReferencesJsDocTypeLiteral.ts @@ -8,7 +8,7 @@ //// * @param {string} o.x - a thing, its ok //// * @param {number} o.y - another thing //// * @param {Object} o.nested - very nested -//// * @param {boolean} o.nested.[|{| "isWriteAccess": true, "isDefinition": true |}great|] - much greatness +//// * @param {boolean} o.nested.[|{| "isDefinition": true |}great|] - much greatness //// * @param {number} o.nested.times - twice? probably!?? //// */ //// function f(o) { return o.nested.[|great|]; } diff --git a/tests/cases/fourslash/findAllRefsDestructureGeneric.ts b/tests/cases/fourslash/findAllRefsDestructureGeneric.ts index f3d4635cebd..3d7a84cb35a 100644 --- a/tests/cases/fourslash/findAllRefsDestructureGeneric.ts +++ b/tests/cases/fourslash/findAllRefsDestructureGeneric.ts @@ -1,7 +1,7 @@ /// ////interface I { -//// [|{| "isWriteAccess": true, "isDefinition": true |}x|]: boolean; +//// [|{| "isDefinition": true |}x|]: boolean; ////} ////declare const i: I; ////const { [|{| "isWriteAccess": true, "isDefinition": true |}x|] } = i; diff --git a/tests/cases/fourslash/findAllRefsForComputedProperties.ts b/tests/cases/fourslash/findAllRefsForComputedProperties.ts index 7dac0432e94..3c442b8b63a 100644 --- a/tests/cases/fourslash/findAllRefsForComputedProperties.ts +++ b/tests/cases/fourslash/findAllRefsForComputedProperties.ts @@ -9,7 +9,7 @@ ////} //// ////var x: I = { -//// ["[|{| "isDefinition": true |}prop1|]"]: function () { }, +//// ["[|{| "isWriteAccess": true, "isDefinition": true |}prop1|]"]: function () { }, ////} const ranges = test.ranges(); diff --git a/tests/cases/fourslash/findAllRefsForComputedProperties2.ts b/tests/cases/fourslash/findAllRefsForComputedProperties2.ts index 81abd714d32..21f9d2c92ba 100644 --- a/tests/cases/fourslash/findAllRefsForComputedProperties2.ts +++ b/tests/cases/fourslash/findAllRefsForComputedProperties2.ts @@ -9,7 +9,7 @@ ////} //// ////var x: I = { -//// ["[|{| "isDefinition": true |}42|]"]: function () { } +//// ["[|{| "isWriteAccess": true, "isDefinition": true |}42|]"]: function () { } ////} const ranges = test.ranges(); diff --git a/tests/cases/fourslash/findAllRefsForMappedType.ts b/tests/cases/fourslash/findAllRefsForMappedType.ts index 904dc8c42c7..8965fa046ea 100644 --- a/tests/cases/fourslash/findAllRefsForMappedType.ts +++ b/tests/cases/fourslash/findAllRefsForMappedType.ts @@ -1,6 +1,6 @@ /// -////interface T { [|{| "isWriteAccess": true, "isDefinition": true |}a|]: number }; +////interface T { [|{| "isDefinition": true |}a|]: number }; ////type U = { [K in keyof T]: string }; ////type V = { [K in keyof U]: boolean }; ////const u: U = { [|{| "isWriteAccess": true, "isDefinition": true |}a|]: "" } diff --git a/tests/cases/fourslash/findAllRefsForObjectSpread.ts b/tests/cases/fourslash/findAllRefsForObjectSpread.ts index c6f111672c8..12c338ca529 100644 --- a/tests/cases/fourslash/findAllRefsForObjectSpread.ts +++ b/tests/cases/fourslash/findAllRefsForObjectSpread.ts @@ -1,7 +1,7 @@ /// -////interface A1 { readonly [|{| "isWriteAccess": true, "isDefinition": true |}a|]: string }; -////interface A2 { [|{| "isWriteAccess": true, "isDefinition": true |}a|]?: number }; +////interface A1 { readonly [|{| "isDefinition": true |}a|]: string }; +////interface A2 { [|{| "isDefinition": true |}a|]?: number }; ////let a1: A1; ////let a2: A2; ////let a12 = { ...a1, ...a2 }; diff --git a/tests/cases/fourslash/findAllRefsForRest.ts b/tests/cases/fourslash/findAllRefsForRest.ts index 026451d68b8..3dac71374f0 100644 --- a/tests/cases/fourslash/findAllRefsForRest.ts +++ b/tests/cases/fourslash/findAllRefsForRest.ts @@ -1,7 +1,7 @@ /// ////interface Gen { //// x: number -//// [|{| "isWriteAccess": true, "isDefinition": true |}parent|]: Gen; +//// [|{| "isDefinition": true |}parent|]: Gen; //// millenial: string; ////} ////let t: Gen; diff --git a/tests/cases/fourslash/findAllRefsInClassExpression.ts b/tests/cases/fourslash/findAllRefsInClassExpression.ts index 19ec2df35d2..8adc64e8e6d 100644 --- a/tests/cases/fourslash/findAllRefsInClassExpression.ts +++ b/tests/cases/fourslash/findAllRefsInClassExpression.ts @@ -1,6 +1,6 @@ /// -////interface I { [|{| "isWriteAccess": true, "isDefinition": true |}boom|](): void; } +////interface I { [|{| "isDefinition": true |}boom|](): void; } ////new class C implements I { //// [|{| "isWriteAccess": true, "isDefinition": true |}boom|](){} ////} diff --git a/tests/cases/fourslash/findAllRefsIndexedAccessTypes.ts b/tests/cases/fourslash/findAllRefsIndexedAccessTypes.ts index fdfb00439f6..49dac247294 100644 --- a/tests/cases/fourslash/findAllRefsIndexedAccessTypes.ts +++ b/tests/cases/fourslash/findAllRefsIndexedAccessTypes.ts @@ -1,8 +1,8 @@ /// ////interface I { -//// [|{| "isDefinition": true, "isWriteAccess": true |}0|]: number; -//// [|{| "isDefinition": true, "isWriteAccess": true |}s|]: string; +//// [|{| "isDefinition": true |}0|]: number; +//// [|{| "isDefinition": true |}s|]: string; ////} ////interface J { //// a: I[[|0|]], diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts index 3b14e686cc6..9e58a37c589 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties1.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties1.ts @@ -2,7 +2,7 @@ //// class class1 extends class1 { //// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|]() { } -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; +//// [|{| "isDefinition": true |}propName|]: string; //// } //// //// var v: class1; diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties2.ts b/tests/cases/fourslash/findAllRefsInheritedProperties2.ts index 23badd64d48..2e776e48acd 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties2.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties2.ts @@ -1,8 +1,8 @@ /// //// interface interface1 extends interface1 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; // r0 -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; // r1 +//// [|{| "isDefinition": true |}doStuff|](): void; // r0 +//// [|{| "isDefinition": true |}propName|]: string; // r1 //// } //// //// var v: interface1; diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts index 2c929a559fb..ea5b1ce7bf4 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties3.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties3.ts @@ -2,15 +2,15 @@ //// class class1 extends class1 { //// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|]() { } // r0 -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; // r1 +//// [|{| "isDefinition": true |}propName|]: string; // r1 //// } //// interface interface1 extends interface1 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; // r2 -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; // r3 +//// [|{| "isDefinition": true |}doStuff|](): void; // r2 +//// [|{| "isDefinition": true |}propName|]: string; // r3 //// } //// class class2 extends class1 implements interface1 { //// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|]() { } // r4 -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; // r5 +//// [|{| "isDefinition": true |}propName|]: string; // r5 //// } //// //// var v: class2; diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties4.ts b/tests/cases/fourslash/findAllRefsInheritedProperties4.ts index e2d8887bbe8..2528fef1939 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties4.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties4.ts @@ -1,12 +1,12 @@ /// //// interface C extends D { -//// [|{| "isWriteAccess": true, "isDefinition": true |}prop0|]: string; // r0 -//// [|{| "isWriteAccess": true, "isDefinition": true |}prop1|]: number; // r1 +//// [|{| "isDefinition": true |}prop0|]: string; // r0 +//// [|{| "isDefinition": true |}prop1|]: number; // r1 //// } //// //// interface D extends C { -//// [|{| "isWriteAccess": true, "isDefinition": true |}prop0|]: string; // r2 +//// [|{| "isDefinition": true |}prop0|]: string; // r2 //// } //// //// var d: D; diff --git a/tests/cases/fourslash/findAllRefsInheritedProperties5.ts b/tests/cases/fourslash/findAllRefsInheritedProperties5.ts index c534a9d6aab..343328405d5 100644 --- a/tests/cases/fourslash/findAllRefsInheritedProperties5.ts +++ b/tests/cases/fourslash/findAllRefsInheritedProperties5.ts @@ -1,12 +1,12 @@ /// //// class C extends D { -//// [|{| "isWriteAccess": true, "isDefinition": true |}prop0|]: string; // r0 -//// [|{| "isWriteAccess": true, "isDefinition": true |}prop1|]: number; // r1 +//// [|{| "isDefinition": true |}prop0|]: string; // r0 +//// [|{| "isDefinition": true |}prop1|]: number; // r1 //// } //// //// class D extends C { -//// [|{| "isWriteAccess": true, "isDefinition": true |}prop0|]: string; // r2 +//// [|{| "isDefinition": true |}prop0|]: string; // r2 //// } //// //// var d: D; diff --git a/tests/cases/fourslash/findAllRefsMappedType.ts b/tests/cases/fourslash/findAllRefsMappedType.ts index 97658da08c1..8c6c59150af 100644 --- a/tests/cases/fourslash/findAllRefsMappedType.ts +++ b/tests/cases/fourslash/findAllRefsMappedType.ts @@ -1,6 +1,6 @@ /// -////interface T { [|{| "isWriteAccess": true, "isDefinition": true |}a|]: number; } +////interface T { [|{| "isDefinition": true |}a|]: number; } ////type U = { readonly [K in keyof T]?: string }; ////declare const t: T; ////t.[|a|]; diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts index d11bcee506f..5a72ca1c1ec 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName01.ts @@ -1,7 +1,7 @@ /// ////interface I { -//// [|{| "isWriteAccess": true, "isDefinition": true |}property1|]: number; +//// [|{| "isDefinition": true |}property1|]: number; //// property2: string; ////} //// diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts index 6ad98df9cd8..76b6d046b8e 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName02.ts @@ -1,7 +1,7 @@ /// ////interface I { -//// [|{| "isWriteAccess": true, "isDefinition": true |}property1|]: number; +//// [|{| "isDefinition": true |}property1|]: number; //// property2: string; ////} //// diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts index 520dbc8e1e4..f82eca087bb 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName03.ts @@ -1,7 +1,7 @@ /// ////interface I { -//// [|{| "isWriteAccess": true, "isDefinition": true |}property1|]: number; +//// [|{| "isDefinition": true |}property1|]: number; //// property2: string; ////} //// diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts index f25fff9da23..fe0d659f0ec 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName04.ts @@ -1,7 +1,7 @@ /// ////interface I { -//// [|{| "isWriteAccess": true, "isDefinition": true |}property1|]: number; +//// [|{| "isDefinition": true |}property1|]: number; //// property2: string; ////} //// diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts index a8dd5bda227..62d1637f3b3 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName06.ts @@ -1,7 +1,7 @@ /// ////interface I { -//// [|{| "isWriteAccess": true, "isDefinition": true |}property1|]: number; +//// [|{| "isDefinition": true |}property1|]: number; //// property2: string; ////} //// diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts index 500ca7fe3cf..7d31cfd4345 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts @@ -1,7 +1,7 @@ /// ////interface Recursive { -//// [|{| "isWriteAccess": true, "isDefinition": true |}next|]?: Recursive; +//// [|{| "isDefinition": true |}next|]?: Recursive; //// value: any; ////} //// diff --git a/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts b/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts index e4e9b830510..d4aefb58ac3 100644 --- a/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts +++ b/tests/cases/fourslash/findAllRefsPropertyContextuallyTypedByTypeParam01.ts @@ -1,7 +1,7 @@ /// ////interface IFoo { -//// [|{| "isWriteAccess": true, "isDefinition": true |}a|]: string; +//// [|{| "isDefinition": true |}a|]: string; ////} ////class C { //// method() { diff --git a/tests/cases/fourslash/findAllRefsReExportLocal.ts b/tests/cases/fourslash/findAllRefsReExportLocal.ts index ed1d0b105b6..603971a2294 100644 --- a/tests/cases/fourslash/findAllRefsReExportLocal.ts +++ b/tests/cases/fourslash/findAllRefsReExportLocal.ts @@ -3,7 +3,7 @@ // @noLib: true // @Filename: /a.ts -////var [|{| "isWriteAccess": true, "isDefinition": true |}x|]; +////var [|{| "isDefinition": true |}x|]; ////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] }; ////export { [|x|] as [|{| "isWriteAccess": true, "isDefinition": true |}y|] }; diff --git a/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts b/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts index 1964ebf2c2c..dff05b219be 100644 --- a/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts +++ b/tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts @@ -3,10 +3,10 @@ // @noLib: true ////interface A { -//// readonly [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number | string; +//// readonly [|{| "isDefinition": true |}x|]: number | string; ////} ////interface B extends A { -//// readonly [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number; +//// readonly [|{| "isDefinition": true |}x|]: number; ////} ////const a: A = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 }; ////const b: B = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 }; diff --git a/tests/cases/fourslash/findAllRefsRootSymbols.ts b/tests/cases/fourslash/findAllRefsRootSymbols.ts index 77eea3b46b0..0e209765b37 100644 --- a/tests/cases/fourslash/findAllRefsRootSymbols.ts +++ b/tests/cases/fourslash/findAllRefsRootSymbols.ts @@ -1,7 +1,7 @@ /// -////interface I { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: {}; } -////interface J { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: {}; } +////interface I { [|{| "isDefinition": true |}x|]: {}; } +////interface J { [|{| "isDefinition": true |}x|]: {}; } ////declare const o: (I | J) & { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: string }; ////o.[|x|]; diff --git a/tests/cases/fourslash/findAllRefsTypedef.ts b/tests/cases/fourslash/findAllRefsTypedef.ts index ecd690c10e5..2e7d8601656 100644 --- a/tests/cases/fourslash/findAllRefsTypedef.ts +++ b/tests/cases/fourslash/findAllRefsTypedef.ts @@ -5,7 +5,7 @@ // @Filename: /a.js /////** //// * @typedef I {Object} -//// * @prop [|{| "isWriteAccess": true, "isDefinition": true |}p|] {number} +//// * @prop [|{| "isDefinition": true |}p|] {number} //// */ //// /////** @type {I} */ diff --git a/tests/cases/fourslash/findAllRefsUnionProperty.ts b/tests/cases/fourslash/findAllRefsUnionProperty.ts index 97b8972c457..3b7813f638b 100644 --- a/tests/cases/fourslash/findAllRefsUnionProperty.ts +++ b/tests/cases/fourslash/findAllRefsUnionProperty.ts @@ -1,8 +1,8 @@ /// ////type T = -//// | { [|{| "isWriteAccess": true, "isDefinition": true |}type|]: "a", [|{| "isWriteAccess": true, "isDefinition": true |}prop|]: number } -//// | { [|{| "isWriteAccess": true, "isDefinition": true |}type|]: "b", [|{| "isWriteAccess": true, "isDefinition": true |}prop|]: string }; +//// | { [|{| "isDefinition": true |}type|]: "a", [|{| "isDefinition": true |}prop|]: number } +//// | { [|{| "isDefinition": true |}type|]: "b", [|{| "isDefinition": true |}prop|]: string }; ////const tt: T = { //// [|{| "isWriteAccess": true, "isDefinition": true |}type|]: "a", //// [|{| "isWriteAccess": true, "isDefinition": true |}prop|]: 0, diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames5.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames5.ts index d54b48bf662..cf171662596 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames5.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames5.ts @@ -3,7 +3,7 @@ ////class Foo { //// public _bar; //// public __bar; -//// public [|{| "isWriteAccess": true, "isDefinition": true |}___bar|]; +//// public [|{| "isDefinition": true |}___bar|]; //// public ____bar; ////} //// diff --git a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames6.ts b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames6.ts index 39bc1d73ca3..77197480eb1 100644 --- a/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames6.ts +++ b/tests/cases/fourslash/findAllRefsWithLeadingUnderscoreNames6.ts @@ -2,7 +2,7 @@ ////class Foo { //// public _bar; -//// public [|{| "isWriteAccess": true, "isDefinition": true |}__bar|]; +//// public [|{| "isDefinition": true |}__bar|]; //// public ___bar; //// public ____bar; ////} diff --git a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts index 6dbbf9e613b..f19640698cd 100644 --- a/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts +++ b/tests/cases/fourslash/findAllRefsWithShorthandPropertyAssignment2.ts @@ -2,7 +2,7 @@ //// var [|{| "isWriteAccess": true, "isDefinition": true |}dx|] = "Foo"; //// -//// module M { export var [|{| "isWriteAccess": true, "isDefinition": true |}dx|]; } +//// module M { export var [|{| "isDefinition": true |}dx|]; } //// module M { //// var z = 100; //// export var y = { [|{| "isWriteAccess": true, "isDefinition": true |}dx|], z }; diff --git a/tests/cases/fourslash/findReferencesAcrossMultipleProjects.ts b/tests/cases/fourslash/findReferencesAcrossMultipleProjects.ts index f9feb5ddb62..2141399705f 100644 --- a/tests/cases/fourslash/findReferencesAcrossMultipleProjects.ts +++ b/tests/cases/fourslash/findReferencesAcrossMultipleProjects.ts @@ -1,7 +1,7 @@ /// //@Filename: a.ts -////var [|{| "isWriteAccess": true, "isDefinition": true |}x|]: number; +////var [|{| "isDefinition": true |}x|]: number; //@Filename: b.ts /////// diff --git a/tests/cases/fourslash/findReferencesAfterEdit.ts b/tests/cases/fourslash/findReferencesAfterEdit.ts index 599be2255a3..3787617692a 100644 --- a/tests/cases/fourslash/findReferencesAfterEdit.ts +++ b/tests/cases/fourslash/findReferencesAfterEdit.ts @@ -2,7 +2,7 @@ // @Filename: a.ts ////interface A { -//// [|{| "isWriteAccess": true, "isDefinition": true |}foo|]: string; +//// [|{| "isDefinition": true |}foo|]: string; ////} // @Filename: b.ts diff --git a/tests/cases/fourslash/findReferencesJSXTagName3.ts b/tests/cases/fourslash/findReferencesJSXTagName3.ts index 0d5d74b6e2e..58715ade2fa 100644 --- a/tests/cases/fourslash/findReferencesJSXTagName3.ts +++ b/tests/cases/fourslash/findReferencesJSXTagName3.ts @@ -6,7 +6,7 @@ ////namespace JSX { //// export interface Element { } //// export interface IntrinsicElements { -//// [|{| "isWriteAccess": true, "isDefinition": true |}div|]: any; +//// [|{| "isDefinition": true |}div|]: any; //// } ////} //// diff --git a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts index e4c3c93d0e1..88ab38e5428 100644 --- a/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts +++ b/tests/cases/fourslash/getOccurrencesIsDefinitionOfComputedProperty.ts @@ -1,5 +1,5 @@ /// -////let o = { ["[|{| "isDefinition": true |}foo|]"]: 12 }; +////let o = { ["[|{| "isWriteAccess": true, "isDefinition": true |}foo|]"]: 12 }; ////let y = o.[|foo|]; ////let z = o['[|foo|]']; diff --git a/tests/cases/fourslash/referencesForClassMembers.ts b/tests/cases/fourslash/referencesForClassMembers.ts index c2eb8706f59..e60c03524a1 100644 --- a/tests/cases/fourslash/referencesForClassMembers.ts +++ b/tests/cases/fourslash/referencesForClassMembers.ts @@ -1,11 +1,11 @@ /// ////class Base { -//// [|{| "isWriteAccess": true, "isDefinition": true |}a|]: number; +//// [|{| "isDefinition": true |}a|]: number; //// [|{| "isWriteAccess": true, "isDefinition": true |}method|](): void { } ////} ////class MyClass extends Base { -//// [|{| "isWriteAccess": true, "isDefinition": true |}a|]; +//// [|{| "isDefinition": true |}a|]; //// [|{| "isWriteAccess": true, "isDefinition": true |}method|]() { } ////} //// diff --git a/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts b/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts index 5aaee38d205..12df996629d 100644 --- a/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts +++ b/tests/cases/fourslash/referencesForClassMembersExtendingAbstractClass.ts @@ -1,11 +1,11 @@ /// ////abstract class Base { -//// abstract [|{| "isWriteAccess": true, "isDefinition": true |}a|]: number; -//// abstract [|{| "isWriteAccess": true, "isDefinition": true |}method|](): void; +//// abstract [|{| "isDefinition": true |}a|]: number; +//// abstract [|{| "isDefinition": true |}method|](): void; ////} ////class MyClass extends Base { -//// [|{| "isWriteAccess": true, "isDefinition": true |}a|]; +//// [|{| "isDefinition": true |}a|]; //// [|{| "isWriteAccess": true, "isDefinition": true |}method|]() { } ////} //// diff --git a/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts b/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts index 6082033b078..103b66ff74b 100644 --- a/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts +++ b/tests/cases/fourslash/referencesForClassMembersExtendingGenericClass.ts @@ -1,11 +1,11 @@ /// ////class Base { -//// [|{| "isWriteAccess": true, "isDefinition": true |}a|]: this; +//// [|{| "isDefinition": true |}a|]: this; //// [|{| "isWriteAccess": true, "isDefinition": true |}method|](a?:T, b?:U): this { } ////} ////class MyClass extends Base { -//// [|{| "isWriteAccess": true, "isDefinition": true |}a|]; +//// [|{| "isDefinition": true |}a|]; //// [|{| "isWriteAccess": true, "isDefinition": true |}method|]() { } ////} //// diff --git a/tests/cases/fourslash/referencesForContextuallyTypedObjectLiteralProperties.ts b/tests/cases/fourslash/referencesForContextuallyTypedObjectLiteralProperties.ts index f4e0daaab00..67f09a9dcd1 100644 --- a/tests/cases/fourslash/referencesForContextuallyTypedObjectLiteralProperties.ts +++ b/tests/cases/fourslash/referencesForContextuallyTypedObjectLiteralProperties.ts @@ -1,6 +1,6 @@ /// -////interface IFoo { [|{| "isWriteAccess": true, "isDefinition": true |}xy|]: number; } +////interface IFoo { [|{| "isDefinition": true |}xy|]: number; } //// ////// Assignment ////var a1: IFoo = { [|{| "isWriteAccess": true, "isDefinition": true |}xy|]: 0 }; diff --git a/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties.ts b/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties.ts index 9ddd31f2fbb..b0bb5d62b4d 100644 --- a/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties.ts +++ b/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties.ts @@ -2,12 +2,12 @@ ////interface A { //// a: number; -//// [|{| "isWriteAccess": true, "isDefinition": true |}common|]: string; +//// [|{| "isDefinition": true |}common|]: string; ////} //// ////interface B { //// b: number; -//// [|{| "isWriteAccess": true, "isDefinition": true |}common|]: number; +//// [|{| "isDefinition": true |}common|]: number; ////} //// ////// Assignment diff --git a/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties2.ts b/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties2.ts index 3ea7cd9b275..a9741d3e39d 100644 --- a/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties2.ts +++ b/tests/cases/fourslash/referencesForContextuallyTypedUnionProperties2.ts @@ -6,7 +6,7 @@ ////} //// ////interface B { -//// [|{| "isWriteAccess": true, "isDefinition": true |}b|]: number; +//// [|{| "isDefinition": true |}b|]: number; //// common: number; ////} //// diff --git a/tests/cases/fourslash/referencesForFunctionOverloads.ts b/tests/cases/fourslash/referencesForFunctionOverloads.ts index 7afa5a20133..2a1ea032e20 100644 --- a/tests/cases/fourslash/referencesForFunctionOverloads.ts +++ b/tests/cases/fourslash/referencesForFunctionOverloads.ts @@ -2,7 +2,7 @@ // Function overloads should be highlighted together. -////function [|{| "isWriteAccess": true, "isDefinition": true |}foo|](x: string); +////function [|{| "isDefinition": true |}foo|](x: string); ////function [|{| "isWriteAccess": true, "isDefinition": true |}foo|](x: string, y: number) { //// [|foo|]('', 43); ////} diff --git a/tests/cases/fourslash/referencesForIndexProperty.ts b/tests/cases/fourslash/referencesForIndexProperty.ts index dba2549e414..4bc0b3620ea 100644 --- a/tests/cases/fourslash/referencesForIndexProperty.ts +++ b/tests/cases/fourslash/referencesForIndexProperty.ts @@ -3,7 +3,7 @@ // References a class property using string index access ////class Foo { -//// [|{| "isWriteAccess": true, "isDefinition": true |}property|]: number; +//// [|{| "isDefinition": true |}property|]: number; //// [|{| "isWriteAccess": true, "isDefinition": true |}method|](): void { } ////} //// diff --git a/tests/cases/fourslash/referencesForIndexProperty3.ts b/tests/cases/fourslash/referencesForIndexProperty3.ts index a2e008c937e..69417700ed0 100644 --- a/tests/cases/fourslash/referencesForIndexProperty3.ts +++ b/tests/cases/fourslash/referencesForIndexProperty3.ts @@ -3,7 +3,7 @@ // References to a property of the apparent type using string indexer ////interface Object { -//// [|{| "isWriteAccess": true, "isDefinition": true |}toMyString|](); +//// [|{| "isDefinition": true |}toMyString|](); ////} //// ////var y: Object; diff --git a/tests/cases/fourslash/referencesForInheritedProperties.ts b/tests/cases/fourslash/referencesForInheritedProperties.ts index 808387d18f7..88d7ea7537d 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties.ts @@ -1,11 +1,11 @@ /// ////interface interface1 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; +//// [|{| "isDefinition": true |}doStuff|](): void; ////} //// ////interface interface2 extends interface1{ -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; +//// [|{| "isDefinition": true |}doStuff|](): void; ////} //// ////class class1 implements interface2 { diff --git a/tests/cases/fourslash/referencesForInheritedProperties2.ts b/tests/cases/fourslash/referencesForInheritedProperties2.ts index f41fbb7f8db..712c7f2ecf2 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties2.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties2.ts @@ -3,11 +3,11 @@ // extends statement in a diffrent declaration ////interface interface1 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; +//// [|{| "isDefinition": true |}doStuff|](): void; ////} //// ////interface interface2 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; +//// [|{| "isDefinition": true |}doStuff|](): void; ////} //// ////interface interface2 extends interface1 { diff --git a/tests/cases/fourslash/referencesForInheritedProperties3.ts b/tests/cases/fourslash/referencesForInheritedProperties3.ts index c6c870ca350..0eabc6cda9e 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties3.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties3.ts @@ -1,8 +1,8 @@ /// //// interface interface1 extends interface1 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; +//// [|{| "isDefinition": true |}doStuff|](): void; +//// [|{| "isDefinition": true |}propName|]: string; //// } //// //// var v: interface1; diff --git a/tests/cases/fourslash/referencesForInheritedProperties4.ts b/tests/cases/fourslash/referencesForInheritedProperties4.ts index adf8240ea31..f6a7d48f9d1 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties4.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties4.ts @@ -2,7 +2,7 @@ //// class class1 extends class1 { //// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|]() { } -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; +//// [|{| "isDefinition": true |}propName|]: string; //// } //// //// var c: class1; diff --git a/tests/cases/fourslash/referencesForInheritedProperties5.ts b/tests/cases/fourslash/referencesForInheritedProperties5.ts index 12fe3919a1d..232b654c63f 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties5.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties5.ts @@ -1,12 +1,12 @@ /// //// interface interface1 extends interface1 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; +//// [|{| "isDefinition": true |}doStuff|](): void; +//// [|{| "isDefinition": true |}propName|]: string; //// } //// interface interface2 extends interface1 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; +//// [|{| "isDefinition": true |}doStuff|](): void; +//// [|{| "isDefinition": true |}propName|]: string; //// } //// //// var v: interface1; diff --git a/tests/cases/fourslash/referencesForInheritedProperties7.ts b/tests/cases/fourslash/referencesForInheritedProperties7.ts index 44cf510182a..25402d36b6e 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties7.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties7.ts @@ -2,15 +2,15 @@ //// class class1 extends class1 { //// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|]() { } -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; +//// [|{| "isDefinition": true |}propName|]: string; //// } //// interface interface1 extends interface1 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|](): void; -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; +//// [|{| "isDefinition": true |}doStuff|](): void; +//// [|{| "isDefinition": true |}propName|]: string; //// } //// class class2 extends class1 implements interface1 { //// [|{| "isWriteAccess": true, "isDefinition": true |}doStuff|]() { } -//// [|{| "isWriteAccess": true, "isDefinition": true |}propName|]: string; +//// [|{| "isDefinition": true |}propName|]: string; //// } //// //// var v: class2; diff --git a/tests/cases/fourslash/referencesForInheritedProperties8.ts b/tests/cases/fourslash/referencesForInheritedProperties8.ts index d0d94b49b57..331a90f9181 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties8.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties8.ts @@ -1,11 +1,11 @@ /// //// interface C extends D { -//// [|{| "isWriteAccess": true, "isDefinition": true |}propD|]: number; +//// [|{| "isDefinition": true |}propD|]: number; //// } //// interface D extends C { -//// [|{| "isWriteAccess": true, "isDefinition": true |}propD|]: string; -//// [|{| "isWriteAccess": true, "isDefinition": true |}propC|]: number; +//// [|{| "isDefinition": true |}propD|]: string; +//// [|{| "isDefinition": true |}propC|]: number; //// } //// var d: D; //// d.[|propD|]; diff --git a/tests/cases/fourslash/referencesForInheritedProperties9.ts b/tests/cases/fourslash/referencesForInheritedProperties9.ts index 27bc164a8fc..3648be2f989 100644 --- a/tests/cases/fourslash/referencesForInheritedProperties9.ts +++ b/tests/cases/fourslash/referencesForInheritedProperties9.ts @@ -1,11 +1,11 @@ /// //// class D extends C { -//// [|{| "isWriteAccess": true, "isDefinition": true |}prop1|]: string; +//// [|{| "isDefinition": true |}prop1|]: string; //// } //// //// class C extends D { -//// [|{| "isWriteAccess": true, "isDefinition": true |}prop1|]: string; +//// [|{| "isDefinition": true |}prop1|]: string; //// } //// //// var c: C; diff --git a/tests/cases/fourslash/referencesForNumericLiteralPropertyNames.ts b/tests/cases/fourslash/referencesForNumericLiteralPropertyNames.ts index 79dc04ecaee..1f28714daa1 100644 --- a/tests/cases/fourslash/referencesForNumericLiteralPropertyNames.ts +++ b/tests/cases/fourslash/referencesForNumericLiteralPropertyNames.ts @@ -1,7 +1,7 @@ /// ////class Foo { -//// public [|{| "isWriteAccess": true, "isDefinition": true |}12|]: any; +//// public [|{| "isDefinition": true |}12|]: any; ////} //// ////var x: Foo; diff --git a/tests/cases/fourslash/referencesForOverrides.ts b/tests/cases/fourslash/referencesForOverrides.ts index ab3d60f1b86..d5d9ea0a6b6 100644 --- a/tests/cases/fourslash/referencesForOverrides.ts +++ b/tests/cases/fourslash/referencesForOverrides.ts @@ -14,16 +14,16 @@ //// //// module SimpleInterfaceTest { //// export interface IFoo { -//// [|{| "isWriteAccess": true, "isDefinition": true |}ifoo|](): void; +//// [|{| "isDefinition": true |}ifoo|](): void; //// } //// export interface IBar extends IFoo { -//// [|{| "isWriteAccess": true, "isDefinition": true |}ifoo|](): void; +//// [|{| "isDefinition": true |}ifoo|](): void; //// } //// } //// //// module SimpleClassInterfaceTest { //// export interface IFoo { -//// [|{| "isWriteAccess": true, "isDefinition": true |}icfoo|](): void; +//// [|{| "isDefinition": true |}icfoo|](): void; //// } //// export class Bar implements IFoo { //// public [|{| "isWriteAccess": true, "isDefinition": true |}icfoo|](): void { @@ -33,29 +33,29 @@ //// //// module Test { //// export interface IBase { -//// [|{| "isWriteAccess": true, "isDefinition": true |}field|]: string; -//// [|{| "isWriteAccess": true, "isDefinition": true |}method|](): void; +//// [|{| "isDefinition": true |}field|]: string; +//// [|{| "isDefinition": true |}method|](): void; //// } //// //// export interface IBlah extends IBase { -//// [|{| "isWriteAccess": true, "isDefinition": true |}field|]: string; +//// [|{| "isDefinition": true |}field|]: string; //// } //// //// export interface IBlah2 extends IBlah { -//// [|{| "isWriteAccess": true, "isDefinition": true |}field|]: string; +//// [|{| "isDefinition": true |}field|]: string; //// } //// //// export interface IDerived extends IBlah2 { -//// [|{| "isWriteAccess": true, "isDefinition": true |}method|](): void; +//// [|{| "isDefinition": true |}method|](): void; //// } //// //// export class Bar implements IDerived { -//// public [|{| "isWriteAccess": true, "isDefinition": true |}field|]: string; +//// public [|{| "isDefinition": true |}field|]: string; //// public [|{| "isWriteAccess": true, "isDefinition": true |}method|](): void { } //// } //// //// export class BarBlah extends Bar { -//// public [|{| "isWriteAccess": true, "isDefinition": true |}field|]: string; +//// public [|{| "isDefinition": true |}field|]: string; //// } //// } //// diff --git a/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts b/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts index a84bdc6315a..be00bb7593f 100644 --- a/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts +++ b/tests/cases/fourslash/referencesForPropertiesOfGenericType.ts @@ -1,7 +1,7 @@ /// ////interface IFoo { -//// [|{| "isWriteAccess": true, "isDefinition": true |}doSomething|](v: T): T; +//// [|{| "isDefinition": true |}doSomething|](v: T): T; ////} //// ////var x: IFoo; diff --git a/tests/cases/fourslash/referencesForStaticsAndMembersWithSameNames.ts b/tests/cases/fourslash/referencesForStaticsAndMembersWithSameNames.ts index 9e7f30f4c49..816b866421a 100644 --- a/tests/cases/fourslash/referencesForStaticsAndMembersWithSameNames.ts +++ b/tests/cases/fourslash/referencesForStaticsAndMembersWithSameNames.ts @@ -3,8 +3,8 @@ ////module FindRef4 { //// module MixedStaticsClassTest { //// export class Foo { -//// [|{| "isWriteAccess": true, "isDefinition": true |}bar|]: Foo; -//// static [|{| "isWriteAccess": true, "isDefinition": true |}bar|]: Foo; +//// [|{| "isDefinition": true |}bar|]: Foo; +//// static [|{| "isDefinition": true |}bar|]: Foo; //// //// public [|{| "isWriteAccess": true, "isDefinition": true |}foo|](): void { //// } diff --git a/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts b/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts index 5c98eddadce..88c9a74bc6e 100644 --- a/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts +++ b/tests/cases/fourslash/referencesForStringLiteralPropertyNames.ts @@ -1,7 +1,7 @@ /// ////class Foo { -//// public "[|{| "isWriteAccess": true, "isDefinition": true |}ss|]": any; +//// public "[|{| "isDefinition": true |}ss|]": any; ////} //// ////var x: Foo; diff --git a/tests/cases/fourslash/referencesForUnionProperties.ts b/tests/cases/fourslash/referencesForUnionProperties.ts index b8e24dfae1c..7efff1aabd0 100644 --- a/tests/cases/fourslash/referencesForUnionProperties.ts +++ b/tests/cases/fourslash/referencesForUnionProperties.ts @@ -1,16 +1,16 @@ /// ////interface One { -//// common: { [|{| "isWriteAccess": true, "isDefinition": true |}a|]: number; }; +//// common: { [|{| "isDefinition": true |}a|]: number; }; ////} //// ////interface Base { -//// [|{| "isWriteAccess": true, "isDefinition": true |}a|]: string; +//// [|{| "isDefinition": true |}a|]: string; //// b: string; ////} //// ////interface HasAOrB extends Base { -//// [|{| "isWriteAccess": true, "isDefinition": true |}a|]: string; +//// [|{| "isDefinition": true |}a|]: string; //// b: string; ////} //// diff --git a/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts b/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts index a961ebf2411..96d423529c2 100644 --- a/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts +++ b/tests/cases/fourslash/renameImportAndExportInDiffFiles.ts @@ -1,7 +1,7 @@ /// // @Filename: a.ts -////export var [|{| "isWriteAccess": true, "isDefinition": true |}a|]; +////export var [|{| "isDefinition": true |}a|]; // @Filename: b.ts ////import { [|{| "isWriteAccess": true, "isDefinition": true |}a|] } from './a'; diff --git a/tests/cases/fourslash/tsxFindAllReferences10.ts b/tests/cases/fourslash/tsxFindAllReferences10.ts index 04ac864e4f2..58459c7df1f 100644 --- a/tests/cases/fourslash/tsxFindAllReferences10.ts +++ b/tests/cases/fourslash/tsxFindAllReferences10.ts @@ -15,7 +15,7 @@ //// className?: string; //// } //// interface ButtonProps extends ClickableProps { -//// [|{| "isWriteAccess": true, "isDefinition": true |}onClick|](event?: React.MouseEvent): void; +//// [|{| "isDefinition": true |}onClick|](event?: React.MouseEvent): void; //// } //// interface LinkProps extends ClickableProps { //// goTo: string; diff --git a/tests/cases/fourslash/tsxFindAllReferences3.ts b/tests/cases/fourslash/tsxFindAllReferences3.ts index 2682e01e7d1..e2f9215466a 100644 --- a/tests/cases/fourslash/tsxFindAllReferences3.ts +++ b/tests/cases/fourslash/tsxFindAllReferences3.ts @@ -9,7 +9,7 @@ //// } //// class MyClass { //// props: { -//// [|{| "isWriteAccess": true, "isDefinition": true |}name|]?: string; +//// [|{| "isDefinition": true |}name|]?: string; //// size?: number; //// } //// diff --git a/tests/cases/fourslash/tsxFindAllReferences7.ts b/tests/cases/fourslash/tsxFindAllReferences7.ts index 37ea60c7a38..471cf747258 100644 --- a/tests/cases/fourslash/tsxFindAllReferences7.ts +++ b/tests/cases/fourslash/tsxFindAllReferences7.ts @@ -11,7 +11,7 @@ //// interface ElementAttributesProperty { props; } //// } //// interface OptionPropBag { -//// [|{| "isWriteAccess": true, "isDefinition": true |}propx|]: number +//// [|{| "isDefinition": true |}propx|]: number //// propString: string //// optional?: boolean //// } diff --git a/tests/cases/fourslash/tsxFindAllReferences9.ts b/tests/cases/fourslash/tsxFindAllReferences9.ts index 9fe02500ad9..bb45ce590cf 100644 --- a/tests/cases/fourslash/tsxFindAllReferences9.ts +++ b/tests/cases/fourslash/tsxFindAllReferences9.ts @@ -18,7 +18,7 @@ //// onClick(event?: React.MouseEvent): void; //// } //// interface LinkProps extends ClickableProps { -//// [|{| "isWriteAccess": true, "isDefinition": true |}goTo|]: string; +//// [|{| "isDefinition": true |}goTo|]: string; //// } //// declare function MainButton(buttonProps: ButtonProps): JSX.Element; //// declare function MainButton(linkProps: LinkProps): JSX.Element; From 88d5b04c70cb41c10dad41183eb3235e8fcc4d2f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 6 Sep 2018 13:26:44 -0700 Subject: [PATCH 160/163] Lowercase type reference directives when determining to reuse program structure (just like when we create new program) --- src/compiler/program.ts | 3 +- .../unittests/tsserverProjectSystem.ts | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index c129d75f156..c97f1a61d27 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1178,7 +1178,8 @@ namespace ts { } } if (resolveTypeReferenceDirectiveNamesWorker) { - const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, x => x.fileName); + // We lower-case all type references because npm automatically lowercases all packages. See GH#9824. + const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, ref => ref.fileName.toLocaleLowerCase()); const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath); // ensure that types resolutions are still correct const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo); diff --git a/src/testRunner/unittests/tsserverProjectSystem.ts b/src/testRunner/unittests/tsserverProjectSystem.ts index a1e0c0932b2..7114759b097 100644 --- a/src/testRunner/unittests/tsserverProjectSystem.ts +++ b/src/testRunner/unittests/tsserverProjectSystem.ts @@ -9555,6 +9555,65 @@ export function Test2() { }); }); + describe("tsserverProjectSystem typeReferenceDirectives", () => { + it("when typeReferenceDirective contains UpperCasePackage", () => { + const projectLocation = "/user/username/projects/myproject"; + const libProjectLocation = `${projectLocation}/lib`; + const typeLib: File = { + path: `${libProjectLocation}/@types/UpperCasePackage/index.d.ts`, + content: `declare class BrokenTest { + constructor(name: string, width: number, height: number, onSelect: Function); + Name: string; + SelectedFile: string; +}` + }; + const appLib: File = { + path: `${libProjectLocation}/@app/lib/index.d.ts`, + content: `/// +declare class TestLib { + issue: BrokenTest; + constructor(); + test(): void; +}` + }; + const testProjectLocation = `${projectLocation}/test`; + const testFile: File = { + path: `${testProjectLocation}/test.ts`, + content: `class TestClass1 { + + constructor() { + var l = new TestLib(); + + } + + public test2() { + var x = new BrokenTest('',0,0,null); + + } +}` + }; + const testConfig: File = { + path: `${testProjectLocation}/tsconfig.json`, + content: JSON.stringify({ + compilerOptions: { + module: "amd", + typeRoots: ["../lib/@types", "../lib/@app"] + } + }) + }; + + const files = [typeLib, appLib, testFile, testConfig, libFile]; + const host = createServerHost(files); + const service = createProjectService(host); + service.openClientFile(testFile.path); + checkNumberOfProjects(service, { configuredProjects: 1 }); + const project = service.configuredProjects.get(testConfig.path)!; + checkProjectActualFiles(project, files.map(f => f.path)); + host.writeFile(appLib.path, appLib.content.replace("test()", "test2()")); + host.checkTimeoutQueueLengthAndRun(2); + }); + }); + describe("tsserverProjectSystem project references", () => { const aTs: File = { path: "/a/a.ts", From a0ebbfb8f06a9e5648555d0eaa7c2541ba1e7cc1 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 6 Sep 2018 14:15:12 -0700 Subject: [PATCH 161/163] Fix JSX completions after boolean property (#26943) --- src/services/completions.ts | 5 ++++- .../cases/fourslash/completionsJsxAttribute.ts | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/services/completions.ts b/src/services/completions.ts index 1e74ea3bbf1..3edc1cc4f56 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -986,7 +986,10 @@ namespace ts.Completions { break; case SyntaxKind.Identifier: // For `

` we don't want to treat this as a jsx inializer, instead it's the attribute name. + if (parent !== previousToken.parent && + !(parent as JsxAttribute).initializer && + findChildOfKind(parent, SyntaxKind.EqualsToken, sourceFile)) { isJsxInitializer = previousToken as Identifier; } } diff --git a/tests/cases/fourslash/completionsJsxAttribute.ts b/tests/cases/fourslash/completionsJsxAttribute.ts index 75bf20c7488..c4d1513a6ee 100644 --- a/tests/cases/fourslash/completionsJsxAttribute.ts +++ b/tests/cases/fourslash/completionsJsxAttribute.ts @@ -8,15 +8,22 @@ //// interface IntrinsicElements { //// div: { //// /** Doc */ -//// foo: string +//// foo: boolean; +//// bar: string; //// } //// } ////} //// ////
; -goTo.marker(); -verify.completionEntryDetailIs("foo", "(JSX attribute) foo: string", "Doc", "JSX attribute", []); +const exact: ReadonlyArray = [ + { name: "foo", kind: "JSX attribute", text: "(JSX attribute) foo: boolean", documentation: "Doc" }, + { name: "bar", kind: "JSX attribute", text: "(JSX attribute) bar: string" }, +]; +verify.completions({ marker: "", exact }); edit.insert("f"); -verify.completionEntryDetailIs("foo", "(JSX attribute) foo: string", "Doc", "JSX attribute", []); - +verify.completions({ exact }); +edit.insert("oo "); +verify.completions({ exact: exact[1] }); +edit.insert("b"); +verify.completions({ exact: exact[1] }); From c401d63c5f0fb937ce53f499ba3872b24470b0fc Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 6 Sep 2018 15:24:07 -0700 Subject: [PATCH 162/163] findAllReferences: Fix declarationIsWriteAccess for PropertyAssignment in destructuring (#26949) --- src/services/findAllReferences.ts | 5 ++++- .../findAllRefsObjectBindingElementPropertyName07.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index bcc68162746..81970322c21 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -255,12 +255,15 @@ namespace ts.FindAllReferences { case SyntaxKind.NamespaceExportDeclaration: case SyntaxKind.NamespaceImport: case SyntaxKind.Parameter: - case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.TypeParameter: return true; + case SyntaxKind.PropertyAssignment: + // In `({ x: y } = 0);`, `x` is not a write access. (Won't call this function for `y`.) + return !isArrayLiteralOrObjectLiteralDestructuringPattern((decl as PropertyAssignment).parent); + case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: case SyntaxKind.Constructor: diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts index 69d1f6ac2ff..18fa4e43273 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName07.ts @@ -2,6 +2,6 @@ ////let p, b; //// -////p, [{ [|{| "isWriteAccess": true, "isDefinition": true |}a|]: p, b }] = [{ [|{| "isWriteAccess": true, "isDefinition": true |}a|]: 10, b: true }]; +////p, [{ [|{| "isDefinition": true |}a|]: p, b }] = [{ [|{| "isWriteAccess": true, "isDefinition": true |}a|]: 10, b: true }]; verify.singleReferenceGroup("(property) a: any"); From d31973b905c1021374442221064b828eb5154b82 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 6 Sep 2018 17:06:50 -0700 Subject: [PATCH 163/163] findAllReferences: Consistently use 'this' parameter as definition site (#26950) --- src/services/findAllReferences.ts | 36 ++++++++++--------- .../cases/fourslash/findAllRefsThisKeyword.ts | 6 ++-- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 81970322c21..b857a05dffb 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -5,12 +5,13 @@ namespace ts.FindAllReferences { references: Entry[]; } + export const enum DefinitionKind { Symbol, Label, Keyword, This, String } export type Definition = - | { type: "symbol"; symbol: Symbol } - | { type: "label"; node: Identifier } - | { type: "keyword"; node: Node } - | { type: "this"; node: Node } - | { type: "string"; node: StringLiteral }; + | { readonly type: DefinitionKind.Symbol; readonly symbol: Symbol } + | { readonly type: DefinitionKind.Label; readonly node: Identifier } + | { readonly type: DefinitionKind.Keyword; readonly node: Node } + | { readonly type: DefinitionKind.This; readonly node: Node } + | { readonly type: DefinitionKind.String; readonly node: StringLiteral }; export type Entry = NodeEntry | SpanEntry; export interface NodeEntry { @@ -98,29 +99,29 @@ namespace ts.FindAllReferences { function definitionToReferencedSymbolDefinitionInfo(def: Definition, checker: TypeChecker, originalNode: Node): ReferencedSymbolDefinitionInfo { const info = (() => { switch (def.type) { - case "symbol": { + case DefinitionKind.Symbol: { const { symbol } = def; const { displayParts, kind } = getDefinitionKindAndDisplayParts(symbol, checker, originalNode); const name = displayParts.map(p => p.text).join(""); return { node: symbol.declarations ? getNameOfDeclaration(first(symbol.declarations)) || first(symbol.declarations) : originalNode, name, kind, displayParts }; } - case "label": { + case DefinitionKind.Label: { const { node } = def; return { node, name: node.text, kind: ScriptElementKind.label, displayParts: [displayPart(node.text, SymbolDisplayPartKind.text)] }; } - case "keyword": { + case DefinitionKind.Keyword: { const { node } = def; const name = tokenToString(node.kind)!; return { node, name, kind: ScriptElementKind.keyword, displayParts: [{ text: name, kind: ScriptElementKind.keyword }] }; } - case "this": { + case DefinitionKind.This: { const { node } = def; const symbol = checker.getSymbolAtLocation(node); const displayParts = symbol && SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind( checker, symbol, node.getSourceFile(), getContainerNode(node), node).displayParts || [textPart("this")]; return { node, name: "this", kind: ScriptElementKind.variableElement, displayParts }; } - case "string": { + case DefinitionKind.String: { const { node } = def; return { node, name: node.text, kind: ScriptElementKind.variableElement, displayParts: [displayPart(getTextOfNode(node), SymbolDisplayPartKind.stringLiteral)] }; } @@ -374,7 +375,7 @@ namespace ts.FindAllReferences.Core { } } - return references.length ? [{ definition: { type: "symbol", symbol }, references }] : emptyArray; + return references.length ? [{ definition: { type: DefinitionKind.Symbol, symbol }, references }] : emptyArray; } /** getReferencedSymbols for special node kinds. */ @@ -585,7 +586,7 @@ namespace ts.FindAllReferences.Core { let references = this.symbolIdToReferences[symbolId]; if (!references) { references = this.symbolIdToReferences[symbolId] = []; - this.result.push({ definition: { type: "symbol", symbol: searchSymbol }, references }); + this.result.push({ definition: { type: DefinitionKind.Symbol, symbol: searchSymbol }, references }); } return node => references.push(nodeEntry(node)); } @@ -879,7 +880,7 @@ namespace ts.FindAllReferences.Core { const references = mapDefined(getPossibleSymbolReferenceNodes(sourceFile, labelName, container), node => // Only pick labels that are either the target label, or have a target that is the target label node === targetLabel || (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel) ? nodeEntry(node) : undefined); - return [{ definition: { type: "label", node: targetLabel }, references }]; + return [{ definition: { type: DefinitionKind.Label, node: targetLabel }, references }]; } function isValidReferencePosition(node: Node, searchSymbolName: string): boolean { @@ -911,7 +912,7 @@ namespace ts.FindAllReferences.Core { return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, tokenToString(keywordKind)!, sourceFile), referenceLocation => referenceLocation.kind === keywordKind ? nodeEntry(referenceLocation) : undefined); }); - return references.length ? [{ definition: { type: "keyword", node: references[0].node }, references }] : undefined; + return references.length ? [{ definition: { type: DefinitionKind.Keyword, node: references[0].node }, references }] : undefined; } function getReferencesInSourceFile(sourceFile: SourceFile, search: Search, state: State, addReferencesHere = true): void { @@ -1353,7 +1354,7 @@ namespace ts.FindAllReferences.Core { return container && (ModifierFlags.Static & getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol ? nodeEntry(node) : undefined; }); - return [{ definition: { type: "symbol", symbol: searchSpaceNode.symbol }, references }]; + return [{ definition: { type: DefinitionKind.Symbol, symbol: searchSpaceNode.symbol }, references }]; } function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: ReadonlyArray, cancellationToken: CancellationToken): SymbolAndEntries[] | undefined { @@ -1416,8 +1417,9 @@ namespace ts.FindAllReferences.Core { }); }).map(n => nodeEntry(n)); + const thisParameter = firstDefined(references, r => isParameter(r.node.parent) ? r.node : undefined); return [{ - definition: { type: "this", node: thisOrSuperKeyword }, + definition: { type: DefinitionKind.This, node: thisParameter || thisOrSuperKeyword }, references }]; } @@ -1430,7 +1432,7 @@ namespace ts.FindAllReferences.Core { }); return [{ - definition: { type: "string", node }, + definition: { type: DefinitionKind.String, node }, references }]; } diff --git a/tests/cases/fourslash/findAllRefsThisKeyword.ts b/tests/cases/fourslash/findAllRefsThisKeyword.ts index 975b4b37ac2..34995467a27 100644 --- a/tests/cases/fourslash/findAllRefsThisKeyword.ts +++ b/tests/cases/fourslash/findAllRefsThisKeyword.ts @@ -26,10 +26,8 @@ const [global, f0, f1, g0, g1, x, y, constructor, method, propDef, propUse] = test.ranges(); verify.singleReferenceGroup("this", [global]); -verify.referenceGroups(f0, [{ definition: "(parameter) this: any", ranges: [f0, f1] }]); -verify.referenceGroups(f1, [{ definition: "this: any", ranges: [f0, f1] }]); -verify.referenceGroups(g0, [{ definition: "(parameter) this: any", ranges: [g0, g1] }]); -verify.referenceGroups(g1, [{ definition: "this: any", ranges: [g0, g1] }]); +verify.singleReferenceGroup("(parameter) this: any", [f0, f1]); +verify.singleReferenceGroup("(parameter) this: any", [g0, g1]); verify.singleReferenceGroup("this: typeof C", [x, y]); verify.singleReferenceGroup("this: this", [constructor, method]); verify.singleReferenceGroup("(property) this: number", [propDef, propUse]);