From 62d304b069a322ce739079da04d6546236fc3966 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 5 Mar 2015 02:31:55 -0800 Subject: [PATCH 1/4] Preserve newlines for property access expressions on multiple lines. --- src/compiler/emitter.ts | 21 +++++++++++++++++++ src/compiler/parser.ts | 20 +++++++++++------- src/compiler/types.ts | 1 + .../baselines/reference/APISample_compile.js | 1 + .../reference/APISample_compile.types | 4 ++++ tests/baselines/reference/APISample_linter.js | 1 + .../reference/APISample_linter.types | 4 ++++ .../reference/APISample_transform.js | 1 + .../reference/APISample_transform.types | 4 ++++ .../baselines/reference/APISample_watcher.js | 8 +++++-- .../reference/APISample_watcher.types | 4 ++++ tests/baselines/reference/arrayConcatMap.js | 3 ++- .../enumConflictsWithGlobalIdentifier.js | 3 ++- .../reference/enumMemberResolution.js | 3 ++- ...nsMissingReturnStatementsAndExpressions.js | 3 ++- .../reference/genericChainedCalls.js | 5 +++-- .../overEagerReturnTypeSpecialization.js | 4 ++-- tests/baselines/reference/parse1.js | 3 ++- tests/baselines/reference/parser509667.js | 3 ++- tests/baselines/reference/underscoreTest1.js | 6 +++++- .../reference/wrappedIncovations1.js | 11 ++++++++++ .../reference/wrappedIncovations1.types | 20 ++++++++++++++++++ .../reference/wrappedIncovations2.js | 11 ++++++++++ .../reference/wrappedIncovations2.types | 20 ++++++++++++++++++ tests/cases/compiler/wrappedIncovations1.ts | 4 ++++ tests/cases/compiler/wrappedIncovations2.ts | 4 ++++ tests/cases/unittests/incrementalParser.ts | 2 +- 27 files changed, 152 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/wrappedIncovations1.js create mode 100644 tests/baselines/reference/wrappedIncovations1.types create mode 100644 tests/baselines/reference/wrappedIncovations2.js create mode 100644 tests/baselines/reference/wrappedIncovations2.types create mode 100644 tests/cases/compiler/wrappedIncovations1.ts create mode 100644 tests/cases/compiler/wrappedIncovations2.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index b1dcbfbcd95..a0c887414cd 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3036,9 +3036,30 @@ module ts { if (tryEmitConstantValue(node)) { return; } + emit(node.expression); + + var indented = false; + var isSynthesied = nodeIsSynthesized(node); + if (!isSynthesied && !nodeEndIsOnSameLineAsNodeStart(node.expression, node.dotToken)) { + indented = true; + increaseIndent(); + writeLine(); + } + write("."); + + if (!isSynthesied && !nodeEndIsOnSameLineAsNodeStart(node.dotToken, node.name) && !indented) { + indented = true; + increaseIndent(); + writeLine(); + } + emit(node.name); + + if (indented) { + decreaseIndent(); + } } function emitQualifiedName(node: QualifiedName) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0bb09330070..557d6505984 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -120,6 +120,7 @@ module ts { return visitNodes(cbNodes, (node).properties); case SyntaxKind.PropertyAccessExpression: return visitNode(cbNode, (node).expression) || + visitNode(cbNode, (node).dotToken) || visitNode(cbNode, (node).name); case SyntaxKind.ElementAccessExpression: return visitNode(cbNode, (node).expression) || @@ -1326,13 +1327,16 @@ module ts { function parseOptionalToken(t: SyntaxKind): Node { if (token === t) { - var node = createNode(t); - nextToken(); - return finishNode(node); + return parseTokenNode(); } return undefined; } + function parseExpectedToken(t: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node { + return parseOptionalToken(t) || + createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0); + } + function parseTokenNode(): T { var node = createNode(token); nextToken(); @@ -2150,8 +2154,7 @@ module ts { literal = parseLiteralNode(); } else { - literal = createMissingNode( - SyntaxKind.TemplateTail, /*reportAtCurrentPosition:*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); + literal = parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition:*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); } span.literal = literal; @@ -3446,7 +3449,7 @@ module ts { // If it wasn't then just try to parse out a '.' and report an error. var node = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); node.expression = expression; - parseExpected(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); + node.dotToken = parseExpectedToken(SyntaxKind.DotToken, /*reportAtCurrentPosition:*/ false, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); node.name = parseRightSideOfDot(/*allowIdentifierNames:*/ true); return finishNode(node); } @@ -3462,10 +3465,11 @@ module ts { function parseMemberExpressionRest(expression: LeftHandSideExpression): MemberExpression { while (true) { - var dotOrBracketStart = scanner.getTokenPos(); - if (parseOptional(SyntaxKind.DotToken)) { + var dotToken = parseOptionalToken(SyntaxKind.DotToken); + if (dotToken) { var propertyAccess = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); propertyAccess.expression = expression; + propertyAccess.dotToken = dotToken; propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames:*/ true); expression = finishNode(propertyAccess); continue; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c7339bcd60d..97706ac324b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -693,6 +693,7 @@ module ts { export interface PropertyAccessExpression extends MemberExpression { expression: LeftHandSideExpression; + dotToken: Node; name: Identifier; } diff --git a/tests/baselines/reference/APISample_compile.js b/tests/baselines/reference/APISample_compile.js index 30fe1d09060..f10e9c9030c 100644 --- a/tests/baselines/reference/APISample_compile.js +++ b/tests/baselines/reference/APISample_compile.js @@ -579,6 +579,7 @@ declare module "typescript" { } interface PropertyAccessExpression extends MemberExpression { expression: LeftHandSideExpression; + dotToken: Node; name: Identifier; } interface ElementAccessExpression extends MemberExpression { diff --git a/tests/baselines/reference/APISample_compile.types b/tests/baselines/reference/APISample_compile.types index 81b98949c7b..1365a0e903b 100644 --- a/tests/baselines/reference/APISample_compile.types +++ b/tests/baselines/reference/APISample_compile.types @@ -1743,6 +1743,10 @@ declare module "typescript" { >expression : LeftHandSideExpression >LeftHandSideExpression : LeftHandSideExpression + dotToken: Node; +>dotToken : Node +>Node : Node + name: Identifier; >name : Identifier >Identifier : Identifier diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index b7a67081440..3e8c579a051 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -610,6 +610,7 @@ declare module "typescript" { } interface PropertyAccessExpression extends MemberExpression { expression: LeftHandSideExpression; + dotToken: Node; name: Identifier; } interface ElementAccessExpression extends MemberExpression { diff --git a/tests/baselines/reference/APISample_linter.types b/tests/baselines/reference/APISample_linter.types index 6da030e8617..0f428ecdec2 100644 --- a/tests/baselines/reference/APISample_linter.types +++ b/tests/baselines/reference/APISample_linter.types @@ -1889,6 +1889,10 @@ declare module "typescript" { >expression : LeftHandSideExpression >LeftHandSideExpression : LeftHandSideExpression + dotToken: Node; +>dotToken : Node +>Node : Node + name: Identifier; >name : Identifier >Identifier : Identifier diff --git a/tests/baselines/reference/APISample_transform.js b/tests/baselines/reference/APISample_transform.js index c30d4f03456..4cd5c5c0983 100644 --- a/tests/baselines/reference/APISample_transform.js +++ b/tests/baselines/reference/APISample_transform.js @@ -611,6 +611,7 @@ declare module "typescript" { } interface PropertyAccessExpression extends MemberExpression { expression: LeftHandSideExpression; + dotToken: Node; name: Identifier; } interface ElementAccessExpression extends MemberExpression { diff --git a/tests/baselines/reference/APISample_transform.types b/tests/baselines/reference/APISample_transform.types index 42862def15f..b78b0565a45 100644 --- a/tests/baselines/reference/APISample_transform.types +++ b/tests/baselines/reference/APISample_transform.types @@ -1839,6 +1839,10 @@ declare module "typescript" { >expression : LeftHandSideExpression >LeftHandSideExpression : LeftHandSideExpression + dotToken: Node; +>dotToken : Node +>Node : Node + name: Identifier; >name : Identifier >Identifier : Identifier diff --git a/tests/baselines/reference/APISample_watcher.js b/tests/baselines/reference/APISample_watcher.js index a9ed17e924d..139af5b7cd2 100644 --- a/tests/baselines/reference/APISample_watcher.js +++ b/tests/baselines/reference/APISample_watcher.js @@ -648,6 +648,7 @@ declare module "typescript" { } interface PropertyAccessExpression extends MemberExpression { expression: LeftHandSideExpression; + dotToken: Node; name: Identifier; } interface ElementAccessExpression extends MemberExpression { @@ -2108,7 +2109,9 @@ function watch(rootFileNames, options) { }); } function logErrors(fileName) { - var allDiagnostics = services.getCompilerOptionsDiagnostics().concat(services.getSyntacticDiagnostics(fileName)).concat(services.getSemanticDiagnostics(fileName)); + var allDiagnostics = services.getCompilerOptionsDiagnostics() + .concat(services.getSyntacticDiagnostics(fileName)) + .concat(services.getSemanticDiagnostics(fileName)); allDiagnostics.forEach(function (diagnostic) { if (diagnostic.file) { var lineChar = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); @@ -2121,6 +2124,7 @@ function watch(rootFileNames, options) { } } // Initialize files constituting the program as all .ts files in the current directory -var currentDirectoryFiles = fs.readdirSync(process.cwd()).filter(function (fileName) { return fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts"; }); +var currentDirectoryFiles = fs.readdirSync(process.cwd()). + filter(function (fileName) { return fileName.length >= 3 && fileName.substr(fileName.length - 3, 3) === ".ts"; }); // Start the watcher watch(currentDirectoryFiles, { module: 1 /* CommonJS */ }); diff --git a/tests/baselines/reference/APISample_watcher.types b/tests/baselines/reference/APISample_watcher.types index 3dd324c421e..5570c9ff12a 100644 --- a/tests/baselines/reference/APISample_watcher.types +++ b/tests/baselines/reference/APISample_watcher.types @@ -2012,6 +2012,10 @@ declare module "typescript" { >expression : LeftHandSideExpression >LeftHandSideExpression : LeftHandSideExpression + dotToken: Node; +>dotToken : Node +>Node : Node + name: Identifier; >name : Identifier >Identifier : Identifier diff --git a/tests/baselines/reference/arrayConcatMap.js b/tests/baselines/reference/arrayConcatMap.js index dc7272b7223..715ca158a43 100644 --- a/tests/baselines/reference/arrayConcatMap.js +++ b/tests/baselines/reference/arrayConcatMap.js @@ -3,4 +3,5 @@ var x = [].concat([{ a: 1 }], [{ a: 2 }]) .map(b => b.a); //// [arrayConcatMap.js] -var x = [].concat([{ a: 1 }], [{ a: 2 }]).map(function (b) { return b.a; }); +var x = [].concat([{ a: 1 }], [{ a: 2 }]) + .map(function (b) { return b.a; }); diff --git a/tests/baselines/reference/enumConflictsWithGlobalIdentifier.js b/tests/baselines/reference/enumConflictsWithGlobalIdentifier.js index 67d9a020bb6..a0a6afb172f 100644 --- a/tests/baselines/reference/enumConflictsWithGlobalIdentifier.js +++ b/tests/baselines/reference/enumConflictsWithGlobalIdentifier.js @@ -11,5 +11,6 @@ var Position; (function (Position) { Position[Position["IgnoreRulesSpecific"] = 0] = "IgnoreRulesSpecific"; })(Position || (Position = {})); -var x = IgnoreRulesSpecific.; +var x = IgnoreRulesSpecific. +; var y = 0 /* IgnoreRulesSpecific */; diff --git a/tests/baselines/reference/enumMemberResolution.js b/tests/baselines/reference/enumMemberResolution.js index e1d79ebeb92..ebfcac3a59e 100644 --- a/tests/baselines/reference/enumMemberResolution.js +++ b/tests/baselines/reference/enumMemberResolution.js @@ -12,6 +12,7 @@ var Position2; (function (Position2) { Position2[Position2["IgnoreRulesSpecific"] = 0] = "IgnoreRulesSpecific"; })(Position2 || (Position2 = {})); -var x = IgnoreRulesSpecific.; // error +var x = IgnoreRulesSpecific. +; // error var y = 1; var z = 0 /* IgnoreRulesSpecific */; // no error diff --git a/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.js b/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.js index ae8e7d9c918..592a03d7158 100644 --- a/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.js +++ b/tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.js @@ -228,7 +228,8 @@ var C = (function () { // Not fine, since we can *only* consist of a single throw statement // if no return statements are present but we are a get accessor. throw null; - throw undefined.; + throw undefined. + ; }, enumerable: true, configurable: true diff --git a/tests/baselines/reference/genericChainedCalls.js b/tests/baselines/reference/genericChainedCalls.js index 71d83a906bf..a738e19023b 100644 --- a/tests/baselines/reference/genericChainedCalls.js +++ b/tests/baselines/reference/genericChainedCalls.js @@ -15,8 +15,9 @@ var s3 = s2.func(num => num.toString()) //// [genericChainedCalls.js] -var r1 = v1.func(function (num) { return num.toString(); }).func(function (str) { return str.length; }) // error, number doesn't have a length -.func(function (num) { return num.toString(); }); +var r1 = v1.func(function (num) { return num.toString(); }) + .func(function (str) { return str.length; }) // error, number doesn't have a length + .func(function (num) { return num.toString(); }); var s1 = v1.func(function (num) { return num.toString(); }); var s2 = s1.func(function (str) { return str.length; }); // should also error var s3 = s2.func(function (num) { return num.toString(); }); diff --git a/tests/baselines/reference/overEagerReturnTypeSpecialization.js b/tests/baselines/reference/overEagerReturnTypeSpecialization.js index 67d2005eca9..90fcc388b76 100644 --- a/tests/baselines/reference/overEagerReturnTypeSpecialization.js +++ b/tests/baselines/reference/overEagerReturnTypeSpecialization.js @@ -17,6 +17,6 @@ var r2: I1 = v1.func(num => num.toString()) // Correctly returns an I1 -.func(function (str) { return str.length; }); // should error + .func(function (str) { return str.length; }); // should error var r2 = v1.func(function (num) { return num.toString(); }) // Correctly returns an I1 -.func(function (str) { return str.length; }); // should be ok + .func(function (str) { return str.length; }); // should be ok diff --git a/tests/baselines/reference/parse1.js b/tests/baselines/reference/parse1.js index 08af81bda17..4804e31adcd 100644 --- a/tests/baselines/reference/parse1.js +++ b/tests/baselines/reference/parse1.js @@ -8,5 +8,6 @@ function foo() { //// [parse1.js] var bar = 42; function foo() { - bar.; + bar. + ; } diff --git a/tests/baselines/reference/parser509667.js b/tests/baselines/reference/parser509667.js index 21e0bc55ce4..0938613b295 100644 --- a/tests/baselines/reference/parser509667.js +++ b/tests/baselines/reference/parser509667.js @@ -16,7 +16,8 @@ var Foo = (function () { function Foo() { } Foo.prototype.f1 = function () { - if (this.) + if (this. + ) ; }; Foo.prototype.f2 = function () { diff --git a/tests/baselines/reference/underscoreTest1.js b/tests/baselines/reference/underscoreTest1.js index a4fa2cbc65d..ddd5201b858 100644 --- a/tests/baselines/reference/underscoreTest1.js +++ b/tests/baselines/reference/underscoreTest1.js @@ -1018,7 +1018,11 @@ _.omit({ name: 'moe', age: 50, userid: 'moe1' }, 'userid'); var iceCream = { flavor: "chocolate" }; _.defaults(iceCream, { flavor: "vanilla", sprinkles: "lots" }); _.clone({ name: 'moe' }); -_.chain([1, 2, 3, 200]).filter(function (num) { return num % 2 == 0; }).tap(alert).map(function (num) { return num * num; }).value(); +_.chain([1, 2, 3, 200]) + .filter(function (num) { return num % 2 == 0; }) + .tap(alert) + .map(function (num) { return num * num; }) + .value(); _.has({ a: 1, b: 2, c: 3 }, "b"); var moe = { name: 'moe', luckyNumbers: [13, 27, 34] }; var clone = { name: 'moe', luckyNumbers: [13, 27, 34] }; diff --git a/tests/baselines/reference/wrappedIncovations1.js b/tests/baselines/reference/wrappedIncovations1.js new file mode 100644 index 00000000000..b9e5ed688f9 --- /dev/null +++ b/tests/baselines/reference/wrappedIncovations1.js @@ -0,0 +1,11 @@ +//// [wrappedIncovations1.ts] +var v = this + .foo() + .bar() + .baz(); + +//// [wrappedIncovations1.js] +var v = this + .foo() + .bar() + .baz(); diff --git a/tests/baselines/reference/wrappedIncovations1.types b/tests/baselines/reference/wrappedIncovations1.types new file mode 100644 index 00000000000..32f7bb0e1b8 --- /dev/null +++ b/tests/baselines/reference/wrappedIncovations1.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/wrappedIncovations1.ts === +var v = this +>v : any +>this .foo() .bar() .baz() : any +>this .foo() .bar() .baz : any +>this .foo() .bar() : any +>this .foo() .bar : any +>this .foo() : any +>this .foo : any +>this : any + + .foo() +>foo : any + + .bar() +>bar : any + + .baz(); +>baz : any + diff --git a/tests/baselines/reference/wrappedIncovations2.js b/tests/baselines/reference/wrappedIncovations2.js new file mode 100644 index 00000000000..09951996c94 --- /dev/null +++ b/tests/baselines/reference/wrappedIncovations2.js @@ -0,0 +1,11 @@ +//// [wrappedIncovations2.ts] +var v = this. + foo(). + bar(). + baz(); + +//// [wrappedIncovations2.js] +var v = this. + foo(). + bar(). + baz(); diff --git a/tests/baselines/reference/wrappedIncovations2.types b/tests/baselines/reference/wrappedIncovations2.types new file mode 100644 index 00000000000..96337796bcd --- /dev/null +++ b/tests/baselines/reference/wrappedIncovations2.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/wrappedIncovations2.ts === +var v = this. +>v : any +>this. foo(). bar(). baz() : any +>this. foo(). bar(). baz : any +>this. foo(). bar() : any +>this. foo(). bar : any +>this. foo() : any +>this. foo : any +>this : any + + foo(). +>foo : any + + bar(). +>bar : any + + baz(); +>baz : any + diff --git a/tests/cases/compiler/wrappedIncovations1.ts b/tests/cases/compiler/wrappedIncovations1.ts new file mode 100644 index 00000000000..2c8ee00fe0e --- /dev/null +++ b/tests/cases/compiler/wrappedIncovations1.ts @@ -0,0 +1,4 @@ +var v = this + .foo() + .bar() + .baz(); \ No newline at end of file diff --git a/tests/cases/compiler/wrappedIncovations2.ts b/tests/cases/compiler/wrappedIncovations2.ts new file mode 100644 index 00000000000..eba99b425e4 --- /dev/null +++ b/tests/cases/compiler/wrappedIncovations2.ts @@ -0,0 +1,4 @@ +var v = this. + foo(). + bar(). + baz(); \ No newline at end of file diff --git a/tests/cases/unittests/incrementalParser.ts b/tests/cases/unittests/incrementalParser.ts index 54adcaf345f..e785f1cdf00 100644 --- a/tests/cases/unittests/incrementalParser.ts +++ b/tests/cases/unittests/incrementalParser.ts @@ -664,7 +664,7 @@ module m3 { }\ var oldText = ScriptSnapshot.fromString(source); var newTextAndChange = withInsert(oldText, 0, ""); - compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 7); + compareTrees(oldText, newTextAndChange.text, newTextAndChange.textChangeRange, 8); }); it('Class to interface',() => { From 680e48f507e38c3be58952b255f9a8201ea37bb3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 7 Mar 2015 12:54:12 -0800 Subject: [PATCH 2/4] Preserve newlines on either side of a binary expression. --- src/compiler/emitter.ts | 34 +++++++++++++++---- .../reference/APISample_transform.js | 3 +- tests/baselines/reference/asiArith.js | 8 ++--- ...constructorWithIncompleteTypeAnnotation.js | 3 +- .../parserGreaterThanTokenAmbiguity10.js | 4 +-- .../parserGreaterThanTokenAmbiguity15.js | 4 +-- .../parserGreaterThanTokenAmbiguity20.js | 4 +-- .../parserGreaterThanTokenAmbiguity4.js | 2 +- .../parserGreaterThanTokenAmbiguity5.js | 4 +-- .../parserGreaterThanTokenAmbiguity9.js | 2 +- ...parserRegularExpressionDivideAmbiguity1.js | 3 +- .../typeGuardsInConditionalExpression.js | 11 +++--- ...ypeGuardsInRightOperandOfAndAndOperator.js | 28 ++++++++------- .../typeGuardsInRightOperandOfOrOrOperator.js | 28 ++++++++------- 14 files changed, 83 insertions(+), 55 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a0c887414cd..9cdcfeef09d 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3290,26 +3290,46 @@ module ts { else { emit(node.left); - if (node.operatorToken.kind !== SyntaxKind.CommaToken) { - write(" "); + // If there was a newline between the left side of the binary expression and the + // operator, then try to preserve that. + var indented = false; + var isSynthesied = nodeIsSynthesized(node); + if (!isSynthesied && !nodeEndIsOnSameLineAsNodeStart(node.left, node.operatorToken)) { + indented = true; + increaseIndent(); + writeLine(); + } + else { + // Otherwise just emit the operator right afterwards. For everything but + // comma, emit a space before the operator. + if (node.operatorToken.kind !== SyntaxKind.CommaToken) { + write(" "); + } } write(tokenToString(node.operatorToken.kind)); - var shouldPlaceOnNewLine = !nodeIsSynthesized(node) && !nodeEndIsOnSameLineAsNodeStart(node.operatorToken, node.right); + // If there was a newline after the operator (or this is a synthesized node that + // wants to be on a new line), then put a newline in. But only if we haven't + // already done this for the left side. + var wantsIndent = (!isSynthesied && !nodeEndIsOnSameLineAsNodeStart(node.operatorToken, node.right)) || + synthesizedNodeStartsOnNewLine(node.right); - // Check if the right expression is on a different line versus the operator itself. If so, - // we'll emit newline. - if (shouldPlaceOnNewLine || synthesizedNodeStartsOnNewLine(node.right)) { + if (wantsIndent && !indented) { + indented = true; increaseIndent(); writeLine(); emit(node.right); - decreaseIndent(); } else { write(" "); emit(node.right); } + + // If we indented the left or the right side, then dedent now. + if (indented) { + decreaseIndent(); + } } } diff --git a/tests/baselines/reference/APISample_transform.js b/tests/baselines/reference/APISample_transform.js index 4cd5c5c0983..27e04bec1a0 100644 --- a/tests/baselines/reference/APISample_transform.js +++ b/tests/baselines/reference/APISample_transform.js @@ -2052,7 +2052,8 @@ function transform(contents, compilerOptions) { return { outputs: outputs, errors: errors.map(function (e) { - return e.file.fileName + "(" + (e.file.getLineAndCharacterOfPosition(e.start).line + 1) + "): " + ts.flattenDiagnosticMessageText(e.messageText, os.EOL); + return e.file.fileName + "(" + (e.file.getLineAndCharacterOfPosition(e.start).line + 1) + "): " + + ts.flattenDiagnosticMessageText(e.messageText, os.EOL); }) }; } diff --git a/tests/baselines/reference/asiArith.js b/tests/baselines/reference/asiArith.js index 8e957aae332..b5016af3117 100644 --- a/tests/baselines/reference/asiArith.js +++ b/tests/baselines/reference/asiArith.js @@ -37,9 +37,9 @@ y //// [asiArith.js] var x = 1; var y = 1; -var z = x + - + +y; +var z = x + + + +y; var a = 1; var b = 1; -var c = x - - - -y; +var c = x + - - -y; diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js index ac77cc177b8..6adbaddb117 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js @@ -314,8 +314,7 @@ var TypeScriptAllInOne; Program.prototype.if = function (retValue) { if (retValue === void 0) { retValue = != 0; } return 1; - ^ - retValue; + ^ retValue; bfs.TYPES(); if (retValue != 0) { return 1 && diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js index a558407de43..64e142d7095 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity10.js @@ -5,5 +5,5 @@ 2; //// [parserGreaterThanTokenAmbiguity10.js] -1 >>> - 2; +1 + >>> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js index 83f2cda2364..7b44da35688 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity15.js @@ -5,5 +5,5 @@ 2; //// [parserGreaterThanTokenAmbiguity15.js] -1 >>= - 2; +1 + >>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js index 9ac06e9644f..7a3650fdfd5 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity20.js @@ -5,5 +5,5 @@ 2; //// [parserGreaterThanTokenAmbiguity20.js] -1 >>>= - 2; +1 + >>>= 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity4.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity4.js index c0b8fc45cc1..dcfb51575e4 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity4.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity4.js @@ -4,4 +4,4 @@ //// [parserGreaterThanTokenAmbiguity4.js] 1 > - > 2; + > 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js index cde18d5c63d..baa3af48e9d 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity5.js @@ -5,5 +5,5 @@ 2; //// [parserGreaterThanTokenAmbiguity5.js] -1 >> - 2; +1 + >> 2; diff --git a/tests/baselines/reference/parserGreaterThanTokenAmbiguity9.js b/tests/baselines/reference/parserGreaterThanTokenAmbiguity9.js index 757ddf38a7f..96be8d0749c 100644 --- a/tests/baselines/reference/parserGreaterThanTokenAmbiguity9.js +++ b/tests/baselines/reference/parserGreaterThanTokenAmbiguity9.js @@ -4,4 +4,4 @@ //// [parserGreaterThanTokenAmbiguity9.js] 1 >> - > 2; + > 2; diff --git a/tests/baselines/reference/parserRegularExpressionDivideAmbiguity1.js b/tests/baselines/reference/parserRegularExpressionDivideAmbiguity1.js index 79e0c04d409..c3e61545c2c 100644 --- a/tests/baselines/reference/parserRegularExpressionDivideAmbiguity1.js +++ b/tests/baselines/reference/parserRegularExpressionDivideAmbiguity1.js @@ -3,4 +3,5 @@ /notregexp/a.foo(); //// [parserRegularExpressionDivideAmbiguity1.js] -1 / notregexp / a.foo(); +1 + / notregexp / a.foo(); diff --git a/tests/baselines/reference/typeGuardsInConditionalExpression.js b/tests/baselines/reference/typeGuardsInConditionalExpression.js index 7c87d80d592..a1a546a193e 100644 --- a/tests/baselines/reference/typeGuardsInConditionalExpression.js +++ b/tests/baselines/reference/typeGuardsInConditionalExpression.js @@ -157,7 +157,8 @@ function foo10(x) { var b; return typeof x === "string" ? x // string : ((b = x) // x is number | boolean - && typeof x === "number" && x.toString()); // x is number + && typeof x === "number" + && x.toString()); // x is number } function foo11(x) { // Mixing typeguards @@ -165,8 +166,9 @@ function foo11(x) { var b; return typeof x === "string" ? x // number | boolean | string - changed in the false branch : ((b = x) // x is number | boolean | string - because the assignment changed it - && typeof x === "number" && (x = 10) // assignment to x - && x); // x is number | boolean | string + && typeof x === "number" + && (x = 10) // assignment to x + && x); // x is number | boolean | string } function foo12(x) { // Mixing typeguards @@ -174,5 +176,6 @@ function foo12(x) { var b; return typeof x === "string" ? (x = 10 && x.toString().length) // number | boolean | string - changed here : ((b = x) // x is number | boolean | string - changed in true branch - && typeof x === "number" && x); // x is number + && typeof x === "number" + && x); // x is number } diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js index ffba829c37d..23ee7b29f51 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js @@ -72,36 +72,38 @@ function foo3(x) { } function foo4(x) { return typeof x !== "string" // string | number | boolean - && typeof x !== "number" // number | boolean - && x; // boolean + && typeof x !== "number" // number | boolean + && x; // boolean } function foo5(x) { // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop var b; return typeof x !== "string" // string | number | boolean - && ((b = x) && (typeof x !== "number" // number | boolean - && x)); // boolean + && ((b = x) && (typeof x !== "number" // number | boolean + && x)); // boolean } function foo6(x) { // Mixing typeguard narrowing in if statement with conditional expression typeguard return typeof x !== "string" // string | number | boolean - && (typeof x !== "number" // number | boolean - ? x // boolean - : x === 10); // number + && (typeof x !== "number" // number | boolean + ? x // boolean + : x === 10); // number } function foo7(x) { var y; var z; // Mixing typeguard narrowing // Assigning value to x deep inside another guard stops narrowing of type too - return typeof x !== "string" && ((z = x) // string | number | boolean - x changed deeper in conditional expression - && (typeof x === "number" ? (x = 10 && x.toString()) // number | boolean | string - : (y = x && x.toString()))); // number | boolean | string + return typeof x !== "string" + && ((z = x) // string | number | boolean - x changed deeper in conditional expression + && (typeof x === "number" ? (x = 10 && x.toString()) // number | boolean | string + : (y = x && x.toString()))); // number | boolean | string } function foo8(x) { // Mixing typeguard // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x !== "string" && (x = 10) // change x - number| string - && (typeof x === "number" ? x // number - : x.length); // string + return typeof x !== "string" + && (x = 10) // change x - number| string + && (typeof x === "number" ? x // number + : x.length); // string } diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js index 5f5880a4947..13bb090ab8c 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js @@ -72,36 +72,38 @@ function foo3(x) { } function foo4(x) { return typeof x === "string" // string | number | boolean - || typeof x === "number" // number | boolean - || x; // boolean + || typeof x === "number" // number | boolean + || x; // boolean } function foo5(x) { // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop var b; return typeof x === "string" // string | number | boolean - || ((b = x) || (typeof x === "number" // number | boolean - || x)); // boolean + || ((b = x) || (typeof x === "number" // number | boolean + || x)); // boolean } function foo6(x) { // Mixing typeguard return typeof x === "string" // string | number | boolean - || (typeof x !== "number" // number | boolean - ? x // boolean - : x === 10); // number + || (typeof x !== "number" // number | boolean + ? x // boolean + : x === 10); // number } function foo7(x) { var y; var z; // Mixing typeguard narrowing // Assigning value to x deep inside another guard stops narrowing of type too - return typeof x === "string" || ((z = x) // string | number | boolean - x changed deeper in conditional expression - || (typeof x === "number" ? (x = 10 && x.toString()) // number | boolean | string - : (y = x && x.toString()))); // number | boolean | string + return typeof x === "string" + || ((z = x) // string | number | boolean - x changed deeper in conditional expression + || (typeof x === "number" ? (x = 10 && x.toString()) // number | boolean | string + : (y = x && x.toString()))); // number | boolean | string } function foo8(x) { // Mixing typeguard // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x === "string" || (x = 10) // change x - number| string - || (typeof x === "number" ? x // number - : x.length); // string + return typeof x === "string" + || (x = 10) // change x - number| string + || (typeof x === "number" ? x // number + : x.length); // string } From dddc4660a1134e1d6fdafff6814efa469c34d205 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 7 Mar 2015 13:33:02 -0800 Subject: [PATCH 3/4] Simplify code to emit indent code. --- src/compiler/emitter.ts | 74 ++++++++----------- src/compiler/parser.ts | 9 ++- src/compiler/types.ts | 2 + .../baselines/reference/APISample_compile.js | 2 + .../reference/APISample_compile.types | 8 ++ tests/baselines/reference/APISample_linter.js | 2 + .../reference/APISample_linter.types | 8 ++ .../reference/APISample_transform.js | 2 + .../reference/APISample_transform.types | 8 ++ .../baselines/reference/APISample_watcher.js | 2 + .../reference/APISample_watcher.types | 8 ++ 11 files changed, 80 insertions(+), 45 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9cdcfeef09d..154b0874548 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2917,6 +2917,7 @@ module ts { function createPropertyAccessExpression(expression: LeftHandSideExpression, name: Identifier): PropertyAccessExpression { var result = createSynthesizedNode(SyntaxKind.PropertyAccessExpression); result.expression = expression; + result.dotToken = createSynthesizedNode(SyntaxKind.DotToken); result.name = name; return result; @@ -3032,6 +3033,20 @@ module ts { return false; } + function indentIfOnDifferentLines(parent: Node, node1: Node, node2: Node) { + var isSynthesized = nodeIsSynthesized(parent); + + var realNodesAreOnDifferentLines = !isSynthesized && !nodeEndIsOnSameLineAsNodeStart(node1, node2); + var synthesizedNodeIsOnDifferentLine = synthesizedNodeStartsOnNewLine(node2); + if (realNodesAreOnDifferentLines || synthesizedNodeIsOnDifferentLine) { + increaseIndent(); + writeLine(); + return true; + } + + return false; + } + function emitPropertyAccess(node: PropertyAccessExpression) { if (tryEmitConstantValue(node)) { return; @@ -3039,21 +3054,11 @@ module ts { emit(node.expression); - var indented = false; - var isSynthesied = nodeIsSynthesized(node); - if (!isSynthesied && !nodeEndIsOnSameLineAsNodeStart(node.expression, node.dotToken)) { - indented = true; - increaseIndent(); - writeLine(); - } + var indented = indentIfOnDifferentLines(node, node.expression, node.dotToken); write("."); - if (!isSynthesied && !nodeEndIsOnSameLineAsNodeStart(node.dotToken, node.name) && !indented) { - indented = true; - increaseIndent(); - writeLine(); - } + indented = indented || indentIfOnDifferentLines(node, node.dotToken, node.name); emit(node.name); @@ -3292,42 +3297,28 @@ module ts { // If there was a newline between the left side of the binary expression and the // operator, then try to preserve that. - var indented = false; - var isSynthesied = nodeIsSynthesized(node); - if (!isSynthesied && !nodeEndIsOnSameLineAsNodeStart(node.left, node.operatorToken)) { - indented = true; - increaseIndent(); - writeLine(); - } - else { - // Otherwise just emit the operator right afterwards. For everything but - // comma, emit a space before the operator. - if (node.operatorToken.kind !== SyntaxKind.CommaToken) { - write(" "); - } + var indented1 = indentIfOnDifferentLines(node, node.left, node.operatorToken); + + // Otherwise just emit the operator right afterwards. For everything but + // comma, emit a space before the operator. + if (!indented1 && node.operatorToken.kind !== SyntaxKind.CommaToken) { + write(" "); } write(tokenToString(node.operatorToken.kind)); - // If there was a newline after the operator (or this is a synthesized node that - // wants to be on a new line), then put a newline in. But only if we haven't - // already done this for the left side. - var wantsIndent = (!isSynthesied && !nodeEndIsOnSameLineAsNodeStart(node.operatorToken, node.right)) || - synthesizedNodeStartsOnNewLine(node.right); + if (!indented1) { + var indented2 = indentIfOnDifferentLines(node, node.operatorToken, node.right); + } - if (wantsIndent && !indented) { - indented = true; - increaseIndent(); - writeLine(); - emit(node.right); - } - else { + if (!indented2) { write(" "); - emit(node.right); } + emit(node.right); + // If we indented the left or the right side, then dedent now. - if (indented) { + if (indented1 || indented2) { decreaseIndent(); } } @@ -3741,10 +3732,7 @@ module ts { if (propName.kind !== SyntaxKind.Identifier) { return createElementAccess(object, propName); } - var node = createSynthesizedNode(SyntaxKind.PropertyAccessExpression); - node.expression = parenthesizeForAccess(object); - node.name = propName; - return node; + return createPropertyAccessExpression(parenthesizeForAccess(object), propName); } function createElementAccess(object: Expression, index: Expression): Expression { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 557d6505984..3b3a2ddeda9 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -157,7 +157,9 @@ module ts { visitNode(cbNode, (node).right); case SyntaxKind.ConditionalExpression: return visitNode(cbNode, (node).condition) || + visitNode(cbNode, (node).questionToken) || visitNode(cbNode, (node).whenTrue) || + visitNode(cbNode, (node).colonToken) || visitNode(cbNode, (node).whenFalse); case SyntaxKind.SpreadElementExpression: return visitNode(cbNode, (node).expression); @@ -3177,7 +3179,8 @@ module ts { function parseConditionalExpressionRest(leftOperand: Expression): Expression { // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. - if (!parseOptional(SyntaxKind.QuestionToken)) { + var questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + if (!questionToken) { return leftOperand; } @@ -3185,8 +3188,10 @@ module ts { // we do not that for the 'whenFalse' part. var node = createNode(SyntaxKind.ConditionalExpression, leftOperand.pos); node.condition = leftOperand; + node.questionToken = questionToken; node.whenTrue = allowInAnd(parseAssignmentExpressionOrHigher); - parseExpected(SyntaxKind.ColonToken); + node.colonToken = parseExpectedToken(SyntaxKind.ColonToken, /*reportAtCurrentPosition:*/ false, + Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); node.whenFalse = parseAssignmentExpressionOrHigher(); return finishNode(node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 97706ac324b..e4132655f38 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -640,7 +640,9 @@ module ts { export interface ConditionalExpression extends Expression { condition: Expression; + questionToken: Node; whenTrue: Expression; + colonToken: Node; whenFalse: Expression; } diff --git a/tests/baselines/reference/APISample_compile.js b/tests/baselines/reference/APISample_compile.js index f10e9c9030c..88add2f8685 100644 --- a/tests/baselines/reference/APISample_compile.js +++ b/tests/baselines/reference/APISample_compile.js @@ -542,7 +542,9 @@ declare module "typescript" { } interface ConditionalExpression extends Expression { condition: Expression; + questionToken: Node; whenTrue: Expression; + colonToken: Node; whenFalse: Expression; } interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration { diff --git a/tests/baselines/reference/APISample_compile.types b/tests/baselines/reference/APISample_compile.types index 1365a0e903b..7715fd36c77 100644 --- a/tests/baselines/reference/APISample_compile.types +++ b/tests/baselines/reference/APISample_compile.types @@ -1633,10 +1633,18 @@ declare module "typescript" { >condition : Expression >Expression : Expression + questionToken: Node; +>questionToken : Node +>Node : Node + whenTrue: Expression; >whenTrue : Expression >Expression : Expression + colonToken: Node; +>colonToken : Node +>Node : Node + whenFalse: Expression; >whenFalse : Expression >Expression : Expression diff --git a/tests/baselines/reference/APISample_linter.js b/tests/baselines/reference/APISample_linter.js index 3e8c579a051..c8845aab968 100644 --- a/tests/baselines/reference/APISample_linter.js +++ b/tests/baselines/reference/APISample_linter.js @@ -573,7 +573,9 @@ declare module "typescript" { } interface ConditionalExpression extends Expression { condition: Expression; + questionToken: Node; whenTrue: Expression; + colonToken: Node; whenFalse: Expression; } interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration { diff --git a/tests/baselines/reference/APISample_linter.types b/tests/baselines/reference/APISample_linter.types index 0f428ecdec2..a0550e967a1 100644 --- a/tests/baselines/reference/APISample_linter.types +++ b/tests/baselines/reference/APISample_linter.types @@ -1779,10 +1779,18 @@ declare module "typescript" { >condition : Expression >Expression : Expression + questionToken: Node; +>questionToken : Node +>Node : Node + whenTrue: Expression; >whenTrue : Expression >Expression : Expression + colonToken: Node; +>colonToken : Node +>Node : Node + whenFalse: Expression; >whenFalse : Expression >Expression : Expression diff --git a/tests/baselines/reference/APISample_transform.js b/tests/baselines/reference/APISample_transform.js index 27e04bec1a0..9c0777413a0 100644 --- a/tests/baselines/reference/APISample_transform.js +++ b/tests/baselines/reference/APISample_transform.js @@ -574,7 +574,9 @@ declare module "typescript" { } interface ConditionalExpression extends Expression { condition: Expression; + questionToken: Node; whenTrue: Expression; + colonToken: Node; whenFalse: Expression; } interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration { diff --git a/tests/baselines/reference/APISample_transform.types b/tests/baselines/reference/APISample_transform.types index b78b0565a45..4803a94f39b 100644 --- a/tests/baselines/reference/APISample_transform.types +++ b/tests/baselines/reference/APISample_transform.types @@ -1729,10 +1729,18 @@ declare module "typescript" { >condition : Expression >Expression : Expression + questionToken: Node; +>questionToken : Node +>Node : Node + whenTrue: Expression; >whenTrue : Expression >Expression : Expression + colonToken: Node; +>colonToken : Node +>Node : Node + whenFalse: Expression; >whenFalse : Expression >Expression : Expression diff --git a/tests/baselines/reference/APISample_watcher.js b/tests/baselines/reference/APISample_watcher.js index 139af5b7cd2..2426c0544d9 100644 --- a/tests/baselines/reference/APISample_watcher.js +++ b/tests/baselines/reference/APISample_watcher.js @@ -611,7 +611,9 @@ declare module "typescript" { } interface ConditionalExpression extends Expression { condition: Expression; + questionToken: Node; whenTrue: Expression; + colonToken: Node; whenFalse: Expression; } interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration { diff --git a/tests/baselines/reference/APISample_watcher.types b/tests/baselines/reference/APISample_watcher.types index 5570c9ff12a..8cb082050fa 100644 --- a/tests/baselines/reference/APISample_watcher.types +++ b/tests/baselines/reference/APISample_watcher.types @@ -1902,10 +1902,18 @@ declare module "typescript" { >condition : Expression >Expression : Expression + questionToken: Node; +>questionToken : Node +>Node : Node + whenTrue: Expression; >whenTrue : Expression >Expression : Expression + colonToken: Node; +>colonToken : Node +>Node : Node + whenFalse: Expression; >whenFalse : Expression >Expression : Expression From 2a990a8685b85ac068a3c4541df5e804fa2388e9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 7 Mar 2015 13:50:26 -0800 Subject: [PATCH 4/4] Preserve newlines for conditional expressions --- src/compiler/emitter.ts | 51 ++++++++++-- .../reference/APISample_transform.js | 3 +- .../conditionalExpressionNewLine1.errors.txt | 13 +++ .../conditionalExpressionNewLine1.js | 5 ++ .../conditionalExpressionNewLine10.errors.txt | 31 +++++++ .../conditionalExpressionNewLine10.js | 17 ++++ .../conditionalExpressionNewLine2.errors.txt | 14 ++++ .../conditionalExpressionNewLine2.js | 7 ++ .../conditionalExpressionNewLine3.errors.txt | 14 ++++ .../conditionalExpressionNewLine3.js | 7 ++ .../conditionalExpressionNewLine4.errors.txt | 14 ++++ .../conditionalExpressionNewLine4.js | 7 ++ .../conditionalExpressionNewLine5.errors.txt | 14 ++++ .../conditionalExpressionNewLine5.js | 7 ++ .../conditionalExpressionNewLine6.errors.txt | 15 ++++ .../conditionalExpressionNewLine6.js | 9 +++ .../conditionalExpressionNewLine7.errors.txt | 15 ++++ .../conditionalExpressionNewLine7.js | 9 +++ .../conditionalExpressionNewLine8.errors.txt | 27 +++++++ .../conditionalExpressionNewLine8.js | 9 +++ .../conditionalExpressionNewLine9.errors.txt | 29 +++++++ .../conditionalExpressionNewLine9.js | 13 +++ ...constructorWithIncompleteTypeAnnotation.js | 3 +- ...ericRecursiveImplicitConstructorErrors3.js | 5 +- .../overloadResolutionOverNonCTLambdas.js | 4 +- tests/baselines/reference/scannertest1.js | 6 +- .../typeGuardsInConditionalExpression.js | 81 +++++++++++-------- .../typeGuardsInFunctionAndModuleBlock.js | 62 ++++++++------ .../reference/typeGuardsInIfStatement.js | 26 +++--- ...ypeGuardsInRightOperandOfAndAndOperator.js | 14 ++-- .../typeGuardsInRightOperandOfOrOrOperator.js | 14 ++-- .../compiler/conditionalExpressionNewLine1.ts | 1 + .../conditionalExpressionNewLine10.ts | 7 ++ .../compiler/conditionalExpressionNewLine2.ts | 2 + .../compiler/conditionalExpressionNewLine3.ts | 2 + .../compiler/conditionalExpressionNewLine4.ts | 2 + .../compiler/conditionalExpressionNewLine5.ts | 2 + .../compiler/conditionalExpressionNewLine6.ts | 3 + .../compiler/conditionalExpressionNewLine7.ts | 3 + .../compiler/conditionalExpressionNewLine8.ts | 3 + .../compiler/conditionalExpressionNewLine9.ts | 5 ++ 41 files changed, 485 insertions(+), 90 deletions(-) create mode 100644 tests/baselines/reference/conditionalExpressionNewLine1.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine1.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine10.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine10.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine2.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine2.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine3.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine3.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine4.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine4.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine5.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine5.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine6.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine6.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine7.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine7.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine8.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine8.js create mode 100644 tests/baselines/reference/conditionalExpressionNewLine9.errors.txt create mode 100644 tests/baselines/reference/conditionalExpressionNewLine9.js create mode 100644 tests/cases/compiler/conditionalExpressionNewLine1.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine10.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine2.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine3.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine4.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine5.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine6.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine7.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine8.ts create mode 100644 tests/cases/compiler/conditionalExpressionNewLine9.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 154b0874548..4d8ed28602f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3330,10 +3330,45 @@ module ts { function emitConditionalExpression(node: ConditionalExpression) { emit(node.condition); - write(" ? "); + var indent1 = indentIfOnDifferentLines(node, node.condition, node.questionToken); + if (!indent1) { + write(" "); + } + + write("?"); + + if (!indent1) { + var indent2 = indentIfOnDifferentLines(node, node.questionToken, node.whenTrue); + } + + if (!indent2) { + write(" "); + } + emit(node.whenTrue); - write(" : "); + + if (indent1 || indent2) { + decreaseIndent(); + } + + var indent3 = indentIfOnDifferentLines(node, node.whenTrue, node.colonToken); + if (!indent3) { + write(" "); + } + + write(":"); + if (!indent3) { + var indent4 = indentIfOnDifferentLines(node, node.colonToken, node.whenFalse); + } + + if (!indent4) { + write(" "); + } + emit(node.whenFalse); + if (indent3 || indent4) { + decreaseIndent(); + } } function isSingleLineEmptyBlock(node: Node) { @@ -3706,10 +3741,16 @@ module ts { equals.left = value; equals.operatorToken = createSynthesizedNode(SyntaxKind.EqualsEqualsEqualsToken); equals.right = createVoidZero(); + return createConditionalExpression(equals, defaultValue, value); + } + + function createConditionalExpression(condition: Expression, whenTrue: Expression, whenFalse: Expression) { var cond = createSynthesizedNode(SyntaxKind.ConditionalExpression); - cond.condition = equals; - cond.whenTrue = defaultValue; - cond.whenFalse = value; + cond.condition = condition; + cond.questionToken = createSynthesizedNode(SyntaxKind.QuestionToken); + cond.whenTrue = whenTrue; + cond.colonToken = createSynthesizedNode(SyntaxKind.ColonToken); + cond.whenFalse = whenFalse; return cond; } diff --git a/tests/baselines/reference/APISample_transform.js b/tests/baselines/reference/APISample_transform.js index 9c0777413a0..290421426c3 100644 --- a/tests/baselines/reference/APISample_transform.js +++ b/tests/baselines/reference/APISample_transform.js @@ -2034,7 +2034,8 @@ function transform(contents, compilerOptions) { // Create a compilerHost object to allow the compiler to read and write files var compilerHost = { getSourceFile: function (fileName, target) { - return files[fileName] !== undefined ? ts.createSourceFile(fileName, files[fileName], target) : undefined; + return files[fileName] !== undefined ? + ts.createSourceFile(fileName, files[fileName], target) : undefined; }, writeFile: function (name, text, writeByteOrderMark) { outputs.push({ name: name, text: text, writeByteOrderMark: writeByteOrderMark }); diff --git a/tests/baselines/reference/conditionalExpressionNewLine1.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine1.errors.txt new file mode 100644 index 00000000000..504d66fe3a7 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine1.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/conditionalExpressionNewLine1.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine1.ts(1,13): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine1.ts(1,17): error TS2304: Cannot find name 'c'. + + +==== tests/cases/compiler/conditionalExpressionNewLine1.ts (3 errors) ==== + var v = a ? b : c; + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS2304: Cannot find name 'b'. + ~ +!!! error TS2304: Cannot find name 'c'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine1.js b/tests/baselines/reference/conditionalExpressionNewLine1.js new file mode 100644 index 00000000000..02055e3e479 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine1.js @@ -0,0 +1,5 @@ +//// [conditionalExpressionNewLine1.ts] +var v = a ? b : c; + +//// [conditionalExpressionNewLine1.js] +var v = a ? b : c; diff --git a/tests/baselines/reference/conditionalExpressionNewLine10.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine10.errors.txt new file mode 100644 index 00000000000..a5c902361e6 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine10.errors.txt @@ -0,0 +1,31 @@ +tests/cases/compiler/conditionalExpressionNewLine10.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine10.ts(2,5): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine10.ts(3,7): error TS2304: Cannot find name 'd'. +tests/cases/compiler/conditionalExpressionNewLine10.ts(4,7): error TS2304: Cannot find name 'e'. +tests/cases/compiler/conditionalExpressionNewLine10.ts(5,5): error TS2304: Cannot find name 'c'. +tests/cases/compiler/conditionalExpressionNewLine10.ts(6,7): error TS2304: Cannot find name 'f'. +tests/cases/compiler/conditionalExpressionNewLine10.ts(7,7): error TS2304: Cannot find name 'g'. + + +==== tests/cases/compiler/conditionalExpressionNewLine10.ts (7 errors) ==== + var v = a + ~ +!!! error TS2304: Cannot find name 'a'. + ? b + ~ +!!! error TS2304: Cannot find name 'b'. + ? d + ~ +!!! error TS2304: Cannot find name 'd'. + : e + ~ +!!! error TS2304: Cannot find name 'e'. + : c + ~ +!!! error TS2304: Cannot find name 'c'. + ? f + ~ +!!! error TS2304: Cannot find name 'f'. + : g; + ~ +!!! error TS2304: Cannot find name 'g'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine10.js b/tests/baselines/reference/conditionalExpressionNewLine10.js new file mode 100644 index 00000000000..bb2f3bec231 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine10.js @@ -0,0 +1,17 @@ +//// [conditionalExpressionNewLine10.ts] +var v = a + ? b + ? d + : e + : c + ? f + : g; + +//// [conditionalExpressionNewLine10.js] +var v = a + ? b + ? d + : e + : c + ? f + : g; diff --git a/tests/baselines/reference/conditionalExpressionNewLine2.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine2.errors.txt new file mode 100644 index 00000000000..5036b247304 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine2.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/conditionalExpressionNewLine2.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine2.ts(2,5): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine2.ts(2,9): error TS2304: Cannot find name 'c'. + + +==== tests/cases/compiler/conditionalExpressionNewLine2.ts (3 errors) ==== + var v = a + ~ +!!! error TS2304: Cannot find name 'a'. + ? b : c; + ~ +!!! error TS2304: Cannot find name 'b'. + ~ +!!! error TS2304: Cannot find name 'c'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine2.js b/tests/baselines/reference/conditionalExpressionNewLine2.js new file mode 100644 index 00000000000..e69f2004ebc --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine2.js @@ -0,0 +1,7 @@ +//// [conditionalExpressionNewLine2.ts] +var v = a + ? b : c; + +//// [conditionalExpressionNewLine2.js] +var v = a + ? b : c; diff --git a/tests/baselines/reference/conditionalExpressionNewLine3.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine3.errors.txt new file mode 100644 index 00000000000..34ea3d419d8 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine3.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/conditionalExpressionNewLine3.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine3.ts(2,3): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine3.ts(2,7): error TS2304: Cannot find name 'c'. + + +==== tests/cases/compiler/conditionalExpressionNewLine3.ts (3 errors) ==== + var v = a ? + ~ +!!! error TS2304: Cannot find name 'a'. + b : c; + ~ +!!! error TS2304: Cannot find name 'b'. + ~ +!!! error TS2304: Cannot find name 'c'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine3.js b/tests/baselines/reference/conditionalExpressionNewLine3.js new file mode 100644 index 00000000000..4d11f45368f --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine3.js @@ -0,0 +1,7 @@ +//// [conditionalExpressionNewLine3.ts] +var v = a ? + b : c; + +//// [conditionalExpressionNewLine3.js] +var v = a ? + b : c; diff --git a/tests/baselines/reference/conditionalExpressionNewLine4.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine4.errors.txt new file mode 100644 index 00000000000..74c39406c6c --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine4.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/conditionalExpressionNewLine4.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine4.ts(1,13): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine4.ts(2,3): error TS2304: Cannot find name 'c'. + + +==== tests/cases/compiler/conditionalExpressionNewLine4.ts (3 errors) ==== + var v = a ? b : + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS2304: Cannot find name 'b'. + c; + ~ +!!! error TS2304: Cannot find name 'c'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine4.js b/tests/baselines/reference/conditionalExpressionNewLine4.js new file mode 100644 index 00000000000..d6532ecb15b --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine4.js @@ -0,0 +1,7 @@ +//// [conditionalExpressionNewLine4.ts] +var v = a ? b : + c; + +//// [conditionalExpressionNewLine4.js] +var v = a ? b : + c; diff --git a/tests/baselines/reference/conditionalExpressionNewLine5.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine5.errors.txt new file mode 100644 index 00000000000..86c8890e218 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine5.errors.txt @@ -0,0 +1,14 @@ +tests/cases/compiler/conditionalExpressionNewLine5.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine5.ts(1,13): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine5.ts(2,5): error TS2304: Cannot find name 'c'. + + +==== tests/cases/compiler/conditionalExpressionNewLine5.ts (3 errors) ==== + var v = a ? b + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS2304: Cannot find name 'b'. + : c; + ~ +!!! error TS2304: Cannot find name 'c'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine5.js b/tests/baselines/reference/conditionalExpressionNewLine5.js new file mode 100644 index 00000000000..6fdd0735bcd --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine5.js @@ -0,0 +1,7 @@ +//// [conditionalExpressionNewLine5.ts] +var v = a ? b + : c; + +//// [conditionalExpressionNewLine5.js] +var v = a ? b + : c; diff --git a/tests/baselines/reference/conditionalExpressionNewLine6.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine6.errors.txt new file mode 100644 index 00000000000..c59ea73b845 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine6.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/conditionalExpressionNewLine6.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine6.ts(2,5): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine6.ts(3,5): error TS2304: Cannot find name 'c'. + + +==== tests/cases/compiler/conditionalExpressionNewLine6.ts (3 errors) ==== + var v = a + ~ +!!! error TS2304: Cannot find name 'a'. + ? b + ~ +!!! error TS2304: Cannot find name 'b'. + : c; + ~ +!!! error TS2304: Cannot find name 'c'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine6.js b/tests/baselines/reference/conditionalExpressionNewLine6.js new file mode 100644 index 00000000000..94539ab891e --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine6.js @@ -0,0 +1,9 @@ +//// [conditionalExpressionNewLine6.ts] +var v = a + ? b + : c; + +//// [conditionalExpressionNewLine6.js] +var v = a + ? b + : c; diff --git a/tests/baselines/reference/conditionalExpressionNewLine7.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine7.errors.txt new file mode 100644 index 00000000000..ff71c42ddae --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine7.errors.txt @@ -0,0 +1,15 @@ +tests/cases/compiler/conditionalExpressionNewLine7.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine7.ts(2,3): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine7.ts(3,3): error TS2304: Cannot find name 'c'. + + +==== tests/cases/compiler/conditionalExpressionNewLine7.ts (3 errors) ==== + var v = a ? + ~ +!!! error TS2304: Cannot find name 'a'. + b : + ~ +!!! error TS2304: Cannot find name 'b'. + c; + ~ +!!! error TS2304: Cannot find name 'c'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine7.js b/tests/baselines/reference/conditionalExpressionNewLine7.js new file mode 100644 index 00000000000..5c781f7d85a --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine7.js @@ -0,0 +1,9 @@ +//// [conditionalExpressionNewLine7.ts] +var v = a ? + b : + c; + +//// [conditionalExpressionNewLine7.js] +var v = a ? + b : + c; diff --git a/tests/baselines/reference/conditionalExpressionNewLine8.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine8.errors.txt new file mode 100644 index 00000000000..1c6a039089c --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine8.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/conditionalExpressionNewLine8.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine8.ts(2,5): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine8.ts(2,9): error TS2304: Cannot find name 'd'. +tests/cases/compiler/conditionalExpressionNewLine8.ts(2,13): error TS2304: Cannot find name 'e'. +tests/cases/compiler/conditionalExpressionNewLine8.ts(3,5): error TS2304: Cannot find name 'c'. +tests/cases/compiler/conditionalExpressionNewLine8.ts(3,9): error TS2304: Cannot find name 'f'. +tests/cases/compiler/conditionalExpressionNewLine8.ts(3,13): error TS2304: Cannot find name 'g'. + + +==== tests/cases/compiler/conditionalExpressionNewLine8.ts (7 errors) ==== + var v = a + ~ +!!! error TS2304: Cannot find name 'a'. + ? b ? d : e + ~ +!!! error TS2304: Cannot find name 'b'. + ~ +!!! error TS2304: Cannot find name 'd'. + ~ +!!! error TS2304: Cannot find name 'e'. + : c ? f : g; + ~ +!!! error TS2304: Cannot find name 'c'. + ~ +!!! error TS2304: Cannot find name 'f'. + ~ +!!! error TS2304: Cannot find name 'g'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine8.js b/tests/baselines/reference/conditionalExpressionNewLine8.js new file mode 100644 index 00000000000..61372eeadbc --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine8.js @@ -0,0 +1,9 @@ +//// [conditionalExpressionNewLine8.ts] +var v = a + ? b ? d : e + : c ? f : g; + +//// [conditionalExpressionNewLine8.js] +var v = a + ? b ? d : e + : c ? f : g; diff --git a/tests/baselines/reference/conditionalExpressionNewLine9.errors.txt b/tests/baselines/reference/conditionalExpressionNewLine9.errors.txt new file mode 100644 index 00000000000..821e3ac67f4 --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine9.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/conditionalExpressionNewLine9.ts(1,9): error TS2304: Cannot find name 'a'. +tests/cases/compiler/conditionalExpressionNewLine9.ts(2,5): error TS2304: Cannot find name 'b'. +tests/cases/compiler/conditionalExpressionNewLine9.ts(3,7): error TS2304: Cannot find name 'd'. +tests/cases/compiler/conditionalExpressionNewLine9.ts(3,11): error TS2304: Cannot find name 'e'. +tests/cases/compiler/conditionalExpressionNewLine9.ts(4,5): error TS2304: Cannot find name 'c'. +tests/cases/compiler/conditionalExpressionNewLine9.ts(5,7): error TS2304: Cannot find name 'f'. +tests/cases/compiler/conditionalExpressionNewLine9.ts(5,11): error TS2304: Cannot find name 'g'. + + +==== tests/cases/compiler/conditionalExpressionNewLine9.ts (7 errors) ==== + var v = a + ~ +!!! error TS2304: Cannot find name 'a'. + ? b + ~ +!!! error TS2304: Cannot find name 'b'. + ? d : e + ~ +!!! error TS2304: Cannot find name 'd'. + ~ +!!! error TS2304: Cannot find name 'e'. + : c + ~ +!!! error TS2304: Cannot find name 'c'. + ? f : g; + ~ +!!! error TS2304: Cannot find name 'f'. + ~ +!!! error TS2304: Cannot find name 'g'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalExpressionNewLine9.js b/tests/baselines/reference/conditionalExpressionNewLine9.js new file mode 100644 index 00000000000..79f4606754e --- /dev/null +++ b/tests/baselines/reference/conditionalExpressionNewLine9.js @@ -0,0 +1,13 @@ +//// [conditionalExpressionNewLine9.ts] +var v = a + ? b + ? d : e + : c + ? f : g; + +//// [conditionalExpressionNewLine9.js] +var v = a + ? b + ? d : e + : c + ? f : g; diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js index 6adbaddb117..16e936620d0 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.js @@ -499,7 +499,8 @@ var CLASS = (function () { CLASS.prototype.Foo = function () { var myEvent = function () { return 1; }; if (myEvent() == 1) - return true ? : ; + return true ? + : ; else return false; }; diff --git a/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.js b/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.js index 11113b778d3..e01c9045345 100644 --- a/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.js +++ b/tests/baselines/reference/genericRecursiveImplicitConstructorErrors3.js @@ -69,7 +69,10 @@ var TypeScript; }; PullTypeSymbol.prototype.getScopedNameEx = function (scopeSymbol, useConstraintInName, getPrettyTypeName, getTypeParamMarkerInfo) { if (this.isArray()) { - var elementMemberName = this._elementType ? (this._elementType.isArray() || this._elementType.isNamedTypeSymbol() ? this._elementType.getScopedNameEx(scopeSymbol, false, getPrettyTypeName, getTypeParamMarkerInfo) : this._elementType.getMemberTypeNameEx(false, scopeSymbol, getPrettyTypeName)) : 1; + var elementMemberName = this._elementType ? + (this._elementType.isArray() || this._elementType.isNamedTypeSymbol() ? + this._elementType.getScopedNameEx(scopeSymbol, false, getPrettyTypeName, getTypeParamMarkerInfo) : + this._elementType.getMemberTypeNameEx(false, scopeSymbol, getPrettyTypeName)) : 1; return TypeScript.MemberName.create(elementMemberName, "", "[]"); } }; diff --git a/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js b/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js index e77e8d3371f..170f2dd2137 100644 --- a/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js +++ b/tests/baselines/reference/overloadResolutionOverNonCTLambdas.js @@ -43,7 +43,9 @@ var Bugs; rest[_i - 1] = arguments[_i]; } var index = rest[0]; - return typeof args[index] !== 'undefined' ? args[index] : match; + return typeof args[index] !== 'undefined' + ? args[index] + : match; }); return result; } diff --git a/tests/baselines/reference/scannertest1.js b/tests/baselines/reference/scannertest1.js index 8c9d805c5f2..b96c965a79e 100644 --- a/tests/baselines/reference/scannertest1.js +++ b/tests/baselines/reference/scannertest1.js @@ -39,7 +39,11 @@ var CharacterInfo = (function () { }; CharacterInfo.hexValue = function (c) { Debug.assert(isHexDigit(c)); - return isDecimalDigit(c) ? (c - CharacterCodes._0) : (c >= CharacterCodes.A && c <= CharacterCodes.F) ? c - CharacterCodes.A + 10 : c - CharacterCodes.a + 10; + return isDecimalDigit(c) + ? (c - CharacterCodes._0) + : (c >= CharacterCodes.A && c <= CharacterCodes.F) + ? c - CharacterCodes.A + 10 + : c - CharacterCodes.a + 10; }; return CharacterInfo; })(); diff --git a/tests/baselines/reference/typeGuardsInConditionalExpression.js b/tests/baselines/reference/typeGuardsInConditionalExpression.js index a1a546a193e..118ebbc02c0 100644 --- a/tests/baselines/reference/typeGuardsInConditionalExpression.js +++ b/tests/baselines/reference/typeGuardsInConditionalExpression.js @@ -105,77 +105,92 @@ function foo12(x: number | string | boolean) { // the type of a variable or parameter is narrowed by any type guard in the condition when false, // provided the false expression contains no assignments to the variable or parameter. function foo(x) { - return typeof x === "string" ? x.length // string - : x++; // number + return typeof x === "string" + ? x.length // string + : x++; // number } function foo2(x) { // x is assigned in the if true branch, the type is not narrowed - return typeof x === "string" ? (x = 10 && x) // string | number - : x; // string | number + return typeof x === "string" + ? (x = 10 && x) // string | number + : x; // string | number } function foo3(x) { // x is assigned in the if false branch, the type is not narrowed // even though assigned using same type as narrowed expression - return typeof x === "string" ? (x = "Hello" && x) // string | number - : x; // string | number + return typeof x === "string" + ? (x = "Hello" && x) // string | number + : x; // string | number } function foo4(x) { // false branch updates the variable - so here it is not number // even though assigned using same type as narrowed expression - return typeof x === "string" ? x // string | number - : (x = 10 && x); // string | number + return typeof x === "string" + ? x // string | number + : (x = 10 && x); // string | number } function foo5(x) { // false branch updates the variable - so here it is not number - return typeof x === "string" ? x // string | number - : (x = "hello" && x); // string | number + return typeof x === "string" + ? x // string | number + : (x = "hello" && x); // string | number } function foo6(x) { // Modify in both branches - return typeof x === "string" ? (x = 10 && x) // string | number - : (x = "hello" && x); // string | number + return typeof x === "string" + ? (x = 10 && x) // string | number + : (x = "hello" && x); // string | number } function foo7(x) { - return typeof x === "string" ? x === "hello" // string - : typeof x === "boolean" ? x // boolean - : x == 10; // number + return typeof x === "string" + ? x === "hello" // string + : typeof x === "boolean" + ? x // boolean + : x == 10; // number } function foo8(x) { var b; - return typeof x === "string" ? x === "hello" : ((b = x) && - (typeof x === "boolean" ? x // boolean - : x == 10)); // number + return typeof x === "string" + ? x === "hello" + : ((b = x) && + (typeof x === "boolean" + ? x // boolean + : x == 10)); // number } function foo9(x) { var y = 10; // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - return typeof x === "string" ? ((y = x.length) && x === "hello") // string - : x === 10; // number + return typeof x === "string" + ? ((y = x.length) && x === "hello") // string + : x === 10; // number } function foo10(x) { // Mixing typeguards var b; - return typeof x === "string" ? x // string - : ((b = x) // x is number | boolean - && typeof x === "number" - && x.toString()); // x is number + return typeof x === "string" + ? x // string + : ((b = x) // x is number | boolean + && typeof x === "number" + && x.toString()); // x is number } function foo11(x) { // Mixing typeguards // Assigning value to x deep inside another guard stops narrowing of type too var b; - return typeof x === "string" ? x // number | boolean | string - changed in the false branch - : ((b = x) // x is number | boolean | string - because the assignment changed it - && typeof x === "number" - && (x = 10) // assignment to x - && x); // x is number | boolean | string + return typeof x === "string" + ? x // number | boolean | string - changed in the false branch + : ((b = x) // x is number | boolean | string - because the assignment changed it + && typeof x === "number" + && (x = 10) // assignment to x + && x); // x is number | boolean | string } function foo12(x) { // Mixing typeguards // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression var b; - return typeof x === "string" ? (x = 10 && x.toString().length) // number | boolean | string - changed here - : ((b = x) // x is number | boolean | string - changed in true branch - && typeof x === "number" - && x); // x is number + return typeof x === "string" + ? (x = 10 && x.toString().length) // number | boolean | string - changed here + : ((b = x) // x is number | boolean | string - changed in true branch + && typeof x === "number" + && x); // x is number } diff --git a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js index 239eeb4bfe7..7cf19dac0ad 100644 --- a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js +++ b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js @@ -82,32 +82,44 @@ module m1 { //// [typeGuardsInFunctionAndModuleBlock.js] // typeguards are scoped in function/module block function foo(x) { - return typeof x === "string" ? x : function f() { - var b = x; // number | boolean - return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number - }(); + return typeof x === "string" + ? x + : function f() { + var b = x; // number | boolean + return typeof x === "boolean" + ? x.toString() // boolean + : x.toString(); // number + }(); } function foo2(x) { - return typeof x === "string" ? x : function f(a) { - var b = x; // new scope - number | boolean - return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number - }(x); // x here is narrowed to number | boolean + return typeof x === "string" + ? x + : function f(a) { + var b = x; // new scope - number | boolean + return typeof x === "boolean" + ? x.toString() // boolean + : x.toString(); // number + }(x); // x here is narrowed to number | boolean } function foo3(x) { - return typeof x === "string" ? x : (function () { - var b = x; // new scope - number | boolean - return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number - })(); + return typeof x === "string" + ? x + : (function () { + var b = x; // new scope - number | boolean + return typeof x === "boolean" + ? x.toString() // boolean + : x.toString(); // number + })(); } function foo4(x) { - return typeof x === "string" ? x : (function (a) { - var b = x; // new scope - number | boolean - return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number - })(x); // x here is narrowed to number | boolean + return typeof x === "string" + ? x + : (function (a) { + var b = x; // new scope - number | boolean + return typeof x === "boolean" + ? x.toString() // boolean + : x.toString(); // number + })(x); // x here is narrowed to number | boolean } // Type guards affect nested function expressions, but not nested function declarations function foo5(x) { @@ -129,8 +141,9 @@ var m; y = x; // string; } else { - y = typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number + y = typeof x === "boolean" + ? x.toString() // boolean + : x.toString(); // number } })(m2 || (m2 = {})); })(m || (m = {})); @@ -147,8 +160,9 @@ var m1; y = x; // string; } else { - y = typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number + y = typeof x === "boolean" + ? x.toString() // boolean + : x.toString(); // number } })(m3 = m2.m3 || (m2.m3 = {})); })(m2 || (m2 = {})); diff --git a/tests/baselines/reference/typeGuardsInIfStatement.js b/tests/baselines/reference/typeGuardsInIfStatement.js index c228c038579..820d205bc65 100644 --- a/tests/baselines/reference/typeGuardsInIfStatement.js +++ b/tests/baselines/reference/typeGuardsInIfStatement.js @@ -258,8 +258,9 @@ function foo10(x) { else { var y; var b = x; // number | boolean - return typeof x === "number" ? x === 10 // number - : x; // x should be boolean + return typeof x === "number" + ? x === 10 // number + : x; // x should be boolean } } function foo11(x) { @@ -271,13 +272,15 @@ function foo11(x) { else { var y; var b = x; // number | boolean | string - because below we are changing value of x in if statement - return typeof x === "number" ? ( - // change value of x - x = 10 && x.toString() // number | boolean | string - ) : ( - // do not change value - y = x && x.toString() // number | boolean | string - ); + return typeof x === "number" + ? ( + // change value of x + x = 10 && x.toString() // number | boolean | string + ) + : ( + // do not change value + y = x && x.toString() // number | boolean | string + ); } } function foo12(x) { @@ -289,7 +292,8 @@ function foo12(x) { else { x = 10; var b = x; // number | boolean | string - return typeof x === "number" ? x.toString() // number - : x.toString(); // boolean | string + return typeof x === "number" + ? x.toString() // number + : x.toString(); // boolean | string } } diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js index 23ee7b29f51..e3f1a8c72c2 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.js @@ -86,8 +86,8 @@ function foo6(x) { // Mixing typeguard narrowing in if statement with conditional expression typeguard return typeof x !== "string" // string | number | boolean && (typeof x !== "number" // number | boolean - ? x // boolean - : x === 10); // number + ? x // boolean + : x === 10); // number } function foo7(x) { var y; @@ -96,14 +96,16 @@ function foo7(x) { // Assigning value to x deep inside another guard stops narrowing of type too return typeof x !== "string" && ((z = x) // string | number | boolean - x changed deeper in conditional expression - && (typeof x === "number" ? (x = 10 && x.toString()) // number | boolean | string - : (y = x && x.toString()))); // number | boolean | string + && (typeof x === "number" + ? (x = 10 && x.toString()) // number | boolean | string + : (y = x && x.toString()))); // number | boolean | string } function foo8(x) { // Mixing typeguard // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression return typeof x !== "string" && (x = 10) // change x - number| string - && (typeof x === "number" ? x // number - : x.length); // string + && (typeof x === "number" + ? x // number + : x.length); // string } diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js index 13bb090ab8c..188d226da13 100644 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js +++ b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.js @@ -86,8 +86,8 @@ function foo6(x) { // Mixing typeguard return typeof x === "string" // string | number | boolean || (typeof x !== "number" // number | boolean - ? x // boolean - : x === 10); // number + ? x // boolean + : x === 10); // number } function foo7(x) { var y; @@ -96,14 +96,16 @@ function foo7(x) { // Assigning value to x deep inside another guard stops narrowing of type too return typeof x === "string" || ((z = x) // string | number | boolean - x changed deeper in conditional expression - || (typeof x === "number" ? (x = 10 && x.toString()) // number | boolean | string - : (y = x && x.toString()))); // number | boolean | string + || (typeof x === "number" + ? (x = 10 && x.toString()) // number | boolean | string + : (y = x && x.toString()))); // number | boolean | string } function foo8(x) { // Mixing typeguard // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression return typeof x === "string" || (x = 10) // change x - number| string - || (typeof x === "number" ? x // number - : x.length); // string + || (typeof x === "number" + ? x // number + : x.length); // string } diff --git a/tests/cases/compiler/conditionalExpressionNewLine1.ts b/tests/cases/compiler/conditionalExpressionNewLine1.ts new file mode 100644 index 00000000000..a21af7d1b0e --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine1.ts @@ -0,0 +1 @@ +var v = a ? b : c; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine10.ts b/tests/cases/compiler/conditionalExpressionNewLine10.ts new file mode 100644 index 00000000000..c1da921a4d6 --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine10.ts @@ -0,0 +1,7 @@ +var v = a + ? b + ? d + : e + : c + ? f + : g; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine2.ts b/tests/cases/compiler/conditionalExpressionNewLine2.ts new file mode 100644 index 00000000000..30c0c37beb6 --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine2.ts @@ -0,0 +1,2 @@ +var v = a + ? b : c; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine3.ts b/tests/cases/compiler/conditionalExpressionNewLine3.ts new file mode 100644 index 00000000000..ab31c226625 --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine3.ts @@ -0,0 +1,2 @@ +var v = a ? + b : c; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine4.ts b/tests/cases/compiler/conditionalExpressionNewLine4.ts new file mode 100644 index 00000000000..f17370ff046 --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine4.ts @@ -0,0 +1,2 @@ +var v = a ? b : + c; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine5.ts b/tests/cases/compiler/conditionalExpressionNewLine5.ts new file mode 100644 index 00000000000..695ce0a1005 --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine5.ts @@ -0,0 +1,2 @@ +var v = a ? b + : c; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine6.ts b/tests/cases/compiler/conditionalExpressionNewLine6.ts new file mode 100644 index 00000000000..189a3d67aa8 --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine6.ts @@ -0,0 +1,3 @@ +var v = a + ? b + : c; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine7.ts b/tests/cases/compiler/conditionalExpressionNewLine7.ts new file mode 100644 index 00000000000..5c5120c8022 --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine7.ts @@ -0,0 +1,3 @@ +var v = a ? + b : + c; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine8.ts b/tests/cases/compiler/conditionalExpressionNewLine8.ts new file mode 100644 index 00000000000..ef8fcf2ed95 --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine8.ts @@ -0,0 +1,3 @@ +var v = a + ? b ? d : e + : c ? f : g; \ No newline at end of file diff --git a/tests/cases/compiler/conditionalExpressionNewLine9.ts b/tests/cases/compiler/conditionalExpressionNewLine9.ts new file mode 100644 index 00000000000..a59440f485c --- /dev/null +++ b/tests/cases/compiler/conditionalExpressionNewLine9.ts @@ -0,0 +1,5 @@ +var v = a + ? b + ? d : e + : c + ? f : g; \ No newline at end of file