From 131c88d63cf1fd0d32eb857bb496d0e7e86a7e86 Mon Sep 17 00:00:00 2001 From: Basoundr_ms Date: Tue, 3 Feb 2015 16:33:23 -0800 Subject: [PATCH] Fix Bug 1070773 - option "NewLinesForBracesInObjectCollectionArrayInitializers" will handle Collection, Array and Object Initializers Changing the New Line option "NewLinesForBracesInObjectInitializers" to "NewLinesForBracesInObjectCollectionArrayInitializers" which will now affect Collection Initializer and Array Initializers in addition to Object Initializers. Check Bug 853748 regarding this. This change does not affect the Custom formatted Array Initializers and Collection Initializers since we have appropriate Suppress operation. (changeset 1409656) --- .../Sessions/CurlyBraceCompletionSession.cs | 44 ++- .../Indentation/SmartTokenFormatter.cs | 4 - .../AutomaticBraceCompletionTests.cs | 356 +++++++++++++++++- .../SmartIndenterEnterOnTokenTests.cs | 79 +++- .../SmartTokenFormatterFormatTokenTests.cs | 22 +- .../CSharp/Impl/CSharpVSResources.Designer.cs | 8 +- .../CSharp/Impl/CSharpVSResources.resx | 4 +- .../CSharp/Impl/Options/AutomationObject.cs | 4 +- .../CSharpSettingStoreOptionSerializer.cs | 2 +- .../Options/Formatting/NewLinesViewModel.cs | 65 +++- .../Formatting/CSharpFormattingOptions.cs | 2 +- .../CSharpFormattingOptionsProvider.cs | 2 +- .../Rules/IndentBlockFormattingRule.cs | 17 +- .../Rules/NewLineUserSettingFormattingRule.cs | 22 +- .../Rules/TokenBasedFormattingRule.cs | 2 +- src/Workspaces/CSharp/Portable/PublicAPI.txt | 3 +- .../CSharpTest/Formatting/FormattingTests.cs | 4 +- 17 files changed, 567 insertions(+), 73 deletions(-) diff --git a/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/CurlyBraceCompletionSession.cs b/src/EditorFeatures/CSharp/AutomaticCompletion/Sessions/CurlyBraceCompletionSession.cs index b72e1198ee2..b74d6520252 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 6b2f35d8b11..187ce11a090 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 d7dcfc6a802..dd038dd2f19 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 c50ec033a9c..efc84e77850 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 0e147d275bc..8e82f31acf5 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 361edd3b94d..8271c3cd4d0 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 ca9966032e6..410e8aa0206 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 a840cc3cd11..16747bc468a 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 a099cdbb8ab..384c6496444 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 cce9c1a648d..1af9cc4b6de 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 88cd5fc713c..4c8101f4b31 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 b2808b7848b..01d672c709a 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 c8f15357e36..6dccb83ad32 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 956a5c07b86..38b21e76e94 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 96e772377a3..de449c44b56 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 751e26a0018..bef9f7c9c32 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 a3e5736b7e4..6f053413c4c 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() { -- GitLab