Preserve newlines for property access expressions on multiple lines.

This commit is contained in:
Cyrus Najmabadi
2015-03-05 02:31:55 -08:00
parent b784a4212a
commit 62d304b069
27 changed files with 152 additions and 22 deletions
+21
View File
@@ -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) {
+12 -8
View File
@@ -120,6 +120,7 @@ module ts {
return visitNodes(cbNodes, (<ObjectLiteralExpression>node).properties);
case SyntaxKind.PropertyAccessExpression:
return visitNode(cbNode, (<PropertyAccessExpression>node).expression) ||
visitNode(cbNode, (<PropertyAccessExpression>node).dotToken) ||
visitNode(cbNode, (<PropertyAccessExpression>node).name);
case SyntaxKind.ElementAccessExpression:
return visitNode(cbNode, (<ElementAccessExpression>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 extends Node>(): T {
var node = <T>createNode(token);
nextToken();
@@ -2150,8 +2154,7 @@ module ts {
literal = parseLiteralNode();
}
else {
literal = <LiteralExpression>createMissingNode(
SyntaxKind.TemplateTail, /*reportAtCurrentPosition:*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
literal = <LiteralExpression>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 = <PropertyAccessExpression>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 = <PropertyAccessExpression>createNode(SyntaxKind.PropertyAccessExpression, expression.pos);
propertyAccess.expression = expression;
propertyAccess.dotToken = dotToken;
propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames:*/ true);
expression = finishNode(propertyAccess);
continue;
+1
View File
@@ -693,6 +693,7 @@ module ts {
export interface PropertyAccessExpression extends MemberExpression {
expression: LeftHandSideExpression;
dotToken: Node;
name: Identifier;
}
@@ -579,6 +579,7 @@ declare module "typescript" {
}
interface PropertyAccessExpression extends MemberExpression {
expression: LeftHandSideExpression;
dotToken: Node;
name: Identifier;
}
interface ElementAccessExpression extends MemberExpression {
@@ -1743,6 +1743,10 @@ declare module "typescript" {
>expression : LeftHandSideExpression
>LeftHandSideExpression : LeftHandSideExpression
dotToken: Node;
>dotToken : Node
>Node : Node
name: Identifier;
>name : Identifier
>Identifier : Identifier
@@ -610,6 +610,7 @@ declare module "typescript" {
}
interface PropertyAccessExpression extends MemberExpression {
expression: LeftHandSideExpression;
dotToken: Node;
name: Identifier;
}
interface ElementAccessExpression extends MemberExpression {
@@ -1889,6 +1889,10 @@ declare module "typescript" {
>expression : LeftHandSideExpression
>LeftHandSideExpression : LeftHandSideExpression
dotToken: Node;
>dotToken : Node
>Node : Node
name: Identifier;
>name : Identifier
>Identifier : Identifier
@@ -611,6 +611,7 @@ declare module "typescript" {
}
interface PropertyAccessExpression extends MemberExpression {
expression: LeftHandSideExpression;
dotToken: Node;
name: Identifier;
}
interface ElementAccessExpression extends MemberExpression {
@@ -1839,6 +1839,10 @@ declare module "typescript" {
>expression : LeftHandSideExpression
>LeftHandSideExpression : LeftHandSideExpression
dotToken: Node;
>dotToken : Node
>Node : Node
name: Identifier;
>name : Identifier
>Identifier : Identifier
@@ -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 */ });
@@ -2012,6 +2012,10 @@ declare module "typescript" {
>expression : LeftHandSideExpression
>LeftHandSideExpression : LeftHandSideExpression
dotToken: Node;
>dotToken : Node
>Node : Node
name: Identifier;
>name : Identifier
>Identifier : Identifier
+2 -1
View File
@@ -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; });
@@ -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 */;
@@ -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
@@ -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
@@ -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(); });
@@ -17,6 +17,6 @@ var r2: I1<number> = v1.func(num => num.toString()) // Correctly returns an I1<s
//// [overEagerReturnTypeSpecialization.js]
//Note: Below simpler repro
var r1 = v1.func(function (num) { return num.toString(); }) // Correctly returns an I1<string>
.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<string>
.func(function (str) { return str.length; }); // should be ok
.func(function (str) { return str.length; }); // should be ok
+2 -1
View File
@@ -8,5 +8,6 @@ function foo() {
//// [parse1.js]
var bar = 42;
function foo() {
bar.;
bar.
;
}
+2 -1
View File
@@ -16,7 +16,8 @@ var Foo = (function () {
function Foo() {
}
Foo.prototype.f1 = function () {
if (this.)
if (this.
)
;
};
Foo.prototype.f2 = function () {
+5 -1
View File
@@ -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] };
@@ -0,0 +1,11 @@
//// [wrappedIncovations1.ts]
var v = this
.foo()
.bar()
.baz();
//// [wrappedIncovations1.js]
var v = this
.foo()
.bar()
.baz();
@@ -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
@@ -0,0 +1,11 @@
//// [wrappedIncovations2.ts]
var v = this.
foo().
bar().
baz();
//// [wrappedIncovations2.js]
var v = this.
foo().
bar().
baz();
@@ -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
@@ -0,0 +1,4 @@
var v = this
.foo()
.bar()
.baz();
@@ -0,0 +1,4 @@
var v = this.
foo().
bar().
baz();
+1 -1
View File
@@ -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',() => {