diff --git a/issue_template.md b/issue_template.md index dcd2280570ccb..7799960ec7805 100644 --- a/issue_template.md +++ b/issue_template.md @@ -1,24 +1,13 @@ - + + -For bug reports, please include the information below. -__________________________________________________________ --> - -**TypeScript Version:** - -1.7.5 / 1.8.0-beta / nightly (1.9.0-dev.20160217) +**TypeScript Version:** 1.8.0 / nightly (2.0.0-dev.201xxxxx) **Code** ```ts -// A self-contained demonstration of the problem follows... +// A *self-contained* demonstration of the problem follows... ``` diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 0879a3a9ee426..30f0e74adb434 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4545,8 +4545,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } write(";"); - tempIndex++; } + // Regardless of whether we will emit a var declaration for the binding pattern, we generate the temporary + // variable for the parameter (see: emitParameter) + tempIndex++; } else if (initializer) { writeLine(); diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index bae2977c44ae8..a42abbbc60909 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -324,6 +324,7 @@ namespace FourSlash { InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, + InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, PlaceOpenBraceOnNewLineForFunctions: false, PlaceOpenBraceOnNewLineForControlBlocks: false, }; diff --git a/src/lib/scripthost.d.ts b/src/lib/scripthost.d.ts index 7faae06714c28..baf93f55d552b 100644 --- a/src/lib/scripthost.d.ts +++ b/src/lib/scripthost.d.ts @@ -276,3 +276,13 @@ interface VBArrayConstructor { } declare var VBArray: VBArrayConstructor; + +/** + * Automation date (VT_DATE) + */ +interface VarDate { } + +interface DateConstructor { + new (vd: VarDate): Date; + getVarDate: () => VarDate; +} \ No newline at end of file diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index e48d61920177f..092450e526c16 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1580,6 +1580,7 @@ namespace ts.server { InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, + InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, PlaceOpenBraceOnNewLineForFunctions: false, PlaceOpenBraceOnNewLineForControlBlocks: false, }); diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index b95b23cfca885..110ac9bf4eab3 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -225,6 +225,12 @@ namespace ts.formatting { public NoSpaceBeforeTemplateMiddleAndTail: Rule; public SpaceBeforeTemplateMiddleAndTail: Rule; + // No space after { and before } in JSX expression + public NoSpaceAfterOpenBraceInJsxExpression: Rule; + public SpaceAfterOpenBraceInJsxExpression: Rule; + public NoSpaceBeforeCloseBraceInJsxExpression: Rule; + public SpaceBeforeCloseBraceInJsxExpression: Rule; + constructor() { /// /// Common Rules @@ -316,7 +322,7 @@ namespace ts.formatting { // Add a space between statements. All keywords except (do,else,case) has open/close parens after them. // So, we have a rule to add a space for [),Any], [do,Any], [else,Any], and [case,Any] - this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNotForContext), RuleAction.Space)); + this.SpaceBetweenStatements = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNotForContext), RuleAction.Space)); // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. this.SpaceAfterTryFinally = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword]), SyntaxKind.OpenBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); @@ -444,8 +450,8 @@ namespace ts.formatting { /// // Insert space after comma delimiter - this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space)); - this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); + this.SpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext, Rules.IsNextTokenNotCloseBracket), RuleAction.Space)); + this.NoSpaceAfterComma = new Rule(RuleDescriptor.create3(SyntaxKind.CommaToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isNonJsxElementContext), RuleAction.Delete)); // Insert space before and after binary operators this.SpaceBeforeBinaryOperator = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.BinaryOperators), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsBinaryOpContext), RuleAction.Space)); @@ -491,6 +497,12 @@ namespace ts.formatting { this.NoSpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); this.SpaceBeforeTemplateMiddleAndTail = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.TemplateMiddle, SyntaxKind.TemplateTail])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); + // No space after { and before } in JSX expression + this.NoSpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete)); + this.SpaceAfterOpenBraceInJsxExpression = new Rule(RuleDescriptor.create3(SyntaxKind.OpenBraceToken, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space)); + this.NoSpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Delete)); + this.SpaceBeforeCloseBraceInJsxExpression = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.CloseBraceToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.isJsxExpressionContext), RuleAction.Space)); + // Insert space after function keyword for anonymous functions this.SpaceAfterAnonymousFunctionKeyword = new Rule(RuleDescriptor.create1(SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space)); 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 { return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText; } + static isNonJsxElementContext(context: FormattingContext): boolean { + return context.contextNode.kind !== SyntaxKind.JsxElement; + } + + static isJsxExpressionContext(context: FormattingContext): boolean { + return context.contextNode.kind === SyntaxKind.JsxExpression; + } + static IsNotBeforeBlockInFunctionDeclarationContext(context: FormattingContext): boolean { return !Rules.IsFunctionDeclContext(context) && !Rules.IsBeforeBlockContext(context); } diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts index d672a401d89d8..1be0f9e912d2e 100644 --- a/src/services/formatting/rulesProvider.ts +++ b/src/services/formatting/rulesProvider.ts @@ -90,6 +90,15 @@ namespace ts.formatting { rules.push(this.globalRules.NoSpaceBeforeTemplateMiddleAndTail); } + if (options.InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces) { + rules.push(this.globalRules.SpaceAfterOpenBraceInJsxExpression); + rules.push(this.globalRules.SpaceBeforeCloseBraceInJsxExpression); + } + else { + rules.push(this.globalRules.NoSpaceAfterOpenBraceInJsxExpression); + rules.push(this.globalRules.NoSpaceBeforeCloseBraceInJsxExpression); + } + if (options.InsertSpaceAfterSemicolonInForStatements) { rules.push(this.globalRules.SpaceAfterSemicolonInFor); } diff --git a/src/services/services.ts b/src/services/services.ts index a17d9feed2485..529ce8a7bf7d5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1267,6 +1267,7 @@ namespace ts { InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean; + InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; [s: string]: boolean | number | string | undefined; diff --git a/tests/baselines/reference/destructuringParameterDeclaration7ES5.js b/tests/baselines/reference/destructuringParameterDeclaration7ES5.js new file mode 100644 index 0000000000000..f9dac1ae2fabe --- /dev/null +++ b/tests/baselines/reference/destructuringParameterDeclaration7ES5.js @@ -0,0 +1,27 @@ +//// [destructuringParameterDeclaration7ES5.ts] + +interface ISomething { + foo: string, + bar: string +} + +function foo({}, {foo, bar}: ISomething) {} + +function baz([], {foo, bar}: ISomething) {} + +function one([], {}) {} + +function two([], [a, b, c]: number[]) {} + + +//// [destructuringParameterDeclaration7ES5.js] +function foo(_a, _b) { + var foo = _b.foo, bar = _b.bar; +} +function baz(_a, _b) { + var foo = _b.foo, bar = _b.bar; +} +function one(_a, _b) { } +function two(_a, _b) { + var a = _b[0], b = _b[1], c = _b[2]; +} diff --git a/tests/baselines/reference/destructuringParameterDeclaration7ES5.symbols b/tests/baselines/reference/destructuringParameterDeclaration7ES5.symbols new file mode 100644 index 0000000000000..44709f18e1b2b --- /dev/null +++ b/tests/baselines/reference/destructuringParameterDeclaration7ES5.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration7ES5.ts === + +interface ISomething { +>ISomething : Symbol(ISomething, Decl(destructuringParameterDeclaration7ES5.ts, 0, 0)) + + foo: string, +>foo : Symbol(ISomething.foo, Decl(destructuringParameterDeclaration7ES5.ts, 1, 22)) + + bar: string +>bar : Symbol(ISomething.bar, Decl(destructuringParameterDeclaration7ES5.ts, 2, 16)) +} + +function foo({}, {foo, bar}: ISomething) {} +>foo : Symbol(foo, Decl(destructuringParameterDeclaration7ES5.ts, 4, 1)) +>foo : Symbol(foo, Decl(destructuringParameterDeclaration7ES5.ts, 6, 18)) +>bar : Symbol(bar, Decl(destructuringParameterDeclaration7ES5.ts, 6, 22)) +>ISomething : Symbol(ISomething, Decl(destructuringParameterDeclaration7ES5.ts, 0, 0)) + +function baz([], {foo, bar}: ISomething) {} +>baz : Symbol(baz, Decl(destructuringParameterDeclaration7ES5.ts, 6, 43)) +>foo : Symbol(foo, Decl(destructuringParameterDeclaration7ES5.ts, 8, 18)) +>bar : Symbol(bar, Decl(destructuringParameterDeclaration7ES5.ts, 8, 22)) +>ISomething : Symbol(ISomething, Decl(destructuringParameterDeclaration7ES5.ts, 0, 0)) + +function one([], {}) {} +>one : Symbol(one, Decl(destructuringParameterDeclaration7ES5.ts, 8, 43)) + +function two([], [a, b, c]: number[]) {} +>two : Symbol(two, Decl(destructuringParameterDeclaration7ES5.ts, 10, 23)) +>a : Symbol(a, Decl(destructuringParameterDeclaration7ES5.ts, 12, 18)) +>b : Symbol(b, Decl(destructuringParameterDeclaration7ES5.ts, 12, 20)) +>c : Symbol(c, Decl(destructuringParameterDeclaration7ES5.ts, 12, 23)) + diff --git a/tests/baselines/reference/destructuringParameterDeclaration7ES5.types b/tests/baselines/reference/destructuringParameterDeclaration7ES5.types new file mode 100644 index 0000000000000..7d64383b0b668 --- /dev/null +++ b/tests/baselines/reference/destructuringParameterDeclaration7ES5.types @@ -0,0 +1,33 @@ +=== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration7ES5.ts === + +interface ISomething { +>ISomething : ISomething + + foo: string, +>foo : string + + bar: string +>bar : string +} + +function foo({}, {foo, bar}: ISomething) {} +>foo : ({}: {}, {foo, bar}: ISomething) => void +>foo : string +>bar : string +>ISomething : ISomething + +function baz([], {foo, bar}: ISomething) {} +>baz : ([]: any[], {foo, bar}: ISomething) => void +>foo : string +>bar : string +>ISomething : ISomething + +function one([], {}) {} +>one : ([]: any[], {}: {}) => void + +function two([], [a, b, c]: number[]) {} +>two : ([]: any[], [a, b, c]: number[]) => void +>a : number +>b : number +>c : number + diff --git a/tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration7ES5.ts b/tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration7ES5.ts new file mode 100644 index 0000000000000..97822e92e2dba --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration7ES5.ts @@ -0,0 +1,14 @@ +// @target: es5 + +interface ISomething { + foo: string, + bar: string +} + +function foo({}, {foo, bar}: ISomething) {} + +function baz([], {foo, bar}: ISomething) {} + +function one([], {}) {} + +function two([], [a, b, c]: number[]) {} diff --git a/tests/cases/fourslash/formattingJsxElements.ts b/tests/cases/fourslash/formattingJsxElements.ts index fbe4bb5d29ed4..e07149960dba9 100644 --- a/tests/cases/fourslash/formattingJsxElements.ts +++ b/tests/cases/fourslash/formattingJsxElements.ts @@ -9,7 +9,7 @@ //// //// ) ////} -//// +//// ////function foo1() { //// return ( ////
@@ -45,8 +45,8 @@ //// class3= {/*5*/ //// }/>/*6*/ //// ) -////} -//// +////} +//// ////(function () { //// return
/*grandchildJsxElementAutoformat*/ /////*containedClosingTagAutoformat*/ -//// +////; +//// +////
,{integer}
;/*commaInJsxElement*/ +////
, {integer}
;/*commaInJsxElement2*/ +////);/*closingParenInJsxElement*/ +////) ;/*closingParenInJsxElement2*/ +////;/*jsxExpressionSpaces*/ +////;/*jsxExpressionSpaces2*/ format.document(); goTo.marker("autoformat"); @@ -114,7 +121,7 @@ verify.indentationIs(12); goTo.marker("danglingBracketAutoformat") // TODO: verify.currentLineContentIs(" >"); -verify.currentLineContentIs(" >"); +verify.currentLineContentIs(" >"); goTo.marker("closingTagAutoformat"); verify.currentLineContentIs("
"); @@ -125,4 +132,17 @@ verify.indentationIs(8); goTo.marker("grandchildJsxElementAutoformat"); verify.currentLineContentIs(" "); goTo.marker("containedClosingTagAutoformat"); -verify.currentLineContentIs(" "); \ No newline at end of file +verify.currentLineContentIs(" "); + +goTo.marker("commaInJsxElement"); +verify.currentLineContentIs("
,{integer}
;"); +goTo.marker("commaInJsxElement2"); +verify.currentLineContentIs("
, {integer}
;"); +goTo.marker("closingParenInJsxElement"); +verify.currentLineContentIs(");"); +goTo.marker("closingParenInJsxElement2"); +verify.currentLineContentIs(") ;"); +goTo.marker("jsxExpressionSpaces"); +verify.currentLineContentIs(";"); +goTo.marker("jsxExpressionSpaces2"); +verify.currentLineContentIs(";"); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingOptionsChangeJsx.ts b/tests/cases/fourslash/formattingOptionsChangeJsx.ts new file mode 100644 index 0000000000000..a3c7e28a1ef7e --- /dev/null +++ b/tests/cases/fourslash/formattingOptionsChangeJsx.ts @@ -0,0 +1,32 @@ +/// + +//@Filename: file.tsx +/////*InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces*/; + +runTest("InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces", ";", ";"); + + +function runTest(propertyName: string, expectedStringWhenTrue: string, expectedStringWhenFalse: string) { + // Go to the correct file + goTo.marker(propertyName); + + // Set the option to false first + format.setOption(propertyName, false); + + // Format + format.document(); + + // Verify + goTo.marker(propertyName); + verify.currentLineContentIs(expectedStringWhenFalse); + + // Set the option to true + format.setOption(propertyName, true); + + // Format + format.document(); + + // Verify + goTo.marker(propertyName); + verify.currentLineContentIs(expectedStringWhenTrue); +} \ No newline at end of file