diff --git a/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/CurlyBraceCompletionSession.cs b/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/CurlyBraceCompletionSession.cs index b72e1198ee251d6b9b13448c575af3df9305a2c2..b74d65202526be1de82767ddfb225df644852521 100644 --- a/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/CurlyBraceCompletionSession.cs +++ b/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/CurlyBraceCompletionSession.cs @@ -187,12 +187,39 @@ private int GetDesiredIndentation(IBraceCompletionSession session, ITextSnapshot return openingPoint - openingSpanLine.Start; } - private class BraceCompletionFormattingRule : AbstractFormattingRule + private class BraceCompletionFormattingRule : BaseFormattingRule { private static readonly Predicate s_predicate = o => o == null || o.Option.IsOn(SuppressOption.NoWrapping); public static readonly IFormattingRule Instance = new BraceCompletionFormattingRule(); + public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken previousToken, SyntaxToken currentToken, OptionSet optionSet, NextOperation nextOperation) + { + // Eg Cases - + // new MyObject { + // new List { + // int[] arr = { + // = new[] { + // = new int[] { + if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentToken.Parent != null && + (currentToken.Parent.Kind() == SyntaxKind.ObjectInitializerExpression || + currentToken.Parent.Kind() == SyntaxKind.CollectionInitializerExpression || + currentToken.Parent.Kind() == SyntaxKind.ArrayInitializerExpression || + currentToken.Parent.Kind() == SyntaxKind.ImplicitArrayCreationExpression)) + { + if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers)) + { + return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines); + } + else + { + return null; + } + } + + return base.GetAdjustNewLinesOperation(previousToken, currentToken, optionSet, nextOperation); + } + public override void AddSuppressOperations(List list, SyntaxNode node, OptionSet optionSet, NextAction nextOperation) { base.AddSuppressOperations(list, node, optionSet, nextOperation); @@ -200,24 +227,9 @@ public override void AddSuppressOperations(List list, SyntaxN // remove suppression rules for array and collection initializer if (node.IsInitializerForArrayOrCollectionCreationExpression()) { - if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectInitializers)) - { // remove any suppression operation list.RemoveAll(s_predicate); } - else - { - // remove only space suppression operation. - for (var i = 0; i < list.Count; i++) - { - var operation = list[i]; - if (operation.Option.IsMaskOn(SuppressOption.NoSpacing)) - { - list[i] = FormattingOperations.CreateSuppressOperation(operation.StartToken, operation.EndToken, operation.Option & ~SuppressOption.NoSpacing); - } - } - } - } } } } diff --git a/src/EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatter.cs b/src/EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatter.cs index 6b2f35d8b11e21a26fcef19c5ab5b87ad4627464..187ce11a0905aabd8c7c15f1207376dd6431c11a 100644 --- a/src/EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatter.cs +++ b/src/EditorFeatures/CSharp/Formatting/Indentation/SmartTokenFormatter.cs @@ -113,10 +113,6 @@ public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken p private class SmartTokenFormattingRule : NoLineChangeFormattingRule { - public SmartTokenFormattingRule() - { - } - public override void AddSuppressOperations(List list, SyntaxNode node, OptionSet optionSet, NextAction nextOperation) { // don't suppress anything diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBraceCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBraceCompletionTests.cs index d7dcfc6a80252f7aee47d367ec666483c52e9ad7..dd038dd2f19a173b6b5a5309852b4c3a42fadb77 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBraceCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBraceCompletionTests.cs @@ -1,6 +1,7 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; @@ -403,6 +404,359 @@ class C } } + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void Collection_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"using System.Collections.Generic; + +class C +{ + public void man() + { + List list = new List $$ + } +}"; + + var expected = @"using System.Collections.Generic; + +class C +{ + public void man() + { + List list = new List { + + } + } +}"; + var optionSet = new Dictionary + { + { CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, false } + }; + using (var session = CreateSession(code, optionSet)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void Collection_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"using System.Collections.Generic; + +class C +{ + public void man() + { + List list = new List $$ + } +}"; + + var expected = @"using System.Collections.Generic; + +class C +{ + public void man() + { + List list = new List + { + + } + } +}"; + using (var session = CreateSession(code)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void Object_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"class C +{ + public void man() + { + var foo = new Foo $$ + } +} + +class Foo +{ + public int bar; +}"; + + var expected = @"class C +{ + public void man() + { + var foo = new Foo { + + } + } +} + +class Foo +{ + public int bar; +}"; + var optionSet = new Dictionary + { + { CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, false } + }; + using (var session = CreateSession(code, optionSet)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void Object_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"class C +{ + public void man() + { + var foo = new Foo $$ + } +} + +class Foo +{ + public int bar; +}"; + + var expected = @"class C +{ + public void man() + { + var foo = new Foo + { + + } + } +} + +class Foo +{ + public int bar; +}"; + using (var session = CreateSession(code)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void ArrayImplicit_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"class C +{ + public void man() + { + int[] arr = $$ + } +}"; + + var expected = @"class C +{ + public void man() + { + int[] arr = { + + } + } +}"; + var optionSet = new Dictionary + { + { CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, false } + }; + using (var session = CreateSession(code, optionSet)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void ArrayImplicit_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"class C +{ + public void man() + { + int[] arr = $$ + } +}"; + + var expected = @"class C +{ + public void man() + { + int[] arr = + { + + } + } +}"; + using (var session = CreateSession(code)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void ArrayExplicit1_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"class C +{ + public void man() + { + int[] arr = new[] $$ + } +}"; + + var expected = @"class C +{ + public void man() + { + int[] arr = new[] { + + } + } +}"; + var optionSet = new Dictionary + { + { CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, false } + }; + using (var session = CreateSession(code, optionSet)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void ArrayExplicit1_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"class C +{ + public void man() + { + int[] arr = new[] $$ + } +}"; + + var expected = @"class C +{ + public void man() + { + int[] arr = new[] + { + + } + } +}"; + using (var session = CreateSession(code)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void ArrayExplicit2_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"class C +{ + public void man() + { + int[] arr = new int[] $$ + } +}"; + + var expected = @"class C +{ + public void man() + { + int[] arr = new int[] { + + } + } +}"; + var optionSet = new Dictionary + { + { CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, false } + }; + using (var session = CreateSession(code, optionSet)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + + [WorkItem(1070773)] + [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] + public void ArrayExplicit2_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"class C +{ + public void man() + { + int[] arr = new int[] $$ + } +}"; + + var expected = @"class C +{ + public void man() + { + int[] arr = new int[] + { + + } + } +}"; + using (var session = CreateSession(code)) + { + Assert.NotNull(session); + + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } + } + [WorkItem(850540)] [Fact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] public void BlockIndentationWithAutomaticBraceFormattingDisabled() diff --git a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs index c50ec033a9c3ce713b4aad4dd5cdbffe155795e6..efc84e77850a7990cf92f973dd3922edf34fcd0e 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Linq; using System.Threading; @@ -663,6 +663,7 @@ public void Class1() } [Fact] + [WorkItem(1070773)] [Trait(Traits.Feature, Traits.Features.SmartIndent)] public void ArrayInitializer1() { @@ -672,9 +673,8 @@ public void ArrayInitializer1() { 1, 2, 3 } } "; - AssertIndentUsingSmartTokenFormatter( + AssertIndentNotUsingSmartTokenFormatterButUsingIndenter( code, - '{', indentationLine: 3, expectedIndentation: 4); } @@ -698,6 +698,27 @@ public void ArrayInitializer2() expectedIndentation: 4); } + [Fact] + [WorkItem(1070773)] + [Trait(Traits.Feature, Traits.Features.SmartTokenFormatting)] + public void ArrayInitializer3() + { + var code = @"namespace NS +{ + class Class + { + void Method(int i) + { + var a = new [] +{ + }"; + + AssertIndentNotUsingSmartTokenFormatterButUsingIndenter( + code, + indentationLine: 7, + expectedIndentation: 12); + } + [Fact] [Trait(Traits.Feature, Traits.Features.SmartIndent)] public void QueryExpression2() @@ -781,6 +802,7 @@ void Method() [Fact] [WorkItem(939305)] + [WorkItem(1070773)] [Trait(Traits.Feature, Traits.Features.SmartIndent)] public void ArrayExpression() { @@ -789,7 +811,7 @@ public void ArrayExpression() void M(object[] q) { M( - q: new object[] + q: new object[] { }); } } @@ -797,6 +819,55 @@ void M(object[] q) AssertIndentNotUsingSmartTokenFormatterButUsingIndenter( code, indentationLine: 6, + expectedIndentation: 14); + } + + [Fact] + [WorkItem(1070773)] + [Trait(Traits.Feature, Traits.Features.SmartIndent)] + public void CollectionExpression() + { + var code = @"class C +{ + void M(List e) + { + M( + new List +{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); + } +} +"; + AssertIndentUsingSmartTokenFormatter( + code, + '{', + indentationLine: 6, + expectedIndentation: 12); + } + + [Fact] + [WorkItem(1070773)] + [Trait(Traits.Feature, Traits.Features.SmartIndent)] + public void ObjectInitializer() + { + var code = @"class C +{ + void M(What dd) + { + M( + new What +{ d = 3, dd = "" }); + } +} + +class What +{ + public int d; + public string dd; +}"; + AssertIndentUsingSmartTokenFormatter( + code, + '{', + indentationLine: 6, expectedIndentation: 12); } diff --git a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatTokenTests.cs b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatTokenTests.cs index 0e147d275bc84883dcb4a553e6d75d51138d4630..8e82f31acf594ddaf8e7a8bd48b7ba90780dcd97 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatTokenTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatTokenTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.ComponentModel.Composition.Hosting; using System.Linq; @@ -383,26 +383,6 @@ void Method(int i) indentationLine: 6); } - [Fact] - [Trait(Traits.Feature, Traits.Features.SmartTokenFormatting)] - public void ArrayInitializer2() - { - var code = @"namespace NS -{ - class Class - { - void Method(int i) - { - var a = new [] -{ - }"; - - AssertSmartTokenFormatterOpenBrace( - code, - indentationLine: 7, - expectedSpace: 12); - } - [Fact] [WorkItem(537827)] [Trait(Traits.Feature, Traits.Features.SmartTokenFormatting)] diff --git a/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs b/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs index 361edd3b94d77dc83087fec776f9cb8e76688635..8271c3cd4d019dcedc789cba81559dfb1ba00ef7 100644 --- a/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs +++ b/src/VisualStudio/CSharp/Impl/CSharpVSResources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.35312 +// Runtime Version:4.0.30319.0 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -331,11 +331,11 @@ internal class CSharpVSResources { } /// - /// Looks up a localized string similar to Place open brace on new line for object initializers. + /// Looks up a localized string similar to Place open brace on new line for object, collection and array initializers. /// - internal static string NewLinesForBracesInObjectInitializers { + internal static string NewLinesForBracesInObjectCollectionArrayInitializers { get { - return ResourceManager.GetString("NewLinesForBracesInObjectInitializers", resourceCulture); + return ResourceManager.GetString("NewLinesForBracesInObjectCollectionArrayInitializers", resourceCulture); } } diff --git a/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx b/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx index ca9966032e69023e8496497c38d7210c66b6f75b..410e8aa0206d97688fce66866c6550301cad9ea0 100644 --- a/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx +++ b/src/VisualStudio/CSharp/Impl/CSharpVSResources.resx @@ -192,8 +192,8 @@ Place open brace on new line for methods - - Place open brace on new line for object initializers + + Place open brace on new line for object, collection and array initializers Place open brace on new line for types diff --git a/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs b/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs index a840cc3cd111f3ac4c29911642db4a5329b945a4..16747bc468a6108daf72c793a8b327ad3690e4f1 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs +++ b/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs @@ -196,8 +196,8 @@ public int NewLines_Braces_Method public int NewLines_Braces_ObjectInitializer { - get { return GetBooleanOption(CSharpFormattingOptions.NewLineForMembersInObjectInit); } - set { SetBooleanOption(CSharpFormattingOptions.NewLineForMembersInObjectInit, value); } + get { return GetBooleanOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers); } + set { SetBooleanOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, value); } } public int NewLines_Braces_Type diff --git a/src/VisualStudio/CSharp/Impl/Options/CSharpSettingStoreOptionSerializer.cs b/src/VisualStudio/CSharp/Impl/Options/CSharpSettingStoreOptionSerializer.cs index a099cdbb8abee32f7c1d09869a4a4ab6483016ed..384c64964443125e85c363dd0feb5b1bf73d7e0a 100644 --- a/src/VisualStudio/CSharp/Impl/Options/CSharpSettingStoreOptionSerializer.cs +++ b/src/VisualStudio/CSharp/Impl/Options/CSharpSettingStoreOptionSerializer.cs @@ -62,7 +62,7 @@ public CSharpSettingStoreOptionSerializer(SVsServiceProvider serviceProvider) { CSharpFormattingOptions.NewLinesForBracesInControlBlocks, nameof(AutomationObject.NewLines_Braces_ControlFlow) }, { CSharpFormattingOptions.NewLinesForBracesInAnonymousMethods, nameof(AutomationObject.NewLines_Braces_AnonymousMethod) }, { CSharpFormattingOptions.NewLinesForBracesInAnonymousTypes, nameof(AutomationObject.NewLines_Braces_AnonymousTypeInitializer) }, - { CSharpFormattingOptions.NewLinesForBracesInObjectInitializers, nameof(AutomationObject.NewLines_Braces_ObjectInitializer) }, + { CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, nameof(AutomationObject.NewLines_Braces_ObjectInitializer) }, { CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody, nameof(AutomationObject.NewLines_Braces_LambdaExpressionBody) }, { CSharpFormattingOptions.NewLineForElse, nameof(AutomationObject.NewLines_Keywords_Else) }, { CSharpFormattingOptions.NewLineForCatch, nameof(AutomationObject.NewLines_Keywords_Catch) }, diff --git a/src/VisualStudio/CSharp/Impl/Options/Formatting/NewLinesViewModel.cs b/src/VisualStudio/CSharp/Impl/Options/Formatting/NewLinesViewModel.cs index cce9c1a648d06ac59b870a814f466f9f37a74900..1af9cc4b6de672bfde49ec63d6ef37de0b8b57cc 100644 --- a/src/VisualStudio/CSharp/Impl/Options/Formatting/NewLinesViewModel.cs +++ b/src/VisualStudio/CSharp/Impl/Options/Formatting/NewLinesViewModel.cs @@ -97,6 +97,59 @@ class C { }; //] } +}"; + private static readonly string s_InitializerPreviewTrue = @"using System; +using System.Collections.Generic; + +class C { + void Foo() { +//[ + var z = new B() + { + A = 3, B = 4 + }; + + // During Brace Completion or Only if Empty Body + var collectionVariable = new List + { + } + + // During Brace Completion + var arrayVariable = new int[] + { + } +//] + } +} + +class B { + public int A { get; set; } + public int B { get; set; } +}"; + private static readonly string s_InitializerPreviewFalse = @"using System; +using System.Collections.Generic; + +class C { + void Foo() { +//[ + var z = new B() { + A = 3, B = 4 + }; + + // During Brace Completion or Only if Empty Body + var collectionVariable = new List { + } + + // During Brace Completion + var arrayVariable = new int[] { + } +//] + } +} + +class B { + public int A { get; set; } + public int B { get; set; } }"; private static readonly string s_objectInitializerPreview = @"using System; class C { @@ -129,27 +182,27 @@ class B { }"; public NewLinesViewModel(OptionSet options, IServiceProvider serviceProvider) : base(options, serviceProvider, LanguageNames.CSharp) - { - Items.Add(new HeaderItemViewModel() { Header = CSharpVSResources.NewLineBraces }); + { + Items.Add(new HeaderItemViewModel() { Header = CSharpVSResources.NewLineBraces }); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLinesForBracesInTypes, CSharpVSResources.NewLinesBracesType, s_previewText, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLinesForBracesInMethods, CSharpVSResources.NewLinesForBracesMethod, s_methodPreview, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLinesForBracesInAnonymousMethods, CSharpVSResources.NewLinesForBracesInAnonymousMethods, s_anonymousMethodPreview, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLinesForBracesInControlBlocks, CSharpVSResources.NewLinesForBracesInControlBlocks, s_forBlockPreview, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLinesForBracesInAnonymousTypes, CSharpVSResources.NewLinesForBracesInAnonymousTypes, s_anonymousTypePreview, this, options)); - Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLinesForBracesInObjectInitializers, CSharpVSResources.NewLinesForBracesInObjectInitializers, s_objectInitializerPreview, this, options)); + Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, CSharpVSResources.NewLinesForBracesInObjectCollectionArrayInitializers, s_InitializerPreviewTrue, s_InitializerPreviewFalse, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody, CSharpVSResources.NewLinesForBracesInLambdaExpressionBody, s_lambdaPreview, this, options)); - Items.Add(new HeaderItemViewModel() { Header = CSharpVSResources.NewLineKeywords }); + Items.Add(new HeaderItemViewModel() { Header = CSharpVSResources.NewLineKeywords }); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLineForElse, CSharpVSResources.ElseOnNewLine, s_ifElsePreview, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLineForCatch, CSharpVSResources.CatchOnNewLine, s_tryCatchFinallyPreview, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLineForFinally, CSharpVSResources.FinallyOnNewLine, s_tryCatchFinallyPreview, this, options)); - Items.Add(new HeaderItemViewModel() { Header = CSharpVSResources.NewLineExpressions }); + Items.Add(new HeaderItemViewModel() { Header = CSharpVSResources.NewLineExpressions }); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLineForMembersInObjectInit, CSharpVSResources.NewLineForMembersInObjectInit, s_objectInitializerPreview, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLineForMembersInAnonymousTypes, CSharpVSResources.NewLineForMembersInAnonymousTypes, s_anonymousTypePreview, this, options)); Items.Add(new CheckBoxOptionViewModel(CSharpFormattingOptions.NewLineForClausesInQuery, CSharpVSResources.NewLineForClausesInQuery, s_queryExpressionPreview, this, options)); + } } } -} diff --git a/src/Workspaces/CSharp/Portable/Formatting/CSharpFormattingOptions.cs b/src/Workspaces/CSharp/Portable/Formatting/CSharpFormattingOptions.cs index 88cd5fc713c2070cd2c29041826278f49f6e4ef5..4c8101f4b31bb937a8e44397d6dd927b81984fed 100644 --- a/src/Workspaces/CSharp/Portable/Formatting/CSharpFormattingOptions.cs +++ b/src/Workspaces/CSharp/Portable/Formatting/CSharpFormattingOptions.cs @@ -83,7 +83,7 @@ public static class CSharpFormattingOptions public static readonly Option NewLinesForBracesInAnonymousTypes = new Option(NewLineFormattingFeatureName, "NewLinesForBracesInAnonymousTypes", defaultValue: true); - public static readonly Option NewLinesForBracesInObjectInitializers = new Option(NewLineFormattingFeatureName, "NewLinesForBracesInObjectInitializers", defaultValue: true); + public static readonly Option NewLinesForBracesInObjectCollectionArrayInitializers = new Option(NewLineFormattingFeatureName, "NewLinesForBracesInObjectCollectionArrayInitializers", defaultValue: true); public static readonly Option NewLinesForBracesInLambdaExpressionBody = new Option(NewLineFormattingFeatureName, "NewLinesForBracesInLambdaExpressionBody", defaultValue: true); diff --git a/src/Workspaces/CSharp/Portable/Formatting/CSharpFormattingOptionsProvider.cs b/src/Workspaces/CSharp/Portable/Formatting/CSharpFormattingOptionsProvider.cs index b2808b7848b576a5a8433e495d9bb3d5d72e2cdd..01d672c709acdc7633efdcfe08ca9e4271b98752 100644 --- a/src/Workspaces/CSharp/Portable/Formatting/CSharpFormattingOptionsProvider.cs +++ b/src/Workspaces/CSharp/Portable/Formatting/CSharpFormattingOptionsProvider.cs @@ -49,7 +49,7 @@ internal class CSharpFormattingOptionsProvider : IOptionProvider CSharpFormattingOptions.NewLinesForBracesInAnonymousMethods, CSharpFormattingOptions.NewLinesForBracesInControlBlocks, CSharpFormattingOptions.NewLinesForBracesInAnonymousTypes, - CSharpFormattingOptions.NewLinesForBracesInObjectInitializers, + CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody, CSharpFormattingOptions.NewLineForElse, CSharpFormattingOptions.NewLineForCatch, diff --git a/src/Workspaces/CSharp/Portable/Formatting/Rules/IndentBlockFormattingRule.cs b/src/Workspaces/CSharp/Portable/Formatting/Rules/IndentBlockFormattingRule.cs index c8f15357e362d909fe43fbf0097301de72161586..6dccb83ad328bb1566669717d2d95ab987319e63 100644 --- a/src/Workspaces/CSharp/Portable/Formatting/Rules/IndentBlockFormattingRule.cs +++ b/src/Workspaces/CSharp/Portable/Formatting/Rules/IndentBlockFormattingRule.cs @@ -137,8 +137,21 @@ private void AddAlignmentBlockOperation(List list, SyntaxN var anonymousObjectCreation = node as AnonymousObjectCreationExpressionSyntax; if (anonymousObjectCreation != null) { - var option = IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine; - SetAlignmentBlockOperation(list, anonymousObjectCreation.NewKeyword, anonymousObjectCreation.OpenBraceToken, anonymousObjectCreation.CloseBraceToken, option); + SetAlignmentBlockOperation(list, anonymousObjectCreation.NewKeyword, anonymousObjectCreation.OpenBraceToken, anonymousObjectCreation.CloseBraceToken, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine); + return; + } + + var arrayCreation = node as ArrayCreationExpressionSyntax; + if (arrayCreation != null && arrayCreation.Initializer != null) + { + SetAlignmentBlockOperation(list, arrayCreation.NewKeyword, arrayCreation.Initializer.OpenBraceToken, arrayCreation.Initializer.CloseBraceToken, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine); + return; + } + + var implicitArrayCreation = node as ImplicitArrayCreationExpressionSyntax; + if (implicitArrayCreation != null && implicitArrayCreation.Initializer != null) + { + SetAlignmentBlockOperation(list, implicitArrayCreation.NewKeyword, implicitArrayCreation.Initializer.OpenBraceToken, implicitArrayCreation.Initializer.CloseBraceToken, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine); return; } } diff --git a/src/Workspaces/CSharp/Portable/Formatting/Rules/NewLineUserSettingFormattingRule.cs b/src/Workspaces/CSharp/Portable/Formatting/Rules/NewLineUserSettingFormattingRule.cs index 956a5c07b869dd0390a057cb3e75e55720e838cd..38b21e76e94ddad90299d2a189f413cb506b390d 100644 --- a/src/Workspaces/CSharp/Portable/Formatting/Rules/NewLineUserSettingFormattingRule.cs +++ b/src/Workspaces/CSharp/Portable/Formatting/Rules/NewLineUserSettingFormattingRule.cs @@ -76,7 +76,7 @@ public override AdjustSpacesOperation GetAdjustSpacesOperation(SyntaxToken previ // new { - Object Initialization if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentToken.Parent != null && currentToken.Parent.IsKind(SyntaxKind.ObjectInitializerExpression)) { - if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectInitializers)) + if (!optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers)) { operation = CreateAdjustSpacesOperation(1, AdjustSpacesOption.ForceSpaces); } @@ -224,10 +224,13 @@ public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken p } } - // new { - Object Initialization - if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentToken.Parent != null && currentToken.Parent.Kind() == SyntaxKind.ObjectInitializerExpression) + // new MyObject { - Object Initialization + // new List { - Collection Initialization + if (currentToken.Kind() == SyntaxKind.OpenBraceToken && currentToken.Parent != null && + (currentToken.Parent.Kind() == SyntaxKind.ObjectInitializerExpression || + currentToken.Parent.Kind() == SyntaxKind.CollectionInitializerExpression)) { - if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectInitializers)) + if (optionSet.GetOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers)) { return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines); } @@ -237,6 +240,17 @@ public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken p } } + // Array Initialization Expression + // int[] arr = new int[] { + // new[] { + // { - Implicit Array + if (currentToken.IsKind(SyntaxKind.OpenBraceToken) && currentToken.Parent != null && + (currentToken.Parent.Kind() == SyntaxKind.ArrayInitializerExpression || + currentToken.Parent.Kind() == SyntaxKind.ImplicitArrayCreationExpression)) + { + return null; + } + var currentTokenParentParent = currentToken.Parent.Parent; // * { - in the member declaration context diff --git a/src/Workspaces/CSharp/Portable/Formatting/Rules/TokenBasedFormattingRule.cs b/src/Workspaces/CSharp/Portable/Formatting/Rules/TokenBasedFormattingRule.cs index 96e772377a33525a90f295a90c8382edf0b3449b..de449c44b56e18d2702be4252bf443a4e69d997a 100644 --- a/src/Workspaces/CSharp/Portable/Formatting/Rules/TokenBasedFormattingRule.cs +++ b/src/Workspaces/CSharp/Portable/Formatting/Rules/TokenBasedFormattingRule.cs @@ -27,7 +27,7 @@ public override AdjustNewLinesOperation GetAdjustNewLinesOperation(SyntaxToken p return null; } - if (!previousToken.IsParenInParenthesizedExpression() && previousToken.Parent != null && !previousToken.Parent.IsKind(SyntaxKind.ArrayRankSpecifier)) + if (!previousToken.IsParenInParenthesizedExpression()) { return CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.PreserveLines); } diff --git a/src/Workspaces/CSharp/Portable/PublicAPI.txt b/src/Workspaces/CSharp/Portable/PublicAPI.txt index 751e26a0018e6d81498725f55a4d17d02632034b..bef9f7c9c3223caee6d79eaed21c177629f869a4 100644 --- a/src/Workspaces/CSharp/Portable/PublicAPI.txt +++ b/src/Workspaces/CSharp/Portable/PublicAPI.txt @@ -23,7 +23,8 @@ static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions.NewLinesForBracesInControlBlocks static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions.NewLinesForBracesInMethods -static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions.NewLinesForBracesInObjectInitializers +static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers + static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions.NewLinesForBracesInTypes static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions.SpaceAfterCast static readonly Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions.SpaceAfterColonInBaseTypeDeclaration diff --git a/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs b/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs index a3e5736b7e457d3e81f8a869a570d7f0953ffcf2..6f053413c4cd2654b7c5f503d16cad65628c845e 100644 --- a/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs +++ b/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs @@ -951,7 +951,7 @@ public void nothing_again(Action a) public void RelativeIndentationToFirstTokenInBaseTokenWithObjectInitializers() { var changingOptions = new Dictionary(); - changingOptions.Add(CSharpFormattingOptions.NewLinesForBracesInObjectInitializers, false); + changingOptions.Add(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, false); AssertFormat(@"class Program { static void Main(string[] args) @@ -1516,7 +1516,7 @@ public void NewLineForOpenBracesNonDefault() changingOptions.Add(CSharpFormattingOptions.NewLinesForBracesInAnonymousMethods, false); changingOptions.Add(CSharpFormattingOptions.NewLinesForBracesInControlBlocks, false); changingOptions.Add(CSharpFormattingOptions.NewLinesForBracesInAnonymousTypes, false); - changingOptions.Add(CSharpFormattingOptions.NewLinesForBracesInObjectInitializers, false); + changingOptions.Add(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, false); changingOptions.Add(CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody, false); AssertFormat(@"class f00 { void br() {