From 124305d00780bd24c40e756a239999eee9644553 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 15 Jul 2016 15:56:22 -0700 Subject: [PATCH 01/11] Emit parens around type-asserted binary operators Fixes #9766 --- src/compiler/emitter.ts | 3 +- tests/baselines/reference/asOpEmitParens.js | 19 ++++++++++++ .../reference/asOpEmitParens.symbols | 16 ++++++++++ .../baselines/reference/asOpEmitParens.types | 30 +++++++++++++++++++ .../expressions/asOperator/asOpEmitParens.ts | 9 ++++++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/asOpEmitParens.js create mode 100644 tests/baselines/reference/asOpEmitParens.symbols create mode 100644 tests/baselines/reference/asOpEmitParens.types create mode 100644 tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 101778e7322..682d9b26fe1 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2553,7 +2553,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge operand = (operand).expression; } - // We have an expression of the form: (SubExpr) + // We have an expression of the form: (SubExpr) or (SubExpr as Type) // Emitting this as (SubExpr) is really not desirable. We would like to emit the subexpr as is. // Omitting the parentheses, however, could cause change in the semantics of the generated // code if the casted expression has a lower precedence than the rest of the expression, e.g.: @@ -2567,6 +2567,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge operand.kind !== SyntaxKind.DeleteExpression && operand.kind !== SyntaxKind.PostfixUnaryExpression && operand.kind !== SyntaxKind.NewExpression && + !(operand.kind === SyntaxKind.BinaryExpression && node.expression.kind === SyntaxKind.AsExpression) && !(operand.kind === SyntaxKind.CallExpression && node.parent.kind === SyntaxKind.NewExpression) && !(operand.kind === SyntaxKind.FunctionExpression && node.parent.kind === SyntaxKind.CallExpression) && !(operand.kind === SyntaxKind.NumericLiteral && node.parent.kind === SyntaxKind.PropertyAccessExpression)) { diff --git a/tests/baselines/reference/asOpEmitParens.js b/tests/baselines/reference/asOpEmitParens.js new file mode 100644 index 00000000000..dee8d263eae --- /dev/null +++ b/tests/baselines/reference/asOpEmitParens.js @@ -0,0 +1,19 @@ +//// [asOpEmitParens.ts] +declare var x; +// Must emit as (x + 1) * 3 +(x + 1 as number) * 3; + +// Should still emit as x.y +(x as any).y; + +// Emit as new (x()) +new (x() as any); + + +//// [asOpEmitParens.js] +// Must emit as (x + 1) * 3 +(x + 1) * 3; +// Should still emit as x.y +x.y; +// Emit as new (x()) +new (x()); diff --git a/tests/baselines/reference/asOpEmitParens.symbols b/tests/baselines/reference/asOpEmitParens.symbols new file mode 100644 index 00000000000..210d9f3ea0d --- /dev/null +++ b/tests/baselines/reference/asOpEmitParens.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts === +declare var x; +>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11)) + +// Must emit as (x + 1) * 3 +(x + 1 as number) * 3; +>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11)) + +// Should still emit as x.y +(x as any).y; +>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11)) + +// Emit as new (x()) +new (x() as any); +>x : Symbol(x, Decl(asOpEmitParens.ts, 0, 11)) + diff --git a/tests/baselines/reference/asOpEmitParens.types b/tests/baselines/reference/asOpEmitParens.types new file mode 100644 index 00000000000..b87d7f4d91f --- /dev/null +++ b/tests/baselines/reference/asOpEmitParens.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts === +declare var x; +>x : any + +// Must emit as (x + 1) * 3 +(x + 1 as number) * 3; +>(x + 1 as number) * 3 : number +>(x + 1 as number) : number +>x + 1 as number : number +>x + 1 : any +>x : any +>1 : number +>3 : number + +// Should still emit as x.y +(x as any).y; +>(x as any).y : any +>(x as any) : any +>x as any : any +>x : any +>y : any + +// Emit as new (x()) +new (x() as any); +>new (x() as any) : any +>(x() as any) : any +>x() as any : any +>x() : any +>x : any + diff --git a/tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts b/tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts new file mode 100644 index 00000000000..7a97a74168a --- /dev/null +++ b/tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts @@ -0,0 +1,9 @@ +declare var x; +// Must emit as (x + 1) * 3 +(x + 1 as number) * 3; + +// Should still emit as x.y +(x as any).y; + +// Emit as new (x()) +new (x() as any); From 40ca4a06b55d9493a7ed45bd92543a0a14a7ac3a Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 15 Jul 2016 16:07:24 -0700 Subject: [PATCH 02/11] Incorrectly included some unrelated files --- .../reference/umdGlobalMerge.errors.txt | 20 ------------------- tests/cases/compiler/umdGlobalMerge.ts | 14 ------------- 2 files changed, 34 deletions(-) delete mode 100644 tests/baselines/reference/umdGlobalMerge.errors.txt delete mode 100644 tests/cases/compiler/umdGlobalMerge.ts diff --git a/tests/baselines/reference/umdGlobalMerge.errors.txt b/tests/baselines/reference/umdGlobalMerge.errors.txt deleted file mode 100644 index eb4a116ef09..00000000000 --- a/tests/baselines/reference/umdGlobalMerge.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -tests/cases/compiler/b.d.ts(2,20): error TS2305: Module '"tests/cases/compiler/a".ns' has no exported member 'IFoo'. - - -==== tests/cases/compiler/a.d.ts (0 errors) ==== - export = ns; - - export as namespace ns; - - declare namespace ns { - export var x: number; - export interface IFoo { } - } - -==== tests/cases/compiler/b.d.ts (1 errors) ==== - declare namespace ns.something { - export var p: ns.IFoo; - ~~~~ -!!! error TS2305: Module '"tests/cases/compiler/a".ns' has no exported member 'IFoo'. - } - \ No newline at end of file diff --git a/tests/cases/compiler/umdGlobalMerge.ts b/tests/cases/compiler/umdGlobalMerge.ts deleted file mode 100644 index 1f42e2fda71..00000000000 --- a/tests/cases/compiler/umdGlobalMerge.ts +++ /dev/null @@ -1,14 +0,0 @@ -// @filename: a.d.ts -export = ns; - -export as namespace ns; - -declare namespace ns { - export var x: number; - export interface IFoo { } -} - -// @filename: b.d.ts -declare namespace ns.something { - export var p: ns.IFoo; -} From 09f518243d32453444cb7de850f6af003a742404 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 27 Jul 2016 15:33:36 -0700 Subject: [PATCH 03/11] Re-add concat overload to support inferring tuples --- src/lib/es5.d.ts | 5 ++++ tests/baselines/reference/concatTuples.js | 8 +++++++ .../baselines/reference/concatTuples.symbols | 10 ++++++++ tests/baselines/reference/concatTuples.types | 23 +++++++++++++++++++ tests/cases/compiler/concatTuples.ts | 2 ++ 5 files changed, 48 insertions(+) create mode 100644 tests/baselines/reference/concatTuples.js create mode 100644 tests/baselines/reference/concatTuples.symbols create mode 100644 tests/baselines/reference/concatTuples.types create mode 100644 tests/cases/compiler/concatTuples.ts diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 6f017c8a343..496df578c19 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1108,6 +1108,11 @@ interface Array { * Removes the last element from an array and returns it. */ pop(): T | undefined; + /** + * Combines two or more arrays. + * @param items Additional items to add to the end of array1. + */ + concat(...items: T[][]): T[]; /** * Combines two or more arrays. * @param items Additional items to add to the end of array1. diff --git a/tests/baselines/reference/concatTuples.js b/tests/baselines/reference/concatTuples.js new file mode 100644 index 00000000000..699c43f210e --- /dev/null +++ b/tests/baselines/reference/concatTuples.js @@ -0,0 +1,8 @@ +//// [concatTuples.ts] +let ijs: [number, number][] = [[1, 2]]; +ijs = ijs.concat([[3, 4], [5, 6]]); + + +//// [concatTuples.js] +var ijs = [[1, 2]]; +ijs = ijs.concat([[3, 4], [5, 6]]); diff --git a/tests/baselines/reference/concatTuples.symbols b/tests/baselines/reference/concatTuples.symbols new file mode 100644 index 00000000000..a6524f3e1ff --- /dev/null +++ b/tests/baselines/reference/concatTuples.symbols @@ -0,0 +1,10 @@ +=== tests/cases/compiler/concatTuples.ts === +let ijs: [number, number][] = [[1, 2]]; +>ijs : Symbol(ijs, Decl(concatTuples.ts, 0, 3)) + +ijs = ijs.concat([[3, 4], [5, 6]]); +>ijs : Symbol(ijs, Decl(concatTuples.ts, 0, 3)) +>ijs.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>ijs : Symbol(ijs, Decl(concatTuples.ts, 0, 3)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/concatTuples.types b/tests/baselines/reference/concatTuples.types new file mode 100644 index 00000000000..3923470b78d --- /dev/null +++ b/tests/baselines/reference/concatTuples.types @@ -0,0 +1,23 @@ +=== tests/cases/compiler/concatTuples.ts === +let ijs: [number, number][] = [[1, 2]]; +>ijs : [number, number][] +>[[1, 2]] : [number, number][] +>[1, 2] : [number, number] +>1 : number +>2 : number + +ijs = ijs.concat([[3, 4], [5, 6]]); +>ijs = ijs.concat([[3, 4], [5, 6]]) : [number, number][] +>ijs : [number, number][] +>ijs.concat([[3, 4], [5, 6]]) : [number, number][] +>ijs.concat : { (...items: [number, number][][]): [number, number][]; (...items: ([number, number] | [number, number][])[]): [number, number][]; } +>ijs : [number, number][] +>concat : { (...items: [number, number][][]): [number, number][]; (...items: ([number, number] | [number, number][])[]): [number, number][]; } +>[[3, 4], [5, 6]] : [number, number][] +>[3, 4] : [number, number] +>3 : number +>4 : number +>[5, 6] : [number, number] +>5 : number +>6 : number + diff --git a/tests/cases/compiler/concatTuples.ts b/tests/cases/compiler/concatTuples.ts new file mode 100644 index 00000000000..9a62f22bb63 --- /dev/null +++ b/tests/cases/compiler/concatTuples.ts @@ -0,0 +1,2 @@ +let ijs: [number, number][] = [[1, 2]]; +ijs = ijs.concat([[3, 4], [5, 6]]); From e8bd372bb2b9815a589b16759323d089390d2be0 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 27 Jul 2016 15:36:32 -0700 Subject: [PATCH 04/11] Update baselines with new concat overload --- tests/baselines/reference/arrayConcat2.symbols | 12 ++++++------ tests/baselines/reference/arrayConcat2.types | 12 ++++++------ tests/baselines/reference/arrayConcatMap.symbols | 4 ++-- tests/baselines/reference/arrayConcatMap.types | 4 ++-- tests/baselines/reference/concatError.symbols | 8 ++++---- tests/baselines/reference/concatError.types | 8 ++++---- .../reference/emitSkipsThisWithRestParameter.symbols | 4 ++-- .../reference/emitSkipsThisWithRestParameter.types | 4 ++-- .../reference/iteratorSpreadInArray7.symbols | 4 ++-- .../baselines/reference/iteratorSpreadInArray7.types | 4 ++-- ...cAnonymousTypeNotReferencingTypeParameter.symbols | 4 ++-- ...ticAnonymousTypeNotReferencingTypeParameter.types | 4 ++-- tests/baselines/reference/underscoreTest1.symbols | 4 ++-- tests/baselines/reference/underscoreTest1.types | 4 ++-- 14 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/baselines/reference/arrayConcat2.symbols b/tests/baselines/reference/arrayConcat2.symbols index fb84193c113..daedee6e9c8 100644 --- a/tests/baselines/reference/arrayConcat2.symbols +++ b/tests/baselines/reference/arrayConcat2.symbols @@ -3,21 +3,21 @@ var a: string[] = []; >a : Symbol(a, Decl(arrayConcat2.ts, 0, 3)) a.concat("hello", 'world'); ->a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(arrayConcat2.ts, 0, 3)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) a.concat('Hello'); ->a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(arrayConcat2.ts, 0, 3)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) var b = new Array(); >b : Symbol(b, Decl(arrayConcat2.ts, 5, 3)) >Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) b.concat('hello'); ->b.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>b.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b : Symbol(b, Decl(arrayConcat2.ts, 5, 3)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) diff --git a/tests/baselines/reference/arrayConcat2.types b/tests/baselines/reference/arrayConcat2.types index b7df3749116..27fe754c485 100644 --- a/tests/baselines/reference/arrayConcat2.types +++ b/tests/baselines/reference/arrayConcat2.types @@ -5,17 +5,17 @@ var a: string[] = []; a.concat("hello", 'world'); >a.concat("hello", 'world') : string[] ->a.concat : (...items: (string | string[])[]) => string[] +>a.concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; } >a : string[] ->concat : (...items: (string | string[])[]) => string[] +>concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; } >"hello" : string >'world' : string a.concat('Hello'); >a.concat('Hello') : string[] ->a.concat : (...items: (string | string[])[]) => string[] +>a.concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; } >a : string[] ->concat : (...items: (string | string[])[]) => string[] +>concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; } >'Hello' : string var b = new Array(); @@ -25,8 +25,8 @@ var b = new Array(); b.concat('hello'); >b.concat('hello') : string[] ->b.concat : (...items: (string | string[])[]) => string[] +>b.concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; } >b : string[] ->concat : (...items: (string | string[])[]) => string[] +>concat : { (...items: string[][]): string[]; (...items: (string | string[])[]): string[]; } >'hello' : string diff --git a/tests/baselines/reference/arrayConcatMap.symbols b/tests/baselines/reference/arrayConcatMap.symbols index bde2686e259..5ef9d811723 100644 --- a/tests/baselines/reference/arrayConcatMap.symbols +++ b/tests/baselines/reference/arrayConcatMap.symbols @@ -2,8 +2,8 @@ var x = [].concat([{ a: 1 }], [{ a: 2 }]) >x : Symbol(x, Decl(arrayConcatMap.ts, 0, 3)) >[].concat([{ a: 1 }], [{ a: 2 }]) .map : Symbol(Array.map, Decl(lib.d.ts, --, --)) ->[].concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>[].concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(arrayConcatMap.ts, 0, 20)) >a : Symbol(a, Decl(arrayConcatMap.ts, 0, 32)) diff --git a/tests/baselines/reference/arrayConcatMap.types b/tests/baselines/reference/arrayConcatMap.types index 38e1a1c49c9..647406ef1c3 100644 --- a/tests/baselines/reference/arrayConcatMap.types +++ b/tests/baselines/reference/arrayConcatMap.types @@ -4,9 +4,9 @@ var x = [].concat([{ a: 1 }], [{ a: 2 }]) >[].concat([{ a: 1 }], [{ a: 2 }]) .map(b => b.a) : any[] >[].concat([{ a: 1 }], [{ a: 2 }]) .map : (callbackfn: (value: any, index: number, array: any[]) => U, thisArg?: any) => U[] >[].concat([{ a: 1 }], [{ a: 2 }]) : any[] ->[].concat : (...items: any[]) => any[] +>[].concat : { (...items: any[][]): any[]; (...items: any[]): any[]; } >[] : undefined[] ->concat : (...items: any[]) => any[] +>concat : { (...items: any[][]): any[]; (...items: any[]): any[]; } >[{ a: 1 }] : { a: number; }[] >{ a: 1 } : { a: number; } >a : number diff --git a/tests/baselines/reference/concatError.symbols b/tests/baselines/reference/concatError.symbols index 23cc55c85be..d4f04531fc7 100644 --- a/tests/baselines/reference/concatError.symbols +++ b/tests/baselines/reference/concatError.symbols @@ -14,15 +14,15 @@ var fa: number[]; fa = fa.concat([0]); >fa : Symbol(fa, Decl(concatError.ts, 8, 3)) ->fa.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>fa.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >fa : Symbol(fa, Decl(concatError.ts, 8, 3)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) fa = fa.concat(0); >fa : Symbol(fa, Decl(concatError.ts, 8, 3)) ->fa.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>fa.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >fa : Symbol(fa, Decl(concatError.ts, 8, 3)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) diff --git a/tests/baselines/reference/concatError.types b/tests/baselines/reference/concatError.types index 21a5cc5d089..9624342bd21 100644 --- a/tests/baselines/reference/concatError.types +++ b/tests/baselines/reference/concatError.types @@ -16,9 +16,9 @@ fa = fa.concat([0]); >fa = fa.concat([0]) : number[] >fa : number[] >fa.concat([0]) : number[] ->fa.concat : (...items: (number | number[])[]) => number[] +>fa.concat : { (...items: number[][]): number[]; (...items: (number | number[])[]): number[]; } >fa : number[] ->concat : (...items: (number | number[])[]) => number[] +>concat : { (...items: number[][]): number[]; (...items: (number | number[])[]): number[]; } >[0] : number[] >0 : number @@ -26,9 +26,9 @@ fa = fa.concat(0); >fa = fa.concat(0) : number[] >fa : number[] >fa.concat(0) : number[] ->fa.concat : (...items: (number | number[])[]) => number[] +>fa.concat : { (...items: number[][]): number[]; (...items: (number | number[])[]): number[]; } >fa : number[] ->concat : (...items: (number | number[])[]) => number[] +>concat : { (...items: number[][]): number[]; (...items: (number | number[])[]): number[]; } >0 : number diff --git a/tests/baselines/reference/emitSkipsThisWithRestParameter.symbols b/tests/baselines/reference/emitSkipsThisWithRestParameter.symbols index 4f1e2bc1aec..04a699a322d 100644 --- a/tests/baselines/reference/emitSkipsThisWithRestParameter.symbols +++ b/tests/baselines/reference/emitSkipsThisWithRestParameter.symbols @@ -15,9 +15,9 @@ function rebase(fn: (base: any, ...args: any[]) => any): (...args: any[]) => any >fn : Symbol(fn, Decl(emitSkipsThisWithRestParameter.ts, 0, 16)) >apply : Symbol(Function.apply, Decl(lib.d.ts, --, --)) >this : Symbol(this, Decl(emitSkipsThisWithRestParameter.ts, 1, 20)) ->[ this ].concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>[ this ].concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >this : Symbol(this, Decl(emitSkipsThisWithRestParameter.ts, 1, 20)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >args : Symbol(args, Decl(emitSkipsThisWithRestParameter.ts, 1, 30)) }; diff --git a/tests/baselines/reference/emitSkipsThisWithRestParameter.types b/tests/baselines/reference/emitSkipsThisWithRestParameter.types index 97276fa117d..ff6f1e6f73a 100644 --- a/tests/baselines/reference/emitSkipsThisWithRestParameter.types +++ b/tests/baselines/reference/emitSkipsThisWithRestParameter.types @@ -18,10 +18,10 @@ function rebase(fn: (base: any, ...args: any[]) => any): (...args: any[]) => any >apply : (this: Function, thisArg: any, argArray?: any) => any >this : any >[ this ].concat(args) : any[] ->[ this ].concat : (...items: any[]) => any[] +>[ this ].concat : { (...items: any[][]): any[]; (...items: any[]): any[]; } >[ this ] : any[] >this : any ->concat : (...items: any[]) => any[] +>concat : { (...items: any[][]): any[]; (...items: any[]): any[]; } >args : any[] }; diff --git a/tests/baselines/reference/iteratorSpreadInArray7.symbols b/tests/baselines/reference/iteratorSpreadInArray7.symbols index 853e07b908a..57774bcd7ee 100644 --- a/tests/baselines/reference/iteratorSpreadInArray7.symbols +++ b/tests/baselines/reference/iteratorSpreadInArray7.symbols @@ -3,9 +3,9 @@ var array: symbol[]; >array : Symbol(array, Decl(iteratorSpreadInArray7.ts, 0, 3)) array.concat([...new SymbolIterator]); ->array.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --)) +>array.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >array : Symbol(array, Decl(iteratorSpreadInArray7.ts, 0, 3)) ->concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >SymbolIterator : Symbol(SymbolIterator, Decl(iteratorSpreadInArray7.ts, 1, 38)) class SymbolIterator { diff --git a/tests/baselines/reference/iteratorSpreadInArray7.types b/tests/baselines/reference/iteratorSpreadInArray7.types index f1dd8ebf855..38549a606ab 100644 --- a/tests/baselines/reference/iteratorSpreadInArray7.types +++ b/tests/baselines/reference/iteratorSpreadInArray7.types @@ -4,9 +4,9 @@ var array: symbol[]; array.concat([...new SymbolIterator]); >array.concat([...new SymbolIterator]) : symbol[] ->array.concat : (...items: (symbol | symbol[])[]) => symbol[] +>array.concat : { (...items: symbol[][]): symbol[]; (...items: (symbol | symbol[])[]): symbol[]; } >array : symbol[] ->concat : (...items: (symbol | symbol[])[]) => symbol[] +>concat : { (...items: symbol[][]): symbol[]; (...items: (symbol | symbol[])[]): symbol[]; } >[...new SymbolIterator] : symbol[] >...new SymbolIterator : symbol >new SymbolIterator : SymbolIterator diff --git a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.symbols b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.symbols index 2596959de9e..f217f42a8d6 100644 --- a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.symbols +++ b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.symbols @@ -300,9 +300,9 @@ class ListWrapper { >ListWrapper : Symbol(ListWrapper, Decl(staticAnonymousTypeNotReferencingTypeParameter.ts, 38, 1)) >a : Symbol(a, Decl(staticAnonymousTypeNotReferencingTypeParameter.ts, 68, 40)) >b : Symbol(b, Decl(staticAnonymousTypeNotReferencingTypeParameter.ts, 68, 50)) ->a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(staticAnonymousTypeNotReferencingTypeParameter.ts, 68, 40)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b : Symbol(b, Decl(staticAnonymousTypeNotReferencingTypeParameter.ts, 68, 50)) static insert(dit: typeof ListWrapper, list: T[], index: number, value: T) { list.splice(index, 0, value); } diff --git a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types index 8d35f32707a..9aa24f01059 100644 --- a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types +++ b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types @@ -348,9 +348,9 @@ class ListWrapper { >a : any[] >b : any[] >a.concat(b) : any[] ->a.concat : (...items: any[]) => any[] +>a.concat : { (...items: any[][]): any[]; (...items: any[]): any[]; } >a : any[] ->concat : (...items: any[]) => any[] +>concat : { (...items: any[][]): any[]; (...items: any[]): any[]; } >b : any[] static insert(dit: typeof ListWrapper, list: T[], index: number, value: T) { list.splice(index, 0, value); } diff --git a/tests/baselines/reference/underscoreTest1.symbols b/tests/baselines/reference/underscoreTest1.symbols index 3506f23510e..89815bd2371 100644 --- a/tests/baselines/reference/underscoreTest1.symbols +++ b/tests/baselines/reference/underscoreTest1.symbols @@ -71,9 +71,9 @@ var flat = _.reduceRight(list, (a, b) => a.concat(b), []); >list : Symbol(list, Decl(underscoreTest1_underscoreTests.ts, 13, 3)) >a : Symbol(a, Decl(underscoreTest1_underscoreTests.ts, 14, 32)) >b : Symbol(b, Decl(underscoreTest1_underscoreTests.ts, 14, 34)) ->a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>a.concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(underscoreTest1_underscoreTests.ts, 14, 32)) ->concat : Symbol(Array.concat, Decl(lib.d.ts, --, --)) +>concat : Symbol(Array.concat, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >b : Symbol(b, Decl(underscoreTest1_underscoreTests.ts, 14, 34)) var even = _.find([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); diff --git a/tests/baselines/reference/underscoreTest1.types b/tests/baselines/reference/underscoreTest1.types index 37f3bdb12ab..0a261883ed8 100644 --- a/tests/baselines/reference/underscoreTest1.types +++ b/tests/baselines/reference/underscoreTest1.types @@ -124,9 +124,9 @@ var flat = _.reduceRight(list, (a, b) => a.concat(b), []); >a : number[] >b : number[] >a.concat(b) : number[] ->a.concat : (...items: (number | number[])[]) => number[] +>a.concat : { (...items: number[][]): number[]; (...items: (number | number[])[]): number[]; } >a : number[] ->concat : (...items: (number | number[])[]) => number[] +>concat : { (...items: number[][]): number[]; (...items: (number | number[])[]): number[]; } >b : number[] >[] : undefined[] From 0f1585f0af48ffdc505ed174e8d0d6d51f0dea16 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Fri, 29 Jul 2016 11:02:33 -0700 Subject: [PATCH 05/11] recreate program if baseUrl or paths changed in tsconfig --- src/services/services.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index ad630fd444e..fd4354923c8 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3097,7 +3097,9 @@ namespace ts { oldSettings.noResolve !== newSettings.noResolve || oldSettings.jsx !== newSettings.jsx || oldSettings.allowJs !== newSettings.allowJs || - oldSettings.disableSizeLimit !== oldSettings.disableSizeLimit); + oldSettings.disableSizeLimit !== oldSettings.disableSizeLimit || + oldSettings.baseUrl !== newSettings.baseUrl || + !mapIsEqualTo(oldSettings.paths, newSettings.paths)); // Now create a new compiler const compilerHost: CompilerHost = { From fc85bc5a8aeafd69215bfdb308fbd064909b11c9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 31 Jul 2016 07:57:01 -0700 Subject: [PATCH 06/11] Use "best choice type" for || and ?: operators --- src/compiler/checker.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 33abcb2af12..7d878765494 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12896,6 +12896,14 @@ namespace ts { return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target); } + function getBestChoiceType(type1: Type, type2: Type): Type { + const firstAssignableToSecond = isTypeAssignableTo(type1, type2); + const secondAssignableToFirst = isTypeAssignableTo(type2, type1); + return secondAssignableToFirst && !firstAssignableToSecond ? type1 : + firstAssignableToSecond && !secondAssignableToFirst ? type2 : + getUnionType([type1, type2], /*subtypeReduction*/ true); + } + function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) { return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node); } @@ -13039,7 +13047,7 @@ namespace ts { leftType; case SyntaxKind.BarBarToken: return getTypeFacts(leftType) & TypeFacts.Falsy ? - getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], /*subtypeReduction*/ true) : + getBestChoiceType(removeDefinitelyFalsyTypes(leftType), rightType) : leftType; case SyntaxKind.EqualsToken: checkAssignmentOperator(rightType); @@ -13166,7 +13174,7 @@ namespace ts { checkExpression(node.condition); const type1 = checkExpression(node.whenTrue, contextualMapper); const type2 = checkExpression(node.whenFalse, contextualMapper); - return getUnionType([type1, type2], /*subtypeReduction*/ true); + return getBestChoiceType(type1, type2); } function typeContainsLiteralFromEnum(type: Type, enumType: EnumType) { From 5c4c997efabefaf80f9d96f49c87c6f2fe684f9a Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Mon, 1 Aug 2016 00:35:34 +0900 Subject: [PATCH 07/11] jsx opening element formatting --- src/services/formatting/formatting.ts | 12 ++--- src/services/formatting/rules.ts | 46 +++++++++++++++---- .../cases/fourslash/formattingJsxElements.ts | 10 ++-- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 5dae6393b99..e131fbb4c1d 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -453,9 +453,9 @@ namespace ts.formatting { case SyntaxKind.MethodDeclaration: if ((node).asteriskToken) { return SyntaxKind.AsteriskToken; - } - // fall-through - + }/* + fall-through + */ case SyntaxKind.PropertyDeclaration: case SyntaxKind.Parameter: return (node).name.kind; @@ -729,7 +729,7 @@ namespace ts.formatting { else { // indent token only if end line of previous range does not match start line of the token const prevEndLine = savePreviousRange && sourceFile.getLineAndCharacterOfPosition(savePreviousRange.end).line; - indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine; + indentToken = lastTriviaWasNewLine && tokenStart.line !== prevEndLine; } } } @@ -889,7 +889,7 @@ namespace ts.formatting { } function indentationIsDifferent(indentationString: string, startLinePosition: number): boolean { - return indentationString !== sourceFile.text.substr(startLinePosition , indentationString.length); + return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length); } function indentMultilineComment(commentRange: TextRange, indentation: number, firstLineIsIndented: boolean) { @@ -933,7 +933,7 @@ namespace ts.formatting { // shift all parts on the delta size const delta = indentation - nonWhitespaceColumnInFirstPart.column; - for (let i = startIndex, len = parts.length; i < len; i++, startLine++) { + for (let i = startIndex, len = parts.length; i < len; i++ , startLine++) { const startLinePos = getStartPositionOfLine(startLine, sourceFile); const nonWhitespaceCharacterAndColumn = i === 0 diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 110ac9bf4ea..1839726b9ad 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -231,6 +231,13 @@ namespace ts.formatting { public NoSpaceBeforeCloseBraceInJsxExpression: Rule; public SpaceBeforeCloseBraceInJsxExpression: Rule; + // JSX opening elements + public SpaceBeforeJsxAttribute: Rule; + public SpaceBeforeSlashInJsxOpeningElement: Rule; + public NoSpaceBeforeGreaterThanTokenInJsxOpeningElement: Rule; + public NoSpaceBeforeEqualInJsxAttribute: Rule; + public NoSpaceAfterEqualInJsxAttribute: Rule; + constructor() { /// /// Common Rules @@ -322,7 +329,7 @@ namespace ts.formatting { // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] - this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space)); + this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space)); // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. this.SpaceAfterTryFinally = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword]), SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); @@ -386,6 +393,13 @@ namespace ts.formatting { // template string this.NoSpaceBetweenTagAndTemplateString = new Rule(RuleDescriptor.create3(SyntaxKind.Identifier, Shared.TokenRange.FromTokens([SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + // jsx opening element + this.SpaceBeforeJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.Identifier), RuleOperation.create2(new RuleOperationContext(Rules.IsNextTokenParentJsxAttribute, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); + this.SpaceBeforeSlashInJsxOpeningElement = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.SlashToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); + this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement = new Rule(RuleDescriptor.create1(SyntaxKind.SlashToken, SyntaxKind.GreaterThanToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxSelfClosingElementContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + this.NoSpaceBeforeEqualInJsxAttribute = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.EqualsToken), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + this.NoSpaceAfterEqualInJsxAttribute = new Rule(RuleDescriptor.create3(SyntaxKind.EqualsToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsJsxAttributeContext, Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + // These rules are higher in priority than user-configurable rules. this.HighPriorityCommonRules = [ this.IgnoreBeforeComment, this.IgnoreAfterLineComment, @@ -413,6 +427,8 @@ namespace ts.formatting { this.SpaceAfterVoidOperator, this.SpaceBetweenAsyncAndOpenParen, this.SpaceBetweenAsyncAndFunctionKeyword, this.NoSpaceBetweenTagAndTemplateString, + this.SpaceBeforeJsxAttribute, this.SpaceBeforeSlashInJsxOpeningElement, this.NoSpaceBeforeGreaterThanTokenInJsxOpeningElement, + this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute, // TypeScript-specific rules this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, @@ -450,8 +466,8 @@ namespace ts.formatting { /// // Insert space after comma delimiter - this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space)); - this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext), RuleAction.Delete)); + this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space)); + this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNonJsxElementContext), RuleAction.Delete)); // Insert space before and after binary operators this.SpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); @@ -498,10 +514,10 @@ namespace ts.formatting { this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); // No space after { and before } in JSX expression - this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete)); - this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space)); - this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete)); - this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space)); + this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete)); + this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space)); + this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Delete)); + this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsJsxExpressionContext), RuleAction.Space)); // Insert space after function keyword for anonymous functions this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space)); @@ -741,14 +757,26 @@ namespace ts.formatting { return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText; } - static isNonJsxElementContext(context: FormattingContext): boolean { + static IsNonJsxElementContext(context: FormattingContext): boolean { return context.contextNode.kind !== SyntaxKind.JsxElement; } - static isJsxExpressionContext(context: FormattingContext): boolean { + static IsJsxExpressionContext(context: FormattingContext): boolean { return context.contextNode.kind === SyntaxKind.JsxExpression; } + static IsNextTokenParentJsxAttribute(context: FormattingContext): boolean { + return context.nextTokenParent.kind === SyntaxKind.JsxAttribute; + } + + static IsJsxAttributeContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.JsxAttribute; + } + + static IsJsxSelfClosingElementContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.JsxSelfClosingElement; + } + static IsNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean { return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context); } diff --git a/tests/cases/fourslash/formattingJsxElements.ts b/tests/cases/fourslash/formattingJsxElements.ts index e07149960db..2b3b396ed4c 100644 --- a/tests/cases/fourslash/formattingJsxElements.ts +++ b/tests/cases/fourslash/formattingJsxElements.ts @@ -70,7 +70,7 @@ ////
, {integer}
;/*commaInJsxElement2*/ ////);/*closingParenInJsxElement*/ ////) ;/*closingParenInJsxElement2*/ -////;/*jsxExpressionSpaces*/ +////;/*jsxExpressionSpaces*/ ////;/*jsxExpressionSpaces2*/ format.document(); @@ -85,7 +85,7 @@ goTo.marker("indent1"); verify.indentationIs(12); goTo.marker("1"); -verify.currentLineContentIs(' class1= {'); +verify.currentLineContentIs(' class1={'); goTo.marker("2"); verify.currentLineContentIs(' }>'); @@ -95,7 +95,7 @@ goTo.marker("indent2"); verify.indentationIs(12); goTo.marker("3"); -verify.currentLineContentIs(' class2= {'); +verify.currentLineContentIs(' class2={'); goTo.marker("4"); verify.currentLineContentIs(' }>'); @@ -105,9 +105,9 @@ goTo.marker("indent3"); verify.indentationIs(12); goTo.marker("5"); -verify.currentLineContentIs(' class3= {'); +verify.currentLineContentIs(' class3={'); goTo.marker("6"); -verify.currentLineContentIs(' }/>'); +verify.currentLineContentIs(' } />'); goTo.marker("attrAutoformat"); From 47f6bb2e26a57e53346412c84b65f01029e6ddef Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 1 Aug 2016 09:49:27 -0700 Subject: [PATCH 08/11] Add test --- tests/cases/compiler/bestChoiceType.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/cases/compiler/bestChoiceType.ts diff --git a/tests/cases/compiler/bestChoiceType.ts b/tests/cases/compiler/bestChoiceType.ts new file mode 100644 index 00000000000..3f8ce4bc868 --- /dev/null +++ b/tests/cases/compiler/bestChoiceType.ts @@ -0,0 +1,19 @@ +// @strictNullChecks: true + +// Repro from #10041 + +(''.match(/ /) || []).map(s => s.toLowerCase()); + +// Similar cases + +function f1() { + let x = ''.match(/ /); + let y = x || []; + let z = y.map(s => s.toLowerCase()); +} + +function f2() { + let x = ''.match(/ /); + let y = x ? x : []; + let z = y.map(s => s.toLowerCase()); +} From aa8c6c8f631b65705ead8019ffe0a955fff5aeab Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 1 Aug 2016 09:50:08 -0700 Subject: [PATCH 09/11] Add test baselines --- tests/baselines/reference/bestChoiceType.js | 35 ++++++++ .../reference/bestChoiceType.symbols | 63 +++++++++++++ .../baselines/reference/bestChoiceType.types | 88 +++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 tests/baselines/reference/bestChoiceType.js create mode 100644 tests/baselines/reference/bestChoiceType.symbols create mode 100644 tests/baselines/reference/bestChoiceType.types diff --git a/tests/baselines/reference/bestChoiceType.js b/tests/baselines/reference/bestChoiceType.js new file mode 100644 index 00000000000..0c1bf5df2d4 --- /dev/null +++ b/tests/baselines/reference/bestChoiceType.js @@ -0,0 +1,35 @@ +//// [bestChoiceType.ts] + +// Repro from #10041 + +(''.match(/ /) || []).map(s => s.toLowerCase()); + +// Similar cases + +function f1() { + let x = ''.match(/ /); + let y = x || []; + let z = y.map(s => s.toLowerCase()); +} + +function f2() { + let x = ''.match(/ /); + let y = x ? x : []; + let z = y.map(s => s.toLowerCase()); +} + + +//// [bestChoiceType.js] +// Repro from #10041 +(''.match(/ /) || []).map(function (s) { return s.toLowerCase(); }); +// Similar cases +function f1() { + var x = ''.match(/ /); + var y = x || []; + var z = y.map(function (s) { return s.toLowerCase(); }); +} +function f2() { + var x = ''.match(/ /); + var y = x ? x : []; + var z = y.map(function (s) { return s.toLowerCase(); }); +} diff --git a/tests/baselines/reference/bestChoiceType.symbols b/tests/baselines/reference/bestChoiceType.symbols new file mode 100644 index 00000000000..25f7de2eeda --- /dev/null +++ b/tests/baselines/reference/bestChoiceType.symbols @@ -0,0 +1,63 @@ +=== tests/cases/compiler/bestChoiceType.ts === + +// Repro from #10041 + +(''.match(/ /) || []).map(s => s.toLowerCase()); +>(''.match(/ /) || []).map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>''.match : Symbol(String.match, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>match : Symbol(String.match, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>s : Symbol(s, Decl(bestChoiceType.ts, 3, 26)) +>s.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) +>s : Symbol(s, Decl(bestChoiceType.ts, 3, 26)) +>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) + +// Similar cases + +function f1() { +>f1 : Symbol(f1, Decl(bestChoiceType.ts, 3, 48)) + + let x = ''.match(/ /); +>x : Symbol(x, Decl(bestChoiceType.ts, 8, 7)) +>''.match : Symbol(String.match, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>match : Symbol(String.match, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let y = x || []; +>y : Symbol(y, Decl(bestChoiceType.ts, 9, 7)) +>x : Symbol(x, Decl(bestChoiceType.ts, 8, 7)) + + let z = y.map(s => s.toLowerCase()); +>z : Symbol(z, Decl(bestChoiceType.ts, 10, 7)) +>y.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>y : Symbol(y, Decl(bestChoiceType.ts, 9, 7)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>s : Symbol(s, Decl(bestChoiceType.ts, 10, 18)) +>s.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) +>s : Symbol(s, Decl(bestChoiceType.ts, 10, 18)) +>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) +} + +function f2() { +>f2 : Symbol(f2, Decl(bestChoiceType.ts, 11, 1)) + + let x = ''.match(/ /); +>x : Symbol(x, Decl(bestChoiceType.ts, 14, 7)) +>''.match : Symbol(String.match, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>match : Symbol(String.match, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + let y = x ? x : []; +>y : Symbol(y, Decl(bestChoiceType.ts, 15, 7)) +>x : Symbol(x, Decl(bestChoiceType.ts, 14, 7)) +>x : Symbol(x, Decl(bestChoiceType.ts, 14, 7)) + + let z = y.map(s => s.toLowerCase()); +>z : Symbol(z, Decl(bestChoiceType.ts, 16, 7)) +>y.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>y : Symbol(y, Decl(bestChoiceType.ts, 15, 7)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>s : Symbol(s, Decl(bestChoiceType.ts, 16, 18)) +>s.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) +>s : Symbol(s, Decl(bestChoiceType.ts, 16, 18)) +>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) +} + diff --git a/tests/baselines/reference/bestChoiceType.types b/tests/baselines/reference/bestChoiceType.types new file mode 100644 index 00000000000..f88cf64e5a2 --- /dev/null +++ b/tests/baselines/reference/bestChoiceType.types @@ -0,0 +1,88 @@ +=== tests/cases/compiler/bestChoiceType.ts === + +// Repro from #10041 + +(''.match(/ /) || []).map(s => s.toLowerCase()); +>(''.match(/ /) || []).map(s => s.toLowerCase()) : string[] +>(''.match(/ /) || []).map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>(''.match(/ /) || []) : RegExpMatchArray +>''.match(/ /) || [] : RegExpMatchArray +>''.match(/ /) : RegExpMatchArray | null +>''.match : { (regexp: string): RegExpMatchArray | null; (regexp: RegExp): RegExpMatchArray | null; } +>'' : string +>match : { (regexp: string): RegExpMatchArray | null; (regexp: RegExp): RegExpMatchArray | null; } +>/ / : RegExp +>[] : never[] +>map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>s => s.toLowerCase() : (s: string) => string +>s : string +>s.toLowerCase() : string +>s.toLowerCase : () => string +>s : string +>toLowerCase : () => string + +// Similar cases + +function f1() { +>f1 : () => void + + let x = ''.match(/ /); +>x : RegExpMatchArray | null +>''.match(/ /) : RegExpMatchArray | null +>''.match : { (regexp: string): RegExpMatchArray | null; (regexp: RegExp): RegExpMatchArray | null; } +>'' : string +>match : { (regexp: string): RegExpMatchArray | null; (regexp: RegExp): RegExpMatchArray | null; } +>/ / : RegExp + + let y = x || []; +>y : RegExpMatchArray +>x || [] : RegExpMatchArray +>x : RegExpMatchArray | null +>[] : never[] + + let z = y.map(s => s.toLowerCase()); +>z : string[] +>y.map(s => s.toLowerCase()) : string[] +>y.map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>y : RegExpMatchArray +>map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>s => s.toLowerCase() : (s: string) => string +>s : string +>s.toLowerCase() : string +>s.toLowerCase : () => string +>s : string +>toLowerCase : () => string +} + +function f2() { +>f2 : () => void + + let x = ''.match(/ /); +>x : RegExpMatchArray | null +>''.match(/ /) : RegExpMatchArray | null +>''.match : { (regexp: string): RegExpMatchArray | null; (regexp: RegExp): RegExpMatchArray | null; } +>'' : string +>match : { (regexp: string): RegExpMatchArray | null; (regexp: RegExp): RegExpMatchArray | null; } +>/ / : RegExp + + let y = x ? x : []; +>y : RegExpMatchArray +>x ? x : [] : RegExpMatchArray +>x : RegExpMatchArray | null +>x : RegExpMatchArray +>[] : never[] + + let z = y.map(s => s.toLowerCase()); +>z : string[] +>y.map(s => s.toLowerCase()) : string[] +>y.map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>y : RegExpMatchArray +>map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>s => s.toLowerCase() : (s: string) => string +>s : string +>s.toLowerCase() : string +>s.toLowerCase : () => string +>s : string +>toLowerCase : () => string +} + From c7d2e5975ba21afce30af3cb083bee41e5367f6f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 1 Aug 2016 09:50:17 -0700 Subject: [PATCH 10/11] Accept new baselines --- .../baselines/reference/nonContextuallyTypedLogicalOr.symbols | 4 ++-- tests/baselines/reference/nonContextuallyTypedLogicalOr.types | 4 ++-- .../reference/subtypingWithObjectMembersOptionality3.types | 4 ++-- .../reference/subtypingWithObjectMembersOptionality4.types | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/nonContextuallyTypedLogicalOr.symbols b/tests/baselines/reference/nonContextuallyTypedLogicalOr.symbols index 2d921f6631c..43d7539b6b9 100644 --- a/tests/baselines/reference/nonContextuallyTypedLogicalOr.symbols +++ b/tests/baselines/reference/nonContextuallyTypedLogicalOr.symbols @@ -28,8 +28,8 @@ var e: Ellement; >Ellement : Symbol(Ellement, Decl(nonContextuallyTypedLogicalOr.ts, 3, 1)) (c || e).dummy; ->(c || e).dummy : Symbol(dummy, Decl(nonContextuallyTypedLogicalOr.ts, 0, 22), Decl(nonContextuallyTypedLogicalOr.ts, 5, 20)) +>(c || e).dummy : Symbol(Contextual.dummy, Decl(nonContextuallyTypedLogicalOr.ts, 0, 22)) >c : Symbol(c, Decl(nonContextuallyTypedLogicalOr.ts, 10, 3)) >e : Symbol(e, Decl(nonContextuallyTypedLogicalOr.ts, 11, 3)) ->dummy : Symbol(dummy, Decl(nonContextuallyTypedLogicalOr.ts, 0, 22), Decl(nonContextuallyTypedLogicalOr.ts, 5, 20)) +>dummy : Symbol(Contextual.dummy, Decl(nonContextuallyTypedLogicalOr.ts, 0, 22)) diff --git a/tests/baselines/reference/nonContextuallyTypedLogicalOr.types b/tests/baselines/reference/nonContextuallyTypedLogicalOr.types index aeb9d1409c6..5061ad1d975 100644 --- a/tests/baselines/reference/nonContextuallyTypedLogicalOr.types +++ b/tests/baselines/reference/nonContextuallyTypedLogicalOr.types @@ -29,8 +29,8 @@ var e: Ellement; (c || e).dummy; >(c || e).dummy : any ->(c || e) : Contextual | Ellement ->c || e : Contextual | Ellement +>(c || e) : Contextual +>c || e : Contextual >c : Contextual >e : Ellement >dummy : any diff --git a/tests/baselines/reference/subtypingWithObjectMembersOptionality3.types b/tests/baselines/reference/subtypingWithObjectMembersOptionality3.types index 000d1cdc8ed..6490b0abd9b 100644 --- a/tests/baselines/reference/subtypingWithObjectMembersOptionality3.types +++ b/tests/baselines/reference/subtypingWithObjectMembersOptionality3.types @@ -69,8 +69,8 @@ var b: { Foo2: Derived; } >Derived : Derived var r = true ? a : b; // ok ->r : { Foo?: Base; } | { Foo2: Derived; } ->true ? a : b : { Foo?: Base; } | { Foo2: Derived; } +>r : { Foo?: Base; } +>true ? a : b : { Foo?: Base; } >true : boolean >a : { Foo?: Base; } >b : { Foo2: Derived; } diff --git a/tests/baselines/reference/subtypingWithObjectMembersOptionality4.types b/tests/baselines/reference/subtypingWithObjectMembersOptionality4.types index 2dcda59f46f..ee636be020b 100644 --- a/tests/baselines/reference/subtypingWithObjectMembersOptionality4.types +++ b/tests/baselines/reference/subtypingWithObjectMembersOptionality4.types @@ -69,8 +69,8 @@ var b: { Foo2?: Derived; } >Derived : Derived var r = true ? a : b; // ok ->r : { Foo: Base; } | { Foo2?: Derived; } ->true ? a : b : { Foo: Base; } | { Foo2?: Derived; } +>r : { Foo2?: Derived; } +>true ? a : b : { Foo2?: Derived; } >true : boolean >a : { Foo: Base; } >b : { Foo2?: Derived; } From f78b9094be5697d2a14b9e2384c0cc1acfceea47 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Mon, 1 Aug 2016 16:50:16 -0700 Subject: [PATCH 11/11] CR feedback --- src/services/services.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index fd4354923c8..6ec95343e33 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3090,7 +3090,7 @@ namespace ts { const oldSettings = program && program.getCompilerOptions(); const newSettings = hostCache.compilationSettings(); - const changesInCompilationSettingsAffectSyntax = oldSettings && + const shouldCreateNewSourceFiles = oldSettings && (oldSettings.target !== newSettings.target || oldSettings.module !== newSettings.module || oldSettings.moduleResolution !== newSettings.moduleResolution || @@ -3151,7 +3151,7 @@ namespace ts { const oldSourceFiles = program.getSourceFiles(); const oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldSettings); for (const oldSourceFile of oldSourceFiles) { - if (!newProgram.getSourceFile(oldSourceFile.fileName) || changesInCompilationSettingsAffectSyntax) { + if (!newProgram.getSourceFile(oldSourceFile.fileName) || shouldCreateNewSourceFiles) { documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey); } } @@ -3185,7 +3185,7 @@ namespace ts { // Check if the language version has changed since we last created a program; if they are the same, // it is safe to reuse the sourceFiles; if not, then the shape of the AST can change, and the oldSourceFile // can not be reused. we have to dump all syntax trees and create new ones. - if (!changesInCompilationSettingsAffectSyntax) { + if (!shouldCreateNewSourceFiles) { // Check if the old program had this file already const oldSourceFile = program && program.getSourceFileByPath(path); if (oldSourceFile) {