Skip to content

Commit 690c682

Browse files
authored
Merge master into release-2.0 (#9400)
* do not format comma/closeparen in jsxelement * format jsx expression * make rules optional * Remove upper boilerplate from issue template Our issue stats did not improve appreciably when we added the issue template. Reduce upper boilerplate text and try to make it more action-oriented * Update issue_template.md * new options should be optional for compatibility * Add getCurrentDirectory to ServerHost * Add nullchecks for typeRoots, remove getCurrentDirectory from ServerHost as it is always the installation location * VarDate interface and relevant Date.prototype members * Fix 9363: Object destructuring broken-variables are bound to the wrong object (#9383) * Fix emit incorrect destructuring mapping in var declaration * Add tests and baselines * Add additional tests and baselines
1 parent 67f0ffe commit 690c682

14 files changed

+218
-26
lines changed

Diff for: issue_template.md

+5-16
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
<!--
2-
Thank you for contributing to TypeScript! Please review this checklist
3-
before submitting your issue.
4-
[ ] Many common issues and suggestions are addressed in the FAQ
5-
https://github.com/Microsoft/TypeScript/wiki/FAQ
6-
[ ] Search for duplicates before logging new issues
7-
https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=is%3Aissue
8-
[ ] Questions are best asked and answered at Stack Overflow
9-
http://stackoverflow.com/questions/tagged/typescript
1+
<!-- BUGS: Please use this template. -->
2+
<!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript -->
3+
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
104

11-
For bug reports, please include the information below.
12-
__________________________________________________________ -->
13-
14-
**TypeScript Version:**
15-
16-
1.7.5 / 1.8.0-beta / nightly (1.9.0-dev.20160217)
5+
**TypeScript Version:** 1.8.0 / nightly (2.0.0-dev.201xxxxx)
176

187
**Code**
198

209
```ts
21-
// A self-contained demonstration of the problem follows...
10+
// A *self-contained* demonstration of the problem follows...
2211

2312
```
2413

Diff for: src/compiler/emitter.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -4545,8 +4545,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
45454545
}
45464546

45474547
write(";");
4548-
tempIndex++;
45494548
}
4549+
// Regardless of whether we will emit a var declaration for the binding pattern, we generate the temporary
4550+
// variable for the parameter (see: emitParameter)
4551+
tempIndex++;
45504552
}
45514553
else if (initializer) {
45524554
writeLine();

Diff for: src/harness/fourslash.ts

+1
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ namespace FourSlash {
324324
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
325325
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
326326
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
327+
InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
327328
PlaceOpenBraceOnNewLineForFunctions: false,
328329
PlaceOpenBraceOnNewLineForControlBlocks: false,
329330
};

Diff for: src/lib/scripthost.d.ts

+10
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,13 @@ interface VBArrayConstructor {
276276
}
277277

278278
declare var VBArray: VBArrayConstructor;
279+
280+
/**
281+
* Automation date (VT_DATE)
282+
*/
283+
interface VarDate { }
284+
285+
interface DateConstructor {
286+
new (vd: VarDate): Date;
287+
getVarDate: () => VarDate;
288+
}

Diff for: src/server/editorServices.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1580,6 +1580,7 @@ namespace ts.server {
15801580
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
15811581
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
15821582
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
1583+
InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
15831584
PlaceOpenBraceOnNewLineForFunctions: false,
15841585
PlaceOpenBraceOnNewLineForControlBlocks: false,
15851586
});

Diff for: src/services/formatting/rules.ts

+23-3
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ namespace ts.formatting {
225225
public NoSpaceBeforeTemplateMiddleAndTail: Rule;
226226
public SpaceBeforeTemplateMiddleAndTail: Rule;
227227

228+
// No space after { and before } in JSX expression
229+
public NoSpaceAfterOpenBraceInJsxExpression: Rule;
230+
public SpaceAfterOpenBraceInJsxExpression: Rule;
231+
public NoSpaceBeforeCloseBraceInJsxExpression: Rule;
232+
public SpaceBeforeCloseBraceInJsxExpression: Rule;
233+
228234
constructor() {
229235
///
230236
/// Common Rules
@@ -316,7 +322,7 @@ namespace ts.formatting {
316322

317323
// Add a space between statements. All keywords except (do,else,case) has open/close parens after them.
318324
// So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any]
319-
this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotForContext), RuleAction.Space));
325+
this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space));
320326

321327
// This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
322328
this.SpaceAfterTryFinally = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword]), SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
@@ -444,8 +450,8 @@ namespace ts.formatting {
444450
///
445451

446452
// Insert space after comma delimiter
447-
this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space));
448-
this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
453+
this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space));
454+
this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext), RuleAction.Delete));
449455

450456
// Insert space before and after binary operators
451457
this.SpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space));
@@ -491,6 +497,12 @@ namespace ts.formatting {
491497
this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete));
492498
this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space));
493499

500+
// No space after { and before } in JSX expression
501+
this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
502+
this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space));
503+
this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete));
504+
this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space));
505+
494506
// Insert space after function keyword for anonymous functions
495507
this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space));
496508
this.NoSpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Delete));
@@ -729,6 +741,14 @@ namespace ts.formatting {
729741
return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText;
730742
}
731743

744+
static isNonJsxElementContext(context: FormattingContext): boolean {
745+
return context.contextNode.kind !== SyntaxKind.JsxElement;
746+
}
747+
748+
static isJsxExpressionContext(context: FormattingContext): boolean {
749+
return context.contextNode.kind === SyntaxKind.JsxExpression;
750+
}
751+
732752
static IsNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean {
733753
return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context);
734754
}

Diff for: src/services/formatting/rulesProvider.ts

+9
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ namespace ts.formatting {
9090
rules.push(this.globalRules.NoSpaceBeforeTemplateMiddleAndTail);
9191
}
9292

93+
if (options.InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces) {
94+
rules.push(this.globalRules.SpaceAfterOpenBraceInJsxExpression);
95+
rules.push(this.globalRules.SpaceBeforeCloseBraceInJsxExpression);
96+
}
97+
else {
98+
rules.push(this.globalRules.NoSpaceAfterOpenBraceInJsxExpression);
99+
rules.push(this.globalRules.NoSpaceBeforeCloseBraceInJsxExpression);
100+
}
101+
93102
if (options.InsertSpaceAfterSemicolonInForStatements) {
94103
rules.push(this.globalRules.SpaceAfterSemicolonInFor);
95104
}

Diff for: src/services/services.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,7 @@ namespace ts {
12671267
InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean;
12681268
InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean;
12691269
InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean;
1270+
InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
12701271
PlaceOpenBraceOnNewLineForFunctions: boolean;
12711272
PlaceOpenBraceOnNewLineForControlBlocks: boolean;
12721273
[s: string]: boolean | number | string | undefined;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [destructuringParameterDeclaration7ES5.ts]
2+
3+
interface ISomething {
4+
foo: string,
5+
bar: string
6+
}
7+
8+
function foo({}, {foo, bar}: ISomething) {}
9+
10+
function baz([], {foo, bar}: ISomething) {}
11+
12+
function one([], {}) {}
13+
14+
function two([], [a, b, c]: number[]) {}
15+
16+
17+
//// [destructuringParameterDeclaration7ES5.js]
18+
function foo(_a, _b) {
19+
var foo = _b.foo, bar = _b.bar;
20+
}
21+
function baz(_a, _b) {
22+
var foo = _b.foo, bar = _b.bar;
23+
}
24+
function one(_a, _b) { }
25+
function two(_a, _b) {
26+
var a = _b[0], b = _b[1], c = _b[2];
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration7ES5.ts ===
2+
3+
interface ISomething {
4+
>ISomething : Symbol(ISomething, Decl(destructuringParameterDeclaration7ES5.ts, 0, 0))
5+
6+
foo: string,
7+
>foo : Symbol(ISomething.foo, Decl(destructuringParameterDeclaration7ES5.ts, 1, 22))
8+
9+
bar: string
10+
>bar : Symbol(ISomething.bar, Decl(destructuringParameterDeclaration7ES5.ts, 2, 16))
11+
}
12+
13+
function foo({}, {foo, bar}: ISomething) {}
14+
>foo : Symbol(foo, Decl(destructuringParameterDeclaration7ES5.ts, 4, 1))
15+
>foo : Symbol(foo, Decl(destructuringParameterDeclaration7ES5.ts, 6, 18))
16+
>bar : Symbol(bar, Decl(destructuringParameterDeclaration7ES5.ts, 6, 22))
17+
>ISomething : Symbol(ISomething, Decl(destructuringParameterDeclaration7ES5.ts, 0, 0))
18+
19+
function baz([], {foo, bar}: ISomething) {}
20+
>baz : Symbol(baz, Decl(destructuringParameterDeclaration7ES5.ts, 6, 43))
21+
>foo : Symbol(foo, Decl(destructuringParameterDeclaration7ES5.ts, 8, 18))
22+
>bar : Symbol(bar, Decl(destructuringParameterDeclaration7ES5.ts, 8, 22))
23+
>ISomething : Symbol(ISomething, Decl(destructuringParameterDeclaration7ES5.ts, 0, 0))
24+
25+
function one([], {}) {}
26+
>one : Symbol(one, Decl(destructuringParameterDeclaration7ES5.ts, 8, 43))
27+
28+
function two([], [a, b, c]: number[]) {}
29+
>two : Symbol(two, Decl(destructuringParameterDeclaration7ES5.ts, 10, 23))
30+
>a : Symbol(a, Decl(destructuringParameterDeclaration7ES5.ts, 12, 18))
31+
>b : Symbol(b, Decl(destructuringParameterDeclaration7ES5.ts, 12, 20))
32+
>c : Symbol(c, Decl(destructuringParameterDeclaration7ES5.ts, 12, 23))
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration7ES5.ts ===
2+
3+
interface ISomething {
4+
>ISomething : ISomething
5+
6+
foo: string,
7+
>foo : string
8+
9+
bar: string
10+
>bar : string
11+
}
12+
13+
function foo({}, {foo, bar}: ISomething) {}
14+
>foo : ({}: {}, {foo, bar}: ISomething) => void
15+
>foo : string
16+
>bar : string
17+
>ISomething : ISomething
18+
19+
function baz([], {foo, bar}: ISomething) {}
20+
>baz : ([]: any[], {foo, bar}: ISomething) => void
21+
>foo : string
22+
>bar : string
23+
>ISomething : ISomething
24+
25+
function one([], {}) {}
26+
>one : ([]: any[], {}: {}) => void
27+
28+
function two([], [a, b, c]: number[]) {}
29+
>two : ([]: any[], [a, b, c]: number[]) => void
30+
>a : number
31+
>b : number
32+
>c : number
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @target: es5
2+
3+
interface ISomething {
4+
foo: string,
5+
bar: string
6+
}
7+
8+
function foo({}, {foo, bar}: ISomething) {}
9+
10+
function baz([], {foo, bar}: ISomething) {}
11+
12+
function one([], {}) {}
13+
14+
function two([], [a, b, c]: number[]) {}

Diff for: tests/cases/fourslash/formattingJsxElements.ts

+26-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//// </div>
1010
//// )
1111
////}
12-
////
12+
////
1313
////function foo1() {
1414
//// return (
1515
//// <div className="commentBox" data-id="test">
@@ -45,8 +45,8 @@
4545
//// class3= {/*5*/
4646
//// }/>/*6*/
4747
//// )
48-
////}
49-
////
48+
////}
49+
////
5050
////(function () {
5151
//// return <div
5252
////className=""/*attrAutoformat*/
@@ -64,7 +64,14 @@
6464
/////*childJsxElementIndent*/
6565
////<span></span>/*grandchildJsxElementAutoformat*/
6666
////</span>/*containedClosingTagAutoformat*/
67-
////</h5>
67+
////</h5>;
68+
////
69+
////<div>,{integer}</div>;/*commaInJsxElement*/
70+
////<div>, {integer}</div>;/*commaInJsxElement2*/
71+
////<span>)</span>;/*closingParenInJsxElement*/
72+
////<span>) </span>;/*closingParenInJsxElement2*/
73+
////<Router routes={ 3 } />;/*jsxExpressionSpaces*/
74+
////<Router routes={ (3) } />;/*jsxExpressionSpaces2*/
6875

6976
format.document();
7077
goTo.marker("autoformat");
@@ -114,7 +121,7 @@ verify.indentationIs(12);
114121

115122
goTo.marker("danglingBracketAutoformat")
116123
// TODO: verify.currentLineContentIs(" >");
117-
verify.currentLineContentIs(" >");
124+
verify.currentLineContentIs(" >");
118125
goTo.marker("closingTagAutoformat");
119126
verify.currentLineContentIs(" </div>");
120127

@@ -125,4 +132,17 @@ verify.indentationIs(8);
125132
goTo.marker("grandchildJsxElementAutoformat");
126133
verify.currentLineContentIs(" <span></span>");
127134
goTo.marker("containedClosingTagAutoformat");
128-
verify.currentLineContentIs(" </span>");
135+
verify.currentLineContentIs(" </span>");
136+
137+
goTo.marker("commaInJsxElement");
138+
verify.currentLineContentIs("<div>,{integer}</div>;");
139+
goTo.marker("commaInJsxElement2");
140+
verify.currentLineContentIs("<div>, {integer}</div>;");
141+
goTo.marker("closingParenInJsxElement");
142+
verify.currentLineContentIs("<span>)</span>;");
143+
goTo.marker("closingParenInJsxElement2");
144+
verify.currentLineContentIs("<span>) </span>;");
145+
goTo.marker("jsxExpressionSpaces");
146+
verify.currentLineContentIs("<Router routes={3} />;");
147+
goTo.marker("jsxExpressionSpaces2");
148+
verify.currentLineContentIs("<Router routes={(3)} />;");

Diff for: tests/cases/fourslash/formattingOptionsChangeJsx.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
///<reference path="fourslash.ts"/>
2+
3+
//@Filename: file.tsx
4+
/////*InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces*/<Madoka homu={ true } saya={ (true) } />;
5+
6+
runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces", "<Madoka homu={ true } saya={ (true) } />;", "<Madoka homu={true} saya={(true)} />;");
7+
8+
9+
function runTest(propertyName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) {
10+
// Go to the correct file
11+
goTo.marker(propertyName);
12+
13+
// Set the option to false first
14+
format.setOption(propertyName, false);
15+
16+
// Format
17+
format.document();
18+
19+
// Verify
20+
goTo.marker(propertyName);
21+
verify.currentLineContentIs(expectedStringWhenFalse);
22+
23+
// Set the option to true
24+
format.setOption(propertyName, true);
25+
26+
// Format
27+
format.document();
28+
29+
// Verify
30+
goTo.marker(propertyName);
31+
verify.currentLineContentIs(expectedStringWhenTrue);
32+
}

0 commit comments

Comments
 (0)