diff --git a/.github/workflows/main-merge.yml b/.github/workflows/main-merge.yml index 21dfaefe4cd4c..26d5cccb9be8e 100644 --- a/.github/workflows/main-merge.yml +++ b/.github/workflows/main-merge.yml @@ -1,18 +1,31 @@ -# Merges any changes from release/prerelease to main (e.g. servicing changes) +# See https://github.com/dotnet/arcade/blob/e52018a/Documentation/Maestro/New-Inter-Branch-Merge-Approach.md -name: Flow main to release/dev18.0 +name: Inter-branch merge on: schedule: - # once a day at 13:00 UTC to cleanup old runs - - cron: '0 13 * * *' + # Create a merge every 3 hours (works only for merges from `main`, others would need a `push` trigger). + - cron: '0 */3 * * *' workflow_dispatch: + inputs: + configuration_file_branch: + description: 'Branch to use for configuration file' + required: true + default: 'main' permissions: contents: write pull-requests: write jobs: - check-script: + # The config does not support multiple flows from the same source branch, + # so we need to run separately for each duplicate source branch (https://github.com/dotnet/arcade/issues/15586). + merge: uses: dotnet/arcade/.github/workflows/inter-branch-merge-base.yml@main with: - configuration_file_path: '.config/branch-merge.json' \ No newline at end of file + configuration_file_path: 'eng/config/branch-merge.jsonc' + configuration_file_branch: ${{ inputs.configuration_file_branch || 'main' }} + merge-2: + uses: dotnet/arcade/.github/workflows/inter-branch-merge-base.yml@main + with: + configuration_file_path: 'eng/config/branch-merge-2.jsonc' + configuration_file_branch: ${{ inputs.configuration_file_branch || 'main' }} diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1fe07fb69f12a..133dad722e492 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -8,9 +8,9 @@ - + https://github.com/dotnet/source-build-reference-packages - d794781cc75921b4ebbefe2eabdb0d6cd1713005 + 964c28e59a72516a64d4c8ff06b797703c5cdbfd diff --git a/eng/config/PublishData.json b/eng/config/PublishData.json index ec925049100ea..c813d3c6e3749 100644 --- a/eng/config/PublishData.json +++ b/eng/config/PublishData.json @@ -178,6 +178,16 @@ "insertionCreateDraftPR": true }, "main": { + "nugetKind": [ + "Shipping", + "NonShipping" + ], + "vsBranch": "main", + "vsMajorVersion": 17, + "insertionCreateDraftPR": true, + "insertionTitlePrefix": "[d17.14 P3]" + }, + "main-vs-deps": { "nugetKind": [ "Shipping", "NonShipping" diff --git a/eng/config/branch-merge-2.jsonc b/eng/config/branch-merge-2.jsonc new file mode 100644 index 0000000000000..cd979074b54a4 --- /dev/null +++ b/eng/config/branch-merge-2.jsonc @@ -0,0 +1,10 @@ +// Used by .github/workflows/main-merge.yml +{ + "merge-flow-configurations": { + // Merge any main changes to main-vs-deps. + "main": { + "MergeToBranch": "main-vs-deps", + "ExtraSwitches": "-QuietComments" + } + } +} diff --git a/.config/branch-merge.json b/eng/config/branch-merge.jsonc similarity index 82% rename from .config/branch-merge.json rename to eng/config/branch-merge.jsonc index 0b1db28cc334a..bd198290691b3 100644 --- a/.config/branch-merge.json +++ b/eng/config/branch-merge.jsonc @@ -1,3 +1,4 @@ +// Used by .github/workflows/main-merge.yml { "merge-flow-configurations": { // Merge any main changes to release/dev18.0. @@ -6,4 +7,4 @@ "ExtraSwitches": "-QuietComments" } } -} \ No newline at end of file +} diff --git a/src/Analyzers/CSharp/Analyzers/UseCollectionInitializer/CSharpUseCollectionInitializerAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseCollectionInitializer/CSharpUseCollectionInitializerAnalyzer.cs index fabc39b46613b..6a93604eb7369 100644 --- a/src/Analyzers/CSharp/Analyzers/UseCollectionInitializer/CSharpUseCollectionInitializerAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseCollectionInitializer/CSharpUseCollectionInitializerAnalyzer.cs @@ -48,8 +48,11 @@ protected override bool HasExistingInvalidInitializerForCollection() protected override bool AnalyzeMatchesAndCollectionConstructorForCollectionExpression( ArrayBuilder> preMatches, ArrayBuilder> postMatches, + out bool mayChangeSemantics, CancellationToken cancellationToken) { + mayChangeSemantics = false; + // Constructor wasn't called with any arguments. Nothing to validate. var argumentList = _objectCreationExpression.ArgumentList; if (argumentList is null || argumentList.Arguments.Count == 0) @@ -63,20 +66,21 @@ protected override bool AnalyzeMatchesAndCollectionConstructorForCollectionExpre if (this.SemanticModel.GetSymbolInfo(_objectCreationExpression, cancellationToken).Symbol is not IMethodSymbol { MethodKind: MethodKind.Constructor, - Parameters.Length: 1, + Parameters: [var firstParameter], } constructor) { return false; } - var ienumerableOfTType = this.SemanticModel.Compilation.IEnumerableOfTType(); - var firstParameter = constructor.Parameters[0]; - if (Equals(firstParameter.Type.OriginalDefinition, ienumerableOfTType) || - firstParameter.Type.AllInterfaces.Any(i => Equals(i.OriginalDefinition, ienumerableOfTType))) + if (CanSpreadFirstParameter(constructor.ContainingType, firstParameter)) { // Took a single argument that implements IEnumerable. We handle this by spreading that argument as the // first thing added to the collection. preMatches.Add(new(argumentList.Arguments[0].Expression, UseSpread: true)); + + // Can't be certain that spreading the elements will be the same as passing to the constructor. So pass + // that uncertainty up to the caller so they can inform the user. + mayChangeSemantics = true; return true; } else if (firstParameter is { Type.SpecialType: SpecialType.System_Int32, Name: "capacity" }) @@ -195,5 +199,36 @@ protected override bool AnalyzeMatchesAndCollectionConstructorForCollectionExpre } return false; + + bool CanSpreadFirstParameter(INamedTypeSymbol constructedType, IParameterSymbol firstParameter) + { + var compilation = this.SemanticModel.Compilation; + + var ienumerableOfTType = compilation.IEnumerableOfTType(); + if (!Equals(firstParameter.Type.OriginalDefinition, ienumerableOfTType) && + !firstParameter.Type.AllInterfaces.Any(i => Equals(i.OriginalDefinition, ienumerableOfTType))) + { + return false; + } + + // Looks like something passed to the constructor call that we could potentially spread instead. e.g. `new + // HashSet(someList)` can become `[.. someList]`. However, check for certain cases we know where this is + // wrong and we can't do this. + + // BlockingCollection and Collection both take ownership of the collection passed to them. So adds to + // them will add through to the original collection. They do not take the original collection and add their + // elements to itself. + + var collectionType = compilation.CollectionOfTType(); + var blockingCollectionType = compilation.BlockingCollectionOfTType(); + if (constructedType.GetBaseTypesAndThis().Any( + t => Equals(collectionType, t.OriginalDefinition) || + Equals(blockingCollectionType, t.OriginalDefinition))) + { + return false; + } + + return true; + } } } diff --git a/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs b/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs index d70e33ad6cbad..f33a25452afca 100644 --- a/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCollectionInitializer/UseCollectionInitializerTests.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.CSharp.UseCollectionInitializer; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Testing; using Roslyn.Test.Utilities; using Xunit; @@ -1826,4 +1827,42 @@ void M(List? list1) LanguageVersion = LanguageVersion.CSharp12, }.RunAsync(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/77416")] + public async Task TestNoCollectionExpressionForBlockingCollection() + { + await new VerifyCS.Test + { + TestCode = """ + using System; + using System.Collections.Concurrent; + + class A + { + public void Main(ConcurrentQueue queue) + { + BlockingCollection bc = [|new|](queue); + [|bc.Add(|]42); + } + } + """, + FixedCode = """ + using System; + using System.Collections.Concurrent; + + class A + { + public void Main(ConcurrentQueue queue) + { + BlockingCollection bc = new(queue) + { + 42 + }; + } + } + """, + LanguageVersion = LanguageVersion.CSharp13, + ReferenceAssemblies = ReferenceAssemblies.Net.Net90, + }.RunAsync(); + } } diff --git a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractObjectCreationExpressionAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractObjectCreationExpressionAnalyzer.cs index 5dee730834d73..bf5bda5a98644 100644 --- a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractObjectCreationExpressionAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractObjectCreationExpressionAnalyzer.cs @@ -37,7 +37,8 @@ internal abstract class AbstractObjectCreationExpressionAnalyzer< { public readonly record struct AnalysisResult( ImmutableArray PreMatches, - ImmutableArray PostMatches); + ImmutableArray PostMatches, + bool ChangesSemantics); protected UpdateExpressionState State; @@ -48,7 +49,7 @@ public readonly record struct AnalysisResult( protected SemanticModel SemanticModel => this.State.SemanticModel; protected abstract bool ShouldAnalyze(CancellationToken cancellationToken); - protected abstract bool TryAddMatches(ArrayBuilder preMatches, ArrayBuilder postMatches, CancellationToken cancellationToken); + protected abstract bool TryAddMatches(ArrayBuilder preMatches, ArrayBuilder postMatches, out bool changesSemantics, CancellationToken cancellationToken); protected abstract bool IsInitializerOfLocalDeclarationStatement( TLocalDeclarationStatementSyntax localDeclarationStatement, TObjectCreationExpressionSyntax rootExpression, [NotNullWhen(true)] out TVariableDeclaratorSyntax? variableDeclarator); @@ -87,10 +88,10 @@ protected AnalysisResult AnalyzeWorker(CancellationToken cancellationToken) using var _1 = ArrayBuilder.GetInstance(out var preMatches); using var _2 = ArrayBuilder.GetInstance(out var postMatches); - if (!TryAddMatches(preMatches, postMatches, cancellationToken)) + if (!TryAddMatches(preMatches, postMatches, out var mayChangeSemantics, cancellationToken)) return default; - return new(preMatches.ToImmutableAndClear(), postMatches.ToImmutableAndClear()); + return new(preMatches.ToImmutableAndClear(), postMatches.ToImmutableAndClear(), mayChangeSemantics); } protected UpdateExpressionState? TryInitializeState( diff --git a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerAnalyzer.cs index 1a8d7140e317b..e5093ced3782a 100644 --- a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerAnalyzer.cs @@ -50,7 +50,10 @@ internal abstract class AbstractUseCollectionInitializerAnalyzer< protected abstract bool IsComplexElementInitializer(SyntaxNode expression); protected abstract bool HasExistingInvalidInitializerForCollection(); protected abstract bool AnalyzeMatchesAndCollectionConstructorForCollectionExpression( - ArrayBuilder> preMatches, ArrayBuilder> postMatches, CancellationToken cancellationToken); + ArrayBuilder> preMatches, + ArrayBuilder> postMatches, + out bool mayChangeSemantics, + CancellationToken cancellationToken); protected abstract IUpdateExpressionSyntaxHelper SyntaxHelper { get; } @@ -66,7 +69,7 @@ public AnalysisResult Analyze( return default; this.Initialize(state.Value, objectCreationExpression, analyzeForCollectionExpression); - var (preMatches, postMatches) = this.AnalyzeWorker(cancellationToken); + var (preMatches, postMatches, mayChangeSemantics) = this.AnalyzeWorker(cancellationToken); // If analysis failed entirely, immediately bail out. if (preMatches.IsDefault || postMatches.IsDefault) @@ -81,15 +84,19 @@ public AnalysisResult Analyze( // other words, we don't want to suggest changing `new List()` to `new List() { }` as that's just // noise. So convert empty results to an invalid result here. if (analyzeForCollectionExpression) - return new(preMatches, postMatches); + return new(preMatches, postMatches, mayChangeSemantics); // Downgrade an empty result to a failure for the normal collection-initializer case. - return postMatches.IsEmpty ? default : new(preMatches, postMatches); + return postMatches.IsEmpty ? default : new(preMatches, postMatches, mayChangeSemantics); } protected sealed override bool TryAddMatches( - ArrayBuilder> preMatches, ArrayBuilder> postMatches, CancellationToken cancellationToken) + ArrayBuilder> preMatches, + ArrayBuilder> postMatches, + out bool mayChangeSemantics, + CancellationToken cancellationToken) { + mayChangeSemantics = false; var seenInvocation = false; var seenIndexAssignment = false; @@ -127,7 +134,10 @@ protected sealed override bool TryAddMatches( } if (_analyzeForCollectionExpression) - return AnalyzeMatchesAndCollectionConstructorForCollectionExpression(preMatches, postMatches, cancellationToken); + { + return AnalyzeMatchesAndCollectionConstructorForCollectionExpression( + preMatches, postMatches, out mayChangeSemantics, cancellationToken); + } return true; } diff --git a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs index 671b11f76ec94..d4410ebb3eaee 100644 --- a/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseCollectionInitializer/AbstractUseCollectionInitializerDiagnosticAnalyzer.cs @@ -68,10 +68,7 @@ public override DiagnosticAnalyzerCategory GetAnalyzerCategory() isUnnecessary: true); protected AbstractUseCollectionInitializerDiagnosticAnalyzer() - : base( - [ - (s_descriptor, CodeStyleOptions2.PreferCollectionInitializer) - ]) + : base([(s_descriptor, CodeStyleOptions2.PreferCollectionInitializer)]) { } @@ -117,9 +114,9 @@ private void OnCompilationStart(CompilationStartAnalysisContext context) // as a non-local diagnostic and would not participate in lightbulb for computing code fixes. var expressionType = context.Compilation.ExpressionOfTType(); context.RegisterCodeBlockStartAction(blockStartContext => - blockStartContext.RegisterSyntaxNodeAction( - nodeContext => AnalyzeNode(nodeContext, ienumerableType, expressionType), - matchKindsArray)); + blockStartContext.RegisterSyntaxNodeAction( + nodeContext => AnalyzeNode(nodeContext, ienumerableType, expressionType), + matchKindsArray)); } private void AnalyzeNode( @@ -206,13 +203,13 @@ private void AnalyzeNode( if (!preferInitializerOption.Value) return null; - var (_, matches) = analyzer.Analyze(semanticModel, syntaxFacts, objectCreationExpression, analyzeForCollectionExpression: false, cancellationToken); + var (_, matches, changesSemantics) = analyzer.Analyze(semanticModel, syntaxFacts, objectCreationExpression, analyzeForCollectionExpression: false, cancellationToken); // If analysis failed, we can't change this, no matter what. if (matches.IsDefault) return null; - return (matches, shouldUseCollectionExpression: false, changesSemantics: false); + return (matches, shouldUseCollectionExpression: false, changesSemantics); } (ImmutableArray> matches, bool shouldUseCollectionExpression, bool changesSemantics)? GetCollectionExpressionMatches() @@ -224,7 +221,7 @@ private void AnalyzeNode( if (!this.AreCollectionExpressionsSupported(context.Compilation)) return null; - var (preMatches, postMatches) = analyzer.Analyze(semanticModel, syntaxFacts, objectCreationExpression, analyzeForCollectionExpression: true, cancellationToken); + var (preMatches, postMatches, changesSemantics1) = analyzer.Analyze(semanticModel, syntaxFacts, objectCreationExpression, analyzeForCollectionExpression: true, cancellationToken); // If analysis failed, we can't change this, no matter what. if (preMatches.IsDefault || postMatches.IsDefault) @@ -232,10 +229,10 @@ private void AnalyzeNode( // Check if it would actually be legal to use a collection expression here though. var allowSemanticsChange = preferExpressionOption.Value == CollectionExpressionPreference.WhenTypesLooselyMatch; - if (!CanUseCollectionExpression(semanticModel, objectCreationExpression, expressionType, preMatches, allowSemanticsChange, cancellationToken, out var changesSemantics)) + if (!CanUseCollectionExpression(semanticModel, objectCreationExpression, expressionType, preMatches, allowSemanticsChange, cancellationToken, out var changesSemantics2)) return null; - return (preMatches.Concat(postMatches), shouldUseCollectionExpression: true, changesSemantics); + return (preMatches.Concat(postMatches), shouldUseCollectionExpression: true, changesSemantics1 || changesSemantics2); } } diff --git a/src/Analyzers/Core/Analyzers/UseObjectInitializer/UseNamedMemberInitializerAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseObjectInitializer/UseNamedMemberInitializerAnalyzer.cs index 1564a3a2d687b..6760960332f27 100644 --- a/src/Analyzers/Core/Analyzers/UseObjectInitializer/UseNamedMemberInitializerAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseObjectInitializer/UseNamedMemberInitializerAnalyzer.cs @@ -69,8 +69,10 @@ protected sealed override bool ShouldAnalyze(CancellationToken cancellationToken protected sealed override bool TryAddMatches( ArrayBuilder> preMatches, ArrayBuilder> postMatches, + out bool changesSemantics, CancellationToken cancellationToken) { + changesSemantics = false; using var _1 = PooledHashSet.GetInstance(out var seenNames); var initializer = this.SyntaxFacts.GetInitializerOfBaseObjectCreationExpression(_objectCreationExpression); diff --git a/src/Analyzers/Core/CodeFixes/UseCollectionInitializer/AbstractUseCollectionInitializerCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseCollectionInitializer/AbstractUseCollectionInitializerCodeFixProvider.cs index d1c1ed93b6077..3894a87ce428f 100644 --- a/src/Analyzers/Core/CodeFixes/UseCollectionInitializer/AbstractUseCollectionInitializerCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseCollectionInitializer/AbstractUseCollectionInitializerCodeFixProvider.cs @@ -76,7 +76,7 @@ protected sealed override async Task FixAsync( using var analyzer = GetAnalyzer(); var useCollectionExpression = properties.ContainsKey(UseCollectionInitializerHelpers.UseCollectionExpressionName) is true; - var (preMatches, postMatches) = analyzer.Analyze( + var (preMatches, postMatches, _) = analyzer.Analyze( semanticModel, syntaxFacts, objectCreation, useCollectionExpression, cancellationToken); if (preMatches.IsDefault || postMatches.IsDefault) diff --git a/src/Analyzers/VisualBasic/Analyzers/UseCollectionInitializer/VisualBasicCollectionInitializerAnalyzer.vb b/src/Analyzers/VisualBasic/Analyzers/UseCollectionInitializer/VisualBasicCollectionInitializerAnalyzer.vb index f93006673927f..6d7b23598ee9f 100644 --- a/src/Analyzers/VisualBasic/Analyzers/UseCollectionInitializer/VisualBasicCollectionInitializerAnalyzer.vb +++ b/src/Analyzers/VisualBasic/Analyzers/UseCollectionInitializer/VisualBasicCollectionInitializerAnalyzer.vb @@ -41,6 +41,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseCollectionInitializer Protected Overrides Function AnalyzeMatchesAndCollectionConstructorForCollectionExpression( preMatches As ArrayBuilder(Of CollectionMatch(Of SyntaxNode)), postMatches As ArrayBuilder(Of CollectionMatch(Of SyntaxNode)), + ByRef changesSemantics As Boolean, cancellationToken As CancellationToken) As Boolean ' Only called for collection expressions, which VB does not support Throw ExceptionUtilities.Unreachable() diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxReplacer.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxReplacer.cs index 5be08a6030e18..2cf64f0ab9d58 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxReplacer.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxReplacer.cs @@ -6,9 +6,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; -using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Syntax { @@ -74,9 +72,9 @@ private class Replacer : CSharpSyntaxRewriter where TNode : SyntaxNode private readonly HashSet _triviaSet; private readonly HashSet _spanSet; - private readonly TextSpan _totalSpan; - private readonly bool _visitIntoStructuredTrivia; - private readonly bool _shouldVisitTrivia; + private TextSpan _totalSpan; + private bool _visitIntoStructuredTrivia; + private bool _shouldVisitTrivia; public Replacer( IEnumerable? nodes, @@ -94,19 +92,9 @@ public Replacer( _tokenSet = tokens != null ? new HashSet(tokens) : s_noTokens; _triviaSet = trivia != null ? new HashSet(trivia) : s_noTrivia; - _spanSet = new HashSet( - _nodeSet.Select(n => n.FullSpan).Concat( - _tokenSet.Select(t => t.FullSpan).Concat( - _triviaSet.Select(t => t.FullSpan)))); - - _totalSpan = ComputeTotalSpan(_spanSet); - - _visitIntoStructuredTrivia = - _nodeSet.Any(n => n.IsPartOfStructuredTrivia()) || - _tokenSet.Any(t => t.IsPartOfStructuredTrivia()) || - _triviaSet.Any(t => t.IsPartOfStructuredTrivia()); + _spanSet = new HashSet(); - _shouldVisitTrivia = _triviaSet.Count > 0 || _visitIntoStructuredTrivia; + CalculateVisitationCriteria(); } private static readonly HashSet s_noNodes = new HashSet(); @@ -129,13 +117,29 @@ public bool HasWork } } - private static TextSpan ComputeTotalSpan(IEnumerable spans) + private void CalculateVisitationCriteria() { + _spanSet.Clear(); + foreach (var node in _nodeSet) + { + _spanSet.Add(node.FullSpan); + } + + foreach (var token in _tokenSet) + { + _spanSet.Add(token.FullSpan); + } + + foreach (var trivia in _triviaSet) + { + _spanSet.Add(trivia.FullSpan); + } + bool first = true; int start = 0; int end = 0; - foreach (var span in spans) + foreach (var span in _spanSet) { if (first) { @@ -150,7 +154,14 @@ private static TextSpan ComputeTotalSpan(IEnumerable spans) } } - return new TextSpan(start, end - start); + _totalSpan = new TextSpan(start, end - start); + + _visitIntoStructuredTrivia = + _nodeSet.Any(static n => n.IsPartOfStructuredTrivia()) || + _tokenSet.Any(static t => t.IsPartOfStructuredTrivia()) || + _triviaSet.Any(static t => t.IsPartOfStructuredTrivia()); + + _shouldVisitTrivia = _triviaSet.Count > 0 || _visitIntoStructuredTrivia; } private bool ShouldVisit(TextSpan span) @@ -179,16 +190,28 @@ private bool ShouldVisit(TextSpan span) [return: NotNullIfNotNull(nameof(node))] public override SyntaxNode? Visit(SyntaxNode? node) { - SyntaxNode? rewritten = node; + var rewritten = node; if (node != null) { + bool isReplacedNode = _nodeSet.Remove(node); + + if (isReplacedNode) + { + // If node is in _nodeSet, then it contributed to the calculation of _spanSet. + // We are currently processing that node, so it no longer needs to contribute + // to _spanSet and affect determination of inward visitation. This is done before + // calling ShouldVisit to avoid walking into the node if there aren't any remaining + // spans inside it representing items to replace. + CalculateVisitationCriteria(); + } + if (this.ShouldVisit(node.FullSpan)) { rewritten = base.Visit(node); } - if (_nodeSet.Contains(node) && _computeReplacementNode != null) + if (isReplacedNode && _computeReplacementNode != null) { rewritten = _computeReplacementNode((TNode)node, (TNode)rewritten!); } @@ -200,13 +223,24 @@ private bool ShouldVisit(TextSpan span) public override SyntaxToken VisitToken(SyntaxToken token) { var rewritten = token; + bool isReplacedToken = _tokenSet.Remove(token); + + if (isReplacedToken) + { + // If token is in _tokenSet, then it contributed to the calculation of _spanSet. + // We are currently processing that token, so it no longer needs to contribute + // to _spanSet and affect determination of inward visitation. This is done before + // calling ShouldVisit to avoid walking into the token if there aren't any remaining + // spans inside it representing items to replace. + CalculateVisitationCriteria(); + } if (_shouldVisitTrivia && this.ShouldVisit(token.FullSpan)) { rewritten = base.VisitToken(token); } - if (_tokenSet.Contains(token) && _computeReplacementToken != null) + if (isReplacedToken && _computeReplacementToken != null) { rewritten = _computeReplacementToken(token, rewritten); } @@ -217,13 +251,24 @@ public override SyntaxToken VisitToken(SyntaxToken token) public override SyntaxTrivia VisitListElement(SyntaxTrivia trivia) { var rewritten = trivia; + bool isReplacedTrivia = _triviaSet.Remove(trivia); + + if (isReplacedTrivia) + { + // If trivia is in _triviaSet, then it contributed to the calculation of _spanSet. + // We are currently processing that trivia, so it no longer needs to contribute + // to _spanSet and affect determination of inward visitation. This is done before + // calling ShouldVisit to avoid walking into the trivia if there aren't any remaining + // spans inside it representing items to replace. + CalculateVisitationCriteria(); + } if (this.VisitIntoStructuredTrivia && trivia.HasStructure && this.ShouldVisit(trivia.FullSpan)) { rewritten = this.VisitTrivia(trivia); } - if (_triviaSet.Contains(trivia) && _computeReplacementTrivia != null) + if (isReplacedTrivia && _computeReplacementTrivia != null) { rewritten = _computeReplacementTrivia(trivia, rewritten); } diff --git a/src/EditorFeatures/CSharp/TextStructureNavigation/CSharpTextStructureNavigatorProvider.cs b/src/EditorFeatures/CSharp/TextStructureNavigation/CSharpTextStructureNavigatorProvider.cs index 26f0775e849f4..d7f65690b4a56 100644 --- a/src/EditorFeatures/CSharp/TextStructureNavigation/CSharpTextStructureNavigatorProvider.cs +++ b/src/EditorFeatures/CSharp/TextStructureNavigation/CSharpTextStructureNavigatorProvider.cs @@ -97,7 +97,7 @@ protected override TextExtent GetExtentOfWordFromToken(ITextStructureNavigator n contentStart++; } - var end = token.Span.End; + var end = Math.Max(contentStart, token.Span.End); var contentEnd = end; if (CharAt(contentEnd - 1) == '8') @@ -115,6 +115,8 @@ protected override TextExtent GetExtentOfWordFromToken(ITextStructureNavigator n contentEnd--; } + // Ensure that in error conditions like a naked `"` that we don't end up with invalid bounds. + contentEnd = Math.Max(contentStart, contentEnd); return (TextSpan.FromBounds(start, contentStart), TextSpan.FromBounds(contentStart, contentEnd), TextSpan.FromBounds(contentEnd, end)); } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/AddParameterCheckTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/AddParameterCheckTests.cs index 51e66334cc26d..ba0ebdce47118 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/AddParameterCheckTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/AddParameterCheckTests.cs @@ -30,7 +30,7 @@ public async Task TestEmptyFile() } [Fact] - public async Task TestSimpleReferenceType_AlreadyNullChecked() + public async Task TestSimpleReferenceType_AlreadyNullChecked1() { var testCode = """ using System; @@ -53,6 +53,27 @@ public C([||]string s) }.RunAsync(); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61181")] + public async Task TestSimpleReferenceType_AlreadyNullChecked2() + { + await new VerifyCS.Test + { + TestCode = """ + using System; + + class C + { + public C([||]string s) + { + ArgumentNullException.ThrowIfNull(s); + } + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + }.RunAsync(); + } + [Fact] public async Task TestSimpleReferenceType() { @@ -83,6 +104,36 @@ public C(string s) """); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61181")] + public async Task TestSimpleReferenceType_ThrowIfNull() + { + await new VerifyCS.Test + { + TestCode = """ + using System; + + class C + { + public C([||]string s) + { + } + } + """, + FixedCode = """ + using System; + + class C + { + public C(string s) + { + ArgumentNullException.ThrowIfNull(s); + } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + }.RunAsync(); + } + [Fact] public async Task TestSimpleReferenceType_CSharp6() { @@ -521,45 +572,81 @@ public C([||]string a, string b, string c) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string a, string b, string c) - {{ - if (string.IsNullOrEmpty(a)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" + class C + { + public C(string a, string b, string c) + { + if (string.IsNullOrEmpty(a)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" " """, """ \" - """)}"", nameof(a)); - }} + """)}}", nameof(a)); + } - if (string.IsNullOrEmpty(b)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(b)}").Replace(""" + if (string.IsNullOrEmpty(b)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(b)}").Replace(""" " """, """ \" - """)}"", nameof(b)); - }} + """)}}", nameof(b)); + } - if (string.IsNullOrEmpty(c)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(c)}").Replace(""" + if (string.IsNullOrEmpty(c)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(c)}").Replace(""" " """, """ \" - """)}"", nameof(c)); - }} - }} -}}", + """)}}", nameof(c)); + } + } + } + """, CodeActionIndex = 3, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_null_checks_for_all_parameters) }.RunAsync(); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61181")] + public async Task TestMultiNullableParameters_Net7() + { + await new VerifyCS.Test + { + TestCode = """ + using System; + + class C + { + public C([||]string a, string b, string c) + { + } + } + """, + FixedCode = $$""" + using System; + + class C + { + public C(string a, string b, string c) + { + ArgumentException.ThrowIfNullOrEmpty(a); + ArgumentException.ThrowIfNullOrEmpty(b); + ArgumentException.ThrowIfNullOrEmpty(c); + } + } + """, + CodeActionIndex = 3, + CodeActionEquivalenceKey = nameof(FeaturesResources.Add_null_checks_for_all_parameters), + ReferenceAssemblies = ReferenceAssemblies.Net.Net70, + }.RunAsync(); + } + [Fact] public async Task TestMultiNullableParametersSomeNullableReferenceTypes() { @@ -577,33 +664,35 @@ public C([||]string a, string b, string? c) } } """, - FixedCode = @$"#nullable enable + FixedCode = $$""" + #nullable enable -using System; + using System; -class C -{{ - public C(string a, string b, string? c) - {{ - if (string.IsNullOrEmpty(a)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" + class C + { + public C(string a, string b, string? c) + { + if (string.IsNullOrEmpty(a)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" " """, """ \" - """)}"", nameof(a)); - }} + """)}}", nameof(a)); + } - if (string.IsNullOrEmpty(b)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(b)}").Replace(""" + if (string.IsNullOrEmpty(b)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(b)}").Replace(""" " """, """ \" - """)}"", nameof(b)); - }} - }} -}}", + """)}}", nameof(b)); + } + } + } + """, CodeActionIndex = 3, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_null_checks_for_all_parameters) }.RunAsync(); @@ -640,31 +729,33 @@ public C(string a, [||]bool b, string c) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string a, bool b, string c) - {{ - if (string.IsNullOrEmpty(a)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" + class C + { + public C(string a, bool b, string c) + { + if (string.IsNullOrEmpty(a)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" " """, """ \" - """)}"", nameof(a)); - }} + """)}}", nameof(a)); + } - if (string.IsNullOrEmpty(c)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(c)}").Replace(""" + if (string.IsNullOrEmpty(c)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(c)}").Replace(""" " """, """ \" - """)}"", nameof(c)); - }} - }} -}}", + """)}}", nameof(c)); + } + } + } + """, CodeActionIndex = 0, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_null_checks_for_all_parameters) }.RunAsync(); @@ -685,31 +776,33 @@ public C([||]string a, bool b, string c) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string a, bool b, string c) - {{ - if (string.IsNullOrEmpty(a)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" + class C + { + public C(string a, bool b, string c) + { + if (string.IsNullOrEmpty(a)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" " """, """ \" - """)}"", nameof(a)); - }} + """)}}", nameof(a)); + } - if (string.IsNullOrEmpty(c)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(c)}").Replace(""" + if (string.IsNullOrEmpty(c)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(c)}").Replace(""" " """, """ \" - """)}"", nameof(c)); - }} - }} -}}", + """)}}", nameof(c)); + } + } + } + """, CodeActionIndex = 3, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_null_checks_for_all_parameters) }.RunAsync(); @@ -730,36 +823,38 @@ public C([||]string a, object b, string c) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string a, object b, string c) - {{ - if (string.IsNullOrEmpty(a)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" + class C + { + public C(string a, object b, string c) + { + if (string.IsNullOrEmpty(a)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(a)}").Replace(""" " """, """ \" - """)}"", nameof(a)); - }} + """)}}", nameof(a)); + } - if (b is null) - {{ - throw new ArgumentNullException(nameof(b)); - }} + if (b is null) + { + throw new ArgumentNullException(nameof(b)); + } - if (string.IsNullOrEmpty(c)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(c)}").Replace(""" + if (string.IsNullOrEmpty(c)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(c)}").Replace(""" " """, """ \" - """)}"", nameof(c)); - }} - }} -}}", + """)}}", nameof(c)); + } + } + } + """, CodeActionIndex = 3, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_null_checks_for_all_parameters) }.RunAsync(); @@ -1864,22 +1959,24 @@ public C([||]string s) } } """, - FixedCode = $@"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrEmpty(s)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrEmpty(s)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} - }} -}}", + """)}}", nameof(s)); + } + } + } + """, CodeActionIndex = 1, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_string_IsNullOrEmpty_check) }.RunAsync(); @@ -1900,27 +1997,61 @@ public C([||]string s) } } """, - FixedCode = $@"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrWhiteSpace(s)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_whitespace, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrWhiteSpace(s)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_whitespace, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} - }} -}}", + """)}}", nameof(s)); + } + } + } + """, CodeActionIndex = 2, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_string_IsNullOrWhiteSpace_check) }.RunAsync(); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61181")] + public async Task TestSpecialStringCheck2_Net8() + { + await new VerifyCS.Test + { + TestCode = """ + using System; + + class C + { + public C([||]string s) + { + } + } + """, + FixedCode = $$""" + using System; + + class C + { + public C(string s) + { + ArgumentException.ThrowIfNullOrWhiteSpace(s); + } + } + """, + CodeActionIndex = 2, + CodeActionEquivalenceKey = nameof(FeaturesResources.Add_string_IsNullOrWhiteSpace_check), + ReferenceAssemblies = ReferenceAssemblies.Net.Net80, + }.RunAsync(); + } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51338")] [UseCulture("de-DE", "de-DE")] public async Task TestSpecialStringCheck3() @@ -1937,22 +2068,24 @@ public C([||]string s) } } """, - FixedCode = $@"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrEmpty(s)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrEmpty(s)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} - }} -}}", + """)}}", nameof(s)); + } + } + } + """, CodeActionIndex = 1, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_string_IsNullOrEmpty_check) }.RunAsync(); @@ -1991,22 +2124,24 @@ static void Main([||]String bar) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class Program -{{ - static void Main(String bar) - {{ - if (String.IsNullOrEmpty(bar)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(bar)}").Replace(""" + class Program + { + static void Main(String bar) + { + if (String.IsNullOrEmpty(bar)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(bar)}").Replace(""" " """, """ \" - """)}"", nameof(bar)); - }} - }} -}}", + """)}}", nameof(bar)); + } + } + } + """, CodeActionIndex = 1, CodeActionEquivalenceKey = nameof(FeaturesResources.Add_string_IsNullOrEmpty_check), Options = @@ -2583,20 +2718,22 @@ public C($$string s) } } """, - FixedCode = $@"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrEmpty(s)) - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrEmpty(s)) + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} -}}", + """)}}", nameof(s)); + } + } + """, Options = { { CSharpCodeStyleOptions.PreferThrowExpression, false }, @@ -2623,20 +2760,22 @@ public C($$string s) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrEmpty(s)) - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrEmpty(s)) + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} -}}", + """)}}", nameof(s)); + } + } + """, Options = { { CSharpCodeStyleOptions.PreferThrowExpression, false }, @@ -2663,22 +2802,24 @@ public C($$string s) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrEmpty(s)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrEmpty(s)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} - }} -}}", + """)}}", nameof(s)); + } + } + } + """, Options = { { CSharpCodeStyleOptions.PreferThrowExpression, false }, @@ -2705,19 +2846,21 @@ public C($$string s) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrEmpty(s)) throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrEmpty(s)) throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} -}}", + """)}}", nameof(s)); + } + } + """, Options = { { CSharpCodeStyleOptions.PreferThrowExpression, false }, @@ -2744,19 +2887,21 @@ public C($$string s) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrEmpty(s)) throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrEmpty(s)) throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} -}}", + """)}}", nameof(s)); + } + } + """, Options = { { CSharpCodeStyleOptions.PreferThrowExpression, false }, @@ -2783,22 +2928,24 @@ public C($$string s) } } """, - FixedCode = @$"using System; + FixedCode = $$""" + using System; -class C -{{ - public C(string s) - {{ - if (string.IsNullOrEmpty(s)) - {{ - throw new ArgumentException($""{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" + class C + { + public C(string s) + { + if (string.IsNullOrEmpty(s)) + { + throw new ArgumentException($"{{string.Format(FeaturesResources._0_cannot_be_null_or_empty, "{nameof(s)}").Replace(""" " """, """ \" - """)}"", nameof(s)); - }} - }} -}}", + """)}}", nameof(s)); + } + } + } + """, Options = { { CSharpCodeStyleOptions.PreferThrowExpression, false }, diff --git a/src/EditorFeatures/CSharpTest/NavigateTo/NavigateToTests.cs b/src/EditorFeatures/CSharpTest/NavigateTo/NavigateToTests.cs index a38c21e711418..694bda17afe6c 100644 --- a/src/EditorFeatures/CSharpTest/NavigateTo/NavigateToTests.cs +++ b/src/EditorFeatures/CSharpTest/NavigateTo/NavigateToTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Xml.Linq; @@ -40,45 +39,45 @@ await TestAsync(testHost, composition, "", async w => public async Task FindClass(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); - }); + testHost, composition, """ + class Goo + { + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); + }); } [Theory, CombinatorialData] public async Task FindRecord(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -record Goo -{ -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); - }); + testHost, composition, """ + record Goo + { + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); + }); } [Theory, CombinatorialData] public async Task FindRecordClass(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -record class Goo -{ -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); - }); + testHost, composition, """ + record class Goo + { + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); + }); } [Theory, CombinatorialData] @@ -126,324 +125,322 @@ await TestAsync(testHost, composition, content, async w => public async Task FindVerbatimClass(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class @static -{ -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("static")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "static", "[|static|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); + testHost, composition, """ + class @static + { + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("static")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "static", "[|static|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); - // Check searching for @static too - item = (await _aggregator.GetItemsAsync("@static")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "static", "[|static|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); - }); + // Check searching for @static too + item = (await _aggregator.GetItemsAsync("@static")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "static", "[|static|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); + }); } [Theory, CombinatorialData] public async Task FindNestedClass(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - class Bar - { - internal class DogBed - { - } - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("DogBed")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "DogBed", "[|DogBed|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); - }); + testHost, composition, """ + class Goo + { + class Bar + { + internal class DogBed + { + } + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("DogBed")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "DogBed", "[|DogBed|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); + }); } [Theory, CombinatorialData] public async Task FindMemberInANestedClass(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - class Bar - { - class DogBed - { - public void Method() + testHost, composition, """ + class Goo { + class Bar + { + class DogBed + { + public void Method() + { + } + } + } } - } - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Method")).Single(); - VerifyNavigateToResultItem(item, "Method", "[|Method|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo.Bar.DogBed", "Test")); - }); + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Method")).Single(); + VerifyNavigateToResultItem(item, "Method", "[|Method|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo.Bar.DogBed", "Test")); + }); } [Theory, CombinatorialData] public async Task FindGenericClassWithConstraints(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -using System.Collections; + testHost, composition, """ + using System.Collections; -class Goo where T : IEnumerable -{ -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); - }); + class Goo where T : IEnumerable + { + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); + }); } [Theory, CombinatorialData] public async Task FindGenericMethodWithConstraints(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -using System; + testHost, composition, """ + using System; -class Goo -{ - public void Bar(T item) where T : IComparable - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Bar")).Single(); - VerifyNavigateToResultItem(item, "Bar", "[|Bar|](T)", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + class Goo + { + public void Bar(T item) where T : IComparable + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Bar")).Single(); + VerifyNavigateToResultItem(item, "Bar", "[|Bar|](T)", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindPartialClass(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -public partial class Goo -{ - int a; -} - -partial class Goo -{ - int b; -} -""", async w => - { - var expecteditem1 = new NavigateToItem("Goo", NavigateToItemKind.Class, "csharp", null, null, s_emptyExactPatternMatch, null); - var expecteditems = new List { expecteditem1, expecteditem1 }; + testHost, composition, """ + public partial class Goo + { + int a; + } - var items = await _aggregator.GetItemsAsync("Goo"); + partial class Goo + { + int b; + } + """, async w => + { + var items = await _aggregator.GetItemsAsync("Goo"); - VerifyNavigateToResultItems(expecteditems, items); - }); + var expecteditem1 = new NavigateToItem("Goo", NavigateToItemKind.Class, "csharp", null, null, s_emptyExactPatternMatch, null); + VerifyNavigateToResultItems([expecteditem1, expecteditem1], items); + }); } [Theory, CombinatorialData] public async Task FindTypesInMetadata(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -using System; + testHost, composition, """ + using System; -Class Program { FileStyleUriParser f; } -""", async w => - { - var items = await _aggregator.GetItemsAsync("FileStyleUriParser"); - Assert.Equal(0, items.Count()); - }); + Class Program { FileStyleUriParser f; } + """, async w => + { + var items = await _aggregator.GetItemsAsync("FileStyleUriParser"); + Assert.Equal(0, items.Count()); + }); } [Theory, CombinatorialData] public async Task FindClassInNamespace(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -namespace Bar -{ - class Goo - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); - }); + testHost, composition, """ + namespace Bar + { + class Goo + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Goo")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "Goo", "[|Goo|]", PatternMatchKind.Exact, NavigateToItemKind.Class, Glyph.ClassInternal); + }); } [Theory, CombinatorialData] public async Task FindStruct(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -struct Bar -{ -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("B")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "Bar", "[|B|]ar", PatternMatchKind.Prefix, NavigateToItemKind.Structure, Glyph.StructureInternal); - }); + testHost, composition, """ + struct Bar + { + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("B")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "Bar", "[|B|]ar", PatternMatchKind.Prefix, NavigateToItemKind.Structure, Glyph.StructureInternal); + }); } [Theory, CombinatorialData] public async Task FindEnum(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -enum Colors -{ - Red, - Green, - Blue -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Colors")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "Colors", "[|Colors|]", PatternMatchKind.Exact, NavigateToItemKind.Enum, Glyph.EnumInternal); - }); + testHost, composition, """ + enum Colors + { + Red, + Green, + Blue + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Colors")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "Colors", "[|Colors|]", PatternMatchKind.Exact, NavigateToItemKind.Enum, Glyph.EnumInternal); + }); } [Theory, CombinatorialData] public async Task FindEnumMember(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -enum Colors -{ - Red, - Green, - Blue -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("R")).Single(); - VerifyNavigateToResultItem(item, "Red", "[|R|]ed", PatternMatchKind.Prefix, NavigateToItemKind.EnumItem, Glyph.EnumMemberPublic); - }); + testHost, composition, """ + enum Colors + { + Red, + Green, + Blue + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("R")).Single(); + VerifyNavigateToResultItem(item, "Red", "[|R|]ed", PatternMatchKind.Prefix, NavigateToItemKind.EnumItem, Glyph.EnumMemberPublic); + }); } [Theory, CombinatorialData] public async Task FindField1(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - int bar; -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("b")).Single(); - VerifyNavigateToResultItem(item, "bar", "[|b|]ar", PatternMatchKind.Prefix, NavigateToItemKind.Field, Glyph.FieldPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + int bar; + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("b")).Single(); + VerifyNavigateToResultItem(item, "bar", "[|b|]ar", PatternMatchKind.Prefix, NavigateToItemKind.Field, Glyph.FieldPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindField2(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - int bar; -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("ba")).Single(); - VerifyNavigateToResultItem(item, "bar", "[|ba|]r", PatternMatchKind.Prefix, NavigateToItemKind.Field, Glyph.FieldPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + int bar; + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("ba")).Single(); + VerifyNavigateToResultItem(item, "bar", "[|ba|]r", PatternMatchKind.Prefix, NavigateToItemKind.Field, Glyph.FieldPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindField3(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - int bar; -} -""", async w => - { - Assert.Empty(await _aggregator.GetItemsAsync("ar")); - }); + testHost, composition, """ + class Goo + { + int bar; + } + """, async w => + { + Assert.Empty(await _aggregator.GetItemsAsync("ar")); + }); } [Theory, CombinatorialData] public async Task FindVerbatimField(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - int @string; -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("string")).Single(); - VerifyNavigateToResultItem(item, "string", "[|string|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + testHost, composition, """ + class Goo + { + int @string; + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("string")).Single(); + VerifyNavigateToResultItem(item, "string", "[|string|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - // Check searching for@string too - item = (await _aggregator.GetItemsAsync("@string")).Single(); - VerifyNavigateToResultItem(item, "string", "[|string|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + // Check searching for@string too + item = (await _aggregator.GetItemsAsync("@string")).Single(); + VerifyNavigateToResultItem(item, "string", "[|string|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindPtrField1(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - int* bar; -} -""", async w => - { - Assert.Empty(await _aggregator.GetItemsAsync("ar")); - }); + testHost, composition, """ + class Goo + { + int* bar; + } + """, async w => + { + Assert.Empty(await _aggregator.GetItemsAsync("ar")); + }); } [Theory, CombinatorialData] public async Task FindPtrField2(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - int* bar; -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("b")).Single(); - VerifyNavigateToResultItem(item, "bar", "[|b|]ar", PatternMatchKind.Prefix, NavigateToItemKind.Field, Glyph.FieldPrivate); - }); + testHost, composition, """ + class Goo + { + int* bar; + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("b")).Single(); + VerifyNavigateToResultItem(item, "bar", "[|b|]ar", PatternMatchKind.Prefix, NavigateToItemKind.Field, Glyph.FieldPrivate); + }); } [Theory, CombinatorialData] public async Task FindConstField(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - const int bar = 7; -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("ba")).Single(); - VerifyNavigateToResultItem(item, "bar", "[|ba|]r", PatternMatchKind.Prefix, NavigateToItemKind.Constant, Glyph.ConstantPrivate); - }); + testHost, composition, """ + class Goo + { + const int bar = 7; + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("ba")).Single(); + VerifyNavigateToResultItem(item, "bar", "[|ba|]r", PatternMatchKind.Prefix, NavigateToItemKind.Constant, Glyph.ConstantPrivate); + }); } [Theory, CombinatorialData] @@ -472,124 +469,124 @@ await TestAsync(testHost, composition, program, async w => public async Task FindAutoProperty(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - int Bar { get; set; } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("B")).Single(); - VerifyNavigateToResultItem(item, "Bar", "[|B|]ar", PatternMatchKind.Prefix, NavigateToItemKind.Property, Glyph.PropertyPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + int Bar { get; set; } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("B")).Single(); + VerifyNavigateToResultItem(item, "Bar", "[|B|]ar", PatternMatchKind.Prefix, NavigateToItemKind.Property, Glyph.PropertyPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindMethod(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - void DoSomething(); -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("DS")).Single(); - VerifyNavigateToResultItem(item, "DoSomething", "[|D|]o[|S|]omething()", PatternMatchKind.CamelCaseExact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + void DoSomething(); + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("DS")).Single(); + VerifyNavigateToResultItem(item, "DoSomething", "[|D|]o[|S|]omething()", PatternMatchKind.CamelCaseExact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindVerbatimMethod(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - void @static(); -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("static")).Single(); - VerifyNavigateToResultItem(item, "static", "[|static|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + testHost, composition, """ + class Goo + { + void @static(); + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("static")).Single(); + VerifyNavigateToResultItem(item, "static", "[|static|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - // Verify if we search for @static too - item = (await _aggregator.GetItemsAsync("@static")).Single(); - VerifyNavigateToResultItem(item, "static", "[|static|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + // Verify if we search for @static too + item = (await _aggregator.GetItemsAsync("@static")).Single(); + VerifyNavigateToResultItem(item, "static", "[|static|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindParameterizedMethod(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - void DoSomething(int a, string b) - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("DS")).Single(); - VerifyNavigateToResultItem(item, "DoSomething", "[|D|]o[|S|]omething(int, string)", PatternMatchKind.CamelCaseExact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + void DoSomething(int a, string b) + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("DS")).Single(); + VerifyNavigateToResultItem(item, "DoSomething", "[|D|]o[|S|]omething(int, string)", PatternMatchKind.CamelCaseExact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindConstructor(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - public Goo() - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Goo")).Single(t => t.Kind == NavigateToItemKind.Method); - VerifyNavigateToResultItem(item, "Goo", "[|Goo|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + public Goo() + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Goo")).Single(t => t.Kind == NavigateToItemKind.Method); + VerifyNavigateToResultItem(item, "Goo", "[|Goo|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindParameterizedConstructor(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - public Goo(int i) - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Goo")).Single(t => t.Kind == NavigateToItemKind.Method); - VerifyNavigateToResultItem(item, "Goo", "[|Goo|](int)", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + public Goo(int i) + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Goo")).Single(t => t.Kind == NavigateToItemKind.Method); + VerifyNavigateToResultItem(item, "Goo", "[|Goo|](int)", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindStaticConstructor(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - static Goo() - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Goo")).Single(t => t.Kind == NavigateToItemKind.Method && t.Name != ".ctor"); - VerifyNavigateToResultItem(item, "Goo", "[|Goo|].static Goo()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + static Goo() + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Goo")).Single(t => t.Kind == NavigateToItemKind.Method && t.Name != ".ctor"); + VerifyNavigateToResultItem(item, "Goo", "[|Goo|].static Goo()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] @@ -598,11 +595,10 @@ public async Task FindPartialMethods(TestHost testHost, Composition composition) await TestAsync(testHost, composition, "partial class Goo { partial void Bar(); } partial class Goo { partial void Bar() { Console.Write(\"hello\"); } }", async w => { var expecteditem1 = new NavigateToItem("Bar", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null); - var expecteditems = new List { expecteditem1, expecteditem1 }; var items = await _aggregator.GetItemsAsync("Bar"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([expecteditem1, expecteditem1], items); }); } @@ -612,11 +608,10 @@ public async Task FindPartialProperties(TestHost testHost, Composition compositi await TestAsync(testHost, composition, "partial class Goo { partial int Prop { get; set; } } partial class Goo { partial int Prop { get => 1; set { } } }", async w => { var expecteditem1 = new NavigateToItem("Prop", NavigateToItemKind.Property, "csharp", null, null, s_emptyExactPatternMatch, null); - var expecteditems = new List { expecteditem1, expecteditem1 }; var items = await _aggregator.GetItemsAsync("Prop"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([expecteditem1, expecteditem1], items); }); } @@ -624,34 +619,34 @@ public async Task FindPartialProperties(TestHost testHost, Composition compositi public async Task FindPartialMethodDefinitionOnly(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -partial class Goo -{ - partial void Bar(); -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Bar")).Single(); - VerifyNavigateToResultItem(item, "Bar", "[|Bar|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_1_2, "Goo", "test1.cs", "Test")); - }); + testHost, composition, """ + partial class Goo + { + partial void Bar(); + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Bar")).Single(); + VerifyNavigateToResultItem(item, "Bar", "[|Bar|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_1_2, "Goo", "test1.cs", "Test")); + }); } [Theory, CombinatorialData] public async Task FindPartialMethodImplementationOnly(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -partial class Goo -{ - partial void Bar() - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("Bar")).Single(); - VerifyNavigateToResultItem(item, "Bar", "[|Bar|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_1_2, "Goo", "test1.cs", "Test")); - }); + testHost, composition, """ + partial class Goo + { + partial void Bar() + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("Bar")).Single(); + VerifyNavigateToResultItem(item, "Bar", "[|Bar|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, string.Format(FeaturesResources.in_0_1_2, "Goo", "test1.cs", "Test")); + }); } [Theory, CombinatorialData] @@ -661,11 +656,10 @@ public async Task FindOverriddenMembers(TestHost testHost, Composition compositi await TestAsync(testHost, composition, program, async w => { var expecteditem1 = new NavigateToItem("Name", NavigateToItemKind.Property, "csharp", null, null, s_emptyExactPatternMatch, null); - var expecteditems = new List { expecteditem1, expecteditem1 }; var items = await _aggregator.GetItemsAsync("Name"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([expecteditem1, expecteditem1], items); var item = items.ElementAt(1); var itemDisplay = item.DisplayFactory.CreateItemDisplay(item); @@ -687,15 +681,15 @@ await TestAsync(testHost, composition, program, async w => public async Task FindInterface(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -public interface IGoo -{ -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("IG")).Single(); - VerifyNavigateToResultItem(item, "IGoo", "[|IG|]oo", PatternMatchKind.Prefix, NavigateToItemKind.Interface, Glyph.InterfacePublic); - }); + testHost, composition, """ + public interface IGoo + { + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("IG")).Single(); + VerifyNavigateToResultItem(item, "IGoo", "[|IG|]oo", PatternMatchKind.Prefix, NavigateToItemKind.Interface, Glyph.InterfacePublic); + }); } [Theory, CombinatorialData] @@ -813,76 +807,73 @@ void Bar() public async Task FindDelegateInNamespace(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -namespace Goo -{ - delegate void DoStuff(); -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("DoStuff")).Single(x => x.Kind != "Method"); - VerifyNavigateToResultItem(item, "DoStuff", "[|DoStuff|]", PatternMatchKind.Exact, NavigateToItemKind.Delegate, Glyph.DelegateInternal); - }); + testHost, composition, """ + namespace Goo + { + delegate void DoStuff(); + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("DoStuff")).Single(x => x.Kind != "Method"); + VerifyNavigateToResultItem(item, "DoStuff", "[|DoStuff|]", PatternMatchKind.Exact, NavigateToItemKind.Delegate, Glyph.DelegateInternal); + }); } [Theory, CombinatorialData] public async Task FindLambdaExpression(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -using System; + testHost, composition, """ + using System; -class Goo -{ - Func sqr = x => x * x; -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("sqr")).Single(); - VerifyNavigateToResultItem(item, "sqr", "[|sqr|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + class Goo + { + Func sqr = x => x * x; + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("sqr")).Single(); + VerifyNavigateToResultItem(item, "sqr", "[|sqr|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindArray(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ - object[] itemArray; -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("itemArray")).Single(); - VerifyNavigateToResultItem(item, "itemArray", "[|itemArray|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); - }); + testHost, composition, """ + class Goo + { + object[] itemArray; + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("itemArray")).Single(); + VerifyNavigateToResultItem(item, "itemArray", "[|itemArray|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPrivate, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); + }); } [Theory, CombinatorialData] public async Task FindClassAndMethodWithSameName(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class Goo -{ -} + testHost, composition, """ + class Goo + { + } -class Test -{ - void Goo() - { - } -} -""", async w => - { - var expectedItems = new List + class Test { - new NavigateToItem("Goo", NavigateToItemKind.Class, "csharp", "Goo", null, s_emptyExactPatternMatch, null), - new NavigateToItem("Goo", NavigateToItemKind.Method, "csharp", "Goo", null, s_emptyExactPatternMatch, null), - }; + void Goo() + { + } + } + """, async w => + { var items = await _aggregator.GetItemsAsync("Goo"); - VerifyNavigateToResultItems(expectedItems, items); + VerifyNavigateToResultItems([ + new("Goo", NavigateToItemKind.Class, "csharp", "Goo", null, s_emptyExactPatternMatch, null), + new("Goo", NavigateToItemKind.Method, "csharp", "Goo", null, s_emptyExactPatternMatch, null)], items); }); } @@ -890,80 +881,77 @@ void Goo() public async Task FindMethodNestedInGenericTypes(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class A -{ - class B - { - struct C - { - void M() + testHost, composition, """ + class A { + class B + { + struct C + { + void M() + { + } + } + } } - } - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("M")).Single(); - VerifyNavigateToResultItem(item, "M", "[|M|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "A.B.C", "Test")); - }); + """, async w => + { + var item = (await _aggregator.GetItemsAsync("M")).Single(); + VerifyNavigateToResultItem(item, "M", "[|M|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate, additionalInfo: string.Format(FeaturesResources.in_0_project_1, "A.B.C", "Test")); + }); } [Theory, CombinatorialData] public async Task OrderingOfConstructorsAndTypes(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class C1 -{ - C1(int i) - { - } -} + testHost, composition, """ + class C1 + { + C1(int i) + { + } + } -class C2 -{ - C2(float f) - { - } + class C2 + { + C2(float f) + { + } - static C2() - { - } -} -""", async w => - { - var expecteditems = new List - { - new NavigateToItem("C1", NavigateToItemKind.Class, "csharp", "C1", null, s_emptyPrefixPatternMatch, null), - new NavigateToItem("C1", NavigateToItemKind.Method, "csharp", "C1", null, s_emptyPrefixPatternMatch, null), - new NavigateToItem("C2", NavigateToItemKind.Class, "csharp", "C2", null, s_emptyPrefixPatternMatch, null), - new NavigateToItem("C2", NavigateToItemKind.Method, "csharp", "C2", null, s_emptyPrefixPatternMatch, null), // this is the static ctor - new NavigateToItem("C2", NavigateToItemKind.Method, "csharp", "C2", null, s_emptyPrefixPatternMatch, null), - }; - var items = (await _aggregator.GetItemsAsync("C")).ToList(); - items.Sort(CompareNavigateToItems); - VerifyNavigateToResultItems(expecteditems, items); - }); + static C2() + { + } + } + """, async w => + { + var items = (await _aggregator.GetItemsAsync("C")).ToList(); + items.Sort(CompareNavigateToItems); + VerifyNavigateToResultItems([ + new("C1", NavigateToItemKind.Class, "csharp", "C1", null, s_emptyPrefixPatternMatch, null), + new("C1", NavigateToItemKind.Method, "csharp", "C1", null, s_emptyPrefixPatternMatch, null), + new("C2", NavigateToItemKind.Class, "csharp", "C2", null, s_emptyPrefixPatternMatch, null), + new("C2", NavigateToItemKind.Method, "csharp", "C2", null, s_emptyPrefixPatternMatch, null), // this is the static ctor + new("C2", NavigateToItemKind.Method, "csharp", "C2", null, s_emptyPrefixPatternMatch, null)], items); + }); } [Theory, CombinatorialData] public async Task NavigateToMethodWithNullableParameter(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class C -{ - void M(object? o) - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("M")).Single(); - VerifyNavigateToResultItem(item, "M", "[|M|](object?)", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate); - }); + testHost, composition, """ + class C + { + void M(object? o) + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("M")).Single(); + VerifyNavigateToResultItem(item, "M", "[|M|](object?)", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPrivate); + }); } [Theory, CombinatorialData] @@ -971,23 +959,23 @@ public async Task StartStopSanity(TestHost testHost, Composition composition) { // Verify that multiple calls to start/stop and dispose don't blow up await TestAsync( -testHost, composition, """ -public class Goo -{ -} -""", async w => - { - // Do one set of queries - Assert.Single((await _aggregator.GetItemsAsync("Goo")), x => x.Kind != "Method"); - _provider.StopSearch(); + testHost, composition, """ + public class Goo + { + } + """, async w => + { + // Do one set of queries + Assert.Single((await _aggregator.GetItemsAsync("Goo")), x => x.Kind != "Method"); + _provider.StopSearch(); - // Do the same query again, make sure nothing was left over - Assert.Single((await _aggregator.GetItemsAsync("Goo")), x => x.Kind != "Method"); - _provider.StopSearch(); + // Do the same query again, make sure nothing was left over + Assert.Single((await _aggregator.GetItemsAsync("Goo")), x => x.Kind != "Method"); + _provider.StopSearch(); - // Dispose the provider - _provider.Dispose(); - }); + // Dispose the provider + _provider.Dispose(); + }); } [Theory, CombinatorialData] @@ -1026,13 +1014,10 @@ await TestAsync(testHost, composition, source, async w => var expecteditem1 = new NavigateToItem("get_keyword", NavigateToItemKind.Field, "csharp", null, null, s_emptyCamelCaseNonContiguousPrefixPatternMatch_NotCaseSensitive, null); var expecteditem2 = new NavigateToItem("get_key_word", NavigateToItemKind.Field, "csharp", null, null, s_emptyCamelCaseNonContiguousPrefixPatternMatch_NotCaseSensitive, null); var expecteditem3 = new NavigateToItem("GetKeyWord", NavigateToItemKind.Field, "csharp", null, null, s_emptyCamelCasePrefixPatternMatch, null); - var expecteditems = new List { expecteditem1, expecteditem2, expecteditem3 }; var items = await _aggregator.GetItemsAsync("GK"); - Assert.Equal(expecteditems.Count, items.Count()); - - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([expecteditem1, expecteditem2, expecteditem3], items); }); } @@ -1044,11 +1029,10 @@ await TestAsync(testHost, composition, source, async w => { var expecteditem1 = new NavigateToItem("get_key_word", NavigateToItemKind.Field, "csharp", null, null, s_emptyCamelCaseNonContiguousPrefixPatternMatch_NotCaseSensitive, null); var expecteditem2 = new NavigateToItem("GetKeyWord", NavigateToItemKind.Field, "csharp", null, null, s_emptyCamelCaseExactPatternMatch, null); - var expecteditems = new List { expecteditem1, expecteditem2 }; var items = await _aggregator.GetItemsAsync("GKW"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([expecteditem1, expecteditem2], items); }); } @@ -1060,11 +1044,10 @@ await TestAsync(testHost, composition, source, async w => { var expecteditem1 = new NavigateToItem("get_key_word", NavigateToItemKind.Field, "csharp", null, null, s_emptyCamelCaseSubstringPatternMatch_NotCaseSensitive, null); var expecteditem2 = new NavigateToItem("GetKeyWord", NavigateToItemKind.Field, "csharp", null, null, s_emptySubstringPatternMatch, null); - var expecteditems = new List { expecteditem1, expecteditem2 }; var items = await _aggregator.GetItemsAsync("K W"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([expecteditem1, expecteditem2], items); }); } @@ -1096,17 +1079,13 @@ public async Task TermSplittingTest6(TestHost testHost, Composition composition) var source = "class SyllableBreaking {int GetKeyWord; int get_key_word; string get_keyword; int getkeyword; int wake;}"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - new NavigateToItem("getkeyword", NavigateToItemKind.Field, "csharp", null, null, s_emptyFuzzyPatternMatch, null), - new NavigateToItem("get_keyword", NavigateToItemKind.Field, "csharp", null, null, s_emptyFuzzyPatternMatch, null), - new NavigateToItem("get_key_word", NavigateToItemKind.Field, "csharp", null, null,s_emptySubstringPatternMatch, null), - new NavigateToItem("GetKeyWord", NavigateToItemKind.Field, "csharp", null, null, s_emptySubstringPatternMatch_NotCaseSensitive, null) - }; - var items = await _aggregator.GetItemsAsync("get word"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([ + new("getkeyword", NavigateToItemKind.Field, "csharp", null, null, s_emptyFuzzyPatternMatch, null), + new("get_keyword", NavigateToItemKind.Field, "csharp", null, null, s_emptyFuzzyPatternMatch, null), + new("get_key_word", NavigateToItemKind.Field, "csharp", null, null,s_emptySubstringPatternMatch, null), + new("GetKeyWord", NavigateToItemKind.Field, "csharp", null, null, s_emptySubstringPatternMatch_NotCaseSensitive, null)], items); }); } @@ -1142,14 +1121,9 @@ void Goo() """; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - new NavigateToItem("this", NavigateToItemKind.Property, "csharp", null, null, s_emptyExactPatternMatch, null), - }; - var items = await _aggregator.GetItemsAsync("this"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([new("this", NavigateToItemKind.Property, "csharp", null, null, s_emptyExactPatternMatch, null)], items); }); } @@ -1159,14 +1133,9 @@ public async Task DottedPattern1(TestHost testHost, Composition composition) var source = "namespace Goo { namespace Bar { class Baz { void Quux() { } } } }"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - new NavigateToItem("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null) - }; - var items = await _aggregator.GetItemsAsync("B.Q"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([new("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null)], items); }); } @@ -1176,13 +1145,9 @@ public async Task DottedPattern2(TestHost testHost, Composition composition) var source = "namespace Goo { namespace Bar { class Baz { void Quux() { } } } }"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - }; - var items = await _aggregator.GetItemsAsync("C.Q"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([], items); }); } @@ -1192,14 +1157,9 @@ public async Task DottedPattern3(TestHost testHost, Composition composition) var source = "namespace Goo { namespace Bar { class Baz { void Quux() { } } } }"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - new NavigateToItem("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null) - }; - var items = await _aggregator.GetItemsAsync("B.B.Q"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([new("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null)], items); }); } @@ -1209,14 +1169,9 @@ public async Task DottedPattern4(TestHost testHost, Composition composition) var source = "namespace Goo { namespace Bar { class Baz { void Quux() { } } } }"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - new NavigateToItem("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null) - }; - var items = await _aggregator.GetItemsAsync("Baz.Quux"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([new("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null)], items); }); } @@ -1226,14 +1181,9 @@ public async Task DottedPattern5(TestHost testHost, Composition composition) var source = "namespace Goo { namespace Bar { class Baz { void Quux() { } } } }"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - new NavigateToItem("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null) - }; - var items = await _aggregator.GetItemsAsync("G.B.B.Quux"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([new("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null)], items); }); } @@ -1243,13 +1193,9 @@ public async Task DottedPattern6(TestHost testHost, Composition composition) var source = "namespace Goo { namespace Bar { class Baz { void Quux() { } } } }"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - }; - var items = await _aggregator.GetItemsAsync("F.F.B.B.Quux"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([], items); }); } @@ -1260,14 +1206,9 @@ public async Task DottedPattern7(TestHost testHost, Composition composition) var source = "namespace Goo { namespace Bar { class Baz { void Quux() { } } } }"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - new NavigateToItem("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null) - }; - var items = await _aggregator.GetItemsAsync("Baz.Q"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([new("Quux", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null)], items); }); } @@ -1278,15 +1219,11 @@ public async Task DottedPatternMatchKind(TestHost testHost, Composition composit var source = "namespace System { class Console { void Write(string s) { } void WriteLine(string s) { } } }"; await TestAsync(testHost, composition, source, async w => { - var expecteditems = new List - { - new NavigateToItem("Write", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), - new NavigateToItem("WriteLine", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null) - }; - var items = await _aggregator.GetItemsAsync("Console.Write"); - VerifyNavigateToResultItems(expecteditems, items); + VerifyNavigateToResultItems([ + new("Write", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), + new("WriteLine", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null)], items); }); } @@ -1323,15 +1260,12 @@ public void VisibleMethod_Generated() { } _aggregator = new NavigateToTestAggregator(_provider); var items = await _aggregator.GetItemsAsync("VisibleMethod"); - var expectedItems = new List() - { - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), - new NavigateToItem("VisibleMethod_Generated", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null) - }; // The pattern matcher should match 'VisibleMethod' to both 'VisibleMethod' and 'VisibleMethod_Not', except that // the _Not method is declared in a generated file. - VerifyNavigateToResultItems(expectedItems, items); + VerifyNavigateToResultItems([ + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), + new("VisibleMethod_Generated", NavigateToItemKind.Method, "csharp", null, null, s_emptyPrefixPatternMatch, null)], items); } [Theory, WorkItem("https://github.com/dotnet/roslyn/pull/11474")] @@ -1339,18 +1273,18 @@ public void VisibleMethod_Generated() { } public async Task FindFuzzy1(TestHost testHost, Composition composition) { await TestAsync( -testHost, composition, """ -class C -{ - public void ToError() - { - } -} -""", async w => - { - var item = (await _aggregator.GetItemsAsync("ToEror")).Single(); - VerifyNavigateToResultItem(item, "ToError", "ToError()", PatternMatchKind.Fuzzy, NavigateToItemKind.Method, Glyph.MethodPublic); - }); + testHost, composition, """ + class C + { + public void ToError() + { + } + } + """, async w => + { + var item = (await _aggregator.GetItemsAsync("ToEror")).Single(); + VerifyNavigateToResultItem(item, "ToError", "ToError()", PatternMatchKind.Fuzzy, NavigateToItemKind.Method, Glyph.MethodPublic); + }); } [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/18843")] @@ -1749,13 +1683,10 @@ public void VisibleMethod() { } _aggregator = new NavigateToTestAggregator(_provider); var items = await _aggregator.GetItemsAsync("VisibleMethod"); - var expectedItems = new List() - { - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null) - }; - VerifyNavigateToResultItems(expectedItems, items); + VerifyNavigateToResultItems([ + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null)], items); Assert.Single(items, i => i.SecondarySort.StartsWith("0000") && IsFromFile(i, "File1.cs")); Assert.Single(items, i => i.SecondarySort.StartsWith("0001") && IsFromFile(i, "File2.cs")); @@ -1794,13 +1725,10 @@ public void VisibleMethod() { } _aggregator = new NavigateToTestAggregator(_provider); var items = await _aggregator.GetItemsAsync("VisibleMethod"); - var expectedItems = new List() - { - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null) - }; - VerifyNavigateToResultItems(expectedItems, items); + VerifyNavigateToResultItems([ + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null)], items); Assert.Single(items, i => i.SecondarySort.StartsWith("0000") && IsFromFile(i, "File1.cs")); Assert.Single(items, i => i.SecondarySort.StartsWith("0001") && IsFromFile(i, "File2.cs")); @@ -1839,13 +1767,10 @@ public void VisibleMethod() { } _aggregator = new NavigateToTestAggregator(_provider); var items = await _aggregator.GetItemsAsync("VisibleMethod"); - var expectedItems = new List() - { - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null) - }; - VerifyNavigateToResultItems(expectedItems, items); + VerifyNavigateToResultItems([ + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null)], items); Assert.Single(items, i => i.SecondarySort.StartsWith("0000") && IsFromFile(i, "File1.cs")); Assert.Single(items, i => i.SecondarySort.StartsWith("0002") && IsFromFile(i, "File2.cs")); @@ -1884,13 +1809,10 @@ public void VisibleMethod() { } _aggregator = new NavigateToTestAggregator(_provider); var items = await _aggregator.GetItemsAsync("VisibleMethod"); - var expectedItems = new List() - { - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null) - }; - VerifyNavigateToResultItems(expectedItems, items); + VerifyNavigateToResultItems([ + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null)], items); Assert.Single(items, i => i.SecondarySort.StartsWith("0000") && IsFromFile(i, "File1.cs")); Assert.Single(items, i => i.SecondarySort.StartsWith("0002") && IsFromFile(i, "File2.cs")); @@ -1929,13 +1851,10 @@ public void VisibleMethod() { } _aggregator = new NavigateToTestAggregator(_provider); var items = await _aggregator.GetItemsAsync("VisibleMethod"); - var expectedItems = new List() - { - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), - new NavigateToItem("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null) - }; - VerifyNavigateToResultItems(expectedItems, items); + VerifyNavigateToResultItems([ + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null), + new("VisibleMethod", NavigateToItemKind.Method, "csharp", null, null, s_emptyExactPatternMatch, null)], items); Assert.Single(items, i => i.SecondarySort.StartsWith("0000") && IsFromFile(i, "File1.cs")); Assert.Single(items, i => i.SecondarySort.StartsWith("0003") && IsFromFile(i, "File2.cs")); diff --git a/src/EditorFeatures/CSharpTest/TextStructureNavigation/TextStructureNavigatorTests.cs b/src/EditorFeatures/CSharpTest/TextStructureNavigation/TextStructureNavigatorTests.cs index 89159b427b39f..0d4299d121c1b 100644 --- a/src/EditorFeatures/CSharpTest/TextStructureNavigation/TextStructureNavigatorTests.cs +++ b/src/EditorFeatures/CSharpTest/TextStructureNavigation/TextStructureNavigatorTests.cs @@ -561,4 +561,13 @@ public void TestClampStringLiteral(string content) { AssertExtent(content); } + + [WpfTheory, WorkItem("https://github.com/dotnet/roslyn/issues/77401")] + [InlineData(@"{|Significant:""|}$$")] + [InlineData(@"{|Significant:""""""|}$$")] + [InlineData(@"""""""{|Significant:u8|}$$")] + public void TestClampStringLiteral_Invalid(string content) + { + AssertExtent(content); + } } diff --git a/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionCommandHandler.cs b/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionCommandHandler.cs index 9635cf19695ee..54e1f864dab16 100644 --- a/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionCommandHandler.cs +++ b/src/EditorFeatures/Core/GoToDefinition/GoToDefinitionCommandHandler.cs @@ -31,15 +31,11 @@ namespace Microsoft.CodeAnalysis.GoToDefinition; [method: ImportingConstructor] [method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] internal class GoToDefinitionCommandHandler( - IGlobalOptionService globalOptionService, IThreadingContext threadingContext, - IUIThreadOperationExecutor executor, IAsynchronousOperationListenerProvider listenerProvider) : ICommandHandler { - private readonly IGlobalOptionService _globalOptionService = globalOptionService; private readonly IThreadingContext _threadingContext = threadingContext; - private readonly IUIThreadOperationExecutor _executor = executor; private readonly IAsynchronousOperationListener _listener = listenerProvider.GetListener(FeatureAttribute.GoToDefinition); public string DisplayName => EditorFeaturesResources.Go_to_Definition; diff --git a/src/EditorFeatures/Test2/GoToDefinition/GoToDefinitionCommandHandlerTests.vb b/src/EditorFeatures/Test2/GoToDefinition/GoToDefinitionCommandHandlerTests.vb index bdd248e842de0..cdeca6bf967c3 100644 --- a/src/EditorFeatures/Test2/GoToDefinition/GoToDefinitionCommandHandlerTests.vb +++ b/src/EditorFeatures/Test2/GoToDefinition/GoToDefinitionCommandHandlerTests.vb @@ -56,9 +56,7 @@ class C Dim provider = workspace.GetService(Of IAsynchronousOperationListenerProvider)() Dim waiter = provider.GetWaiter(FeatureAttribute.GoToDefinition) Dim handler = New GoToDefinitionCommandHandler( - workspace.GetService(Of IGlobalOptionService), workspace.GetService(Of IThreadingContext), - workspace.GetService(Of IUIThreadOperationExecutor), provider) handler.ExecuteCommand(New GoToDefinitionCommandArgs(view, baseDocument.GetTextBuffer()), TestCommandExecutionContext.Create()) @@ -98,9 +96,7 @@ int y = x$$ Dim provider = workspace.GetService(Of IAsynchronousOperationListenerProvider)() Dim waiter = provider.GetWaiter(FeatureAttribute.GoToDefinition) Dim handler = New GoToDefinitionCommandHandler( - workspace.GetService(Of IGlobalOptionService), workspace.GetService(Of IThreadingContext), - workspace.GetService(Of IUIThreadOperationExecutor), provider) handler.ExecuteCommand(New GoToDefinitionCommandArgs(view, document.GetTextBuffer()), TestCommandExecutionContext.Create()) @@ -143,9 +139,7 @@ class C Dim provider = workspace.GetService(Of IAsynchronousOperationListenerProvider)() Dim waiter = provider.GetWaiter(FeatureAttribute.GoToDefinition) Dim handler = New GoToDefinitionCommandHandler( - workspace.GetService(Of IGlobalOptionService), workspace.GetService(Of IThreadingContext), - workspace.GetService(Of IUIThreadOperationExecutor), provider) Dim snapshot = document.GetTextBuffer().CurrentSnapshot diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractKeywordRecommender.cs index b5fa226cdc805..618804e218ce7 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AbstractKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AbstractKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AbstractKeyword) { private static readonly ISet s_validNonInterfaceMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -45,11 +45,6 @@ internal class AbstractKeywordRecommender : AbstractSyntacticSingleKeywordRecomm SyntaxKind.FileKeyword, }; - public AbstractKeywordRecommender() - : base(SyntaxKind.AbstractKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AddKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AddKeywordRecommender.cs index 1435aa60d1a65..6e8ab182339bd 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AddKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AddKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AddKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AddKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AddKeyword) { - public AddKeywordRecommender() - : base(SyntaxKind.AddKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.TargetToken.IsAccessorDeclarationContext(position, SyntaxKind.AddKeyword); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AliasKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AliasKeywordRecommender.cs index f3f6d2c5f56ea..7d6320f01b172 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AliasKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AliasKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AliasKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AliasKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AliasKeyword) { - public AliasKeywordRecommender() - : base(SyntaxKind.AliasKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // cases: diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AllowsKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AllowsKeywordRecommender.cs index 4a805d2a16ba7..c047705a1c956 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AllowsKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AllowsKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AllowsKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AllowsKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AllowsKeyword) { - public AllowsKeywordRecommender() - : base(SyntaxKind.AllowsKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return IsAllowsRefStructConstraintContext(context); diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AndKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AndKeywordRecommender.cs index b38e4af55dd06..efe7e52e95c98 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AndKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AndKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AndKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AndKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AndKeyword) { - public AndKeywordRecommender() - : base(SyntaxKind.AndKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsAtEndOfPattern; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AnnotationsKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AnnotationsKeywordRecommender.cs index 3137f750a709c..371f3fb4f6020 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AnnotationsKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AnnotationsKeywordRecommender.cs @@ -7,13 +7,9 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AnnotationsKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AnnotationsKeywordRecommender() + : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AnnotationsKeyword, isValidInPreprocessorContext: true) { - public AnnotationsKeywordRecommender() - : base(SyntaxKind.AnnotationsKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var previousToken1 = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AsKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AsKeywordRecommender.cs index 4bd98f826ca8d..948e99553d869 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AsKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AsKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AsKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AsKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AsKeyword) { - public AsKeywordRecommender() - : base(SyntaxKind.AsKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => !context.IsInNonUserCode && context.IsIsOrAsOrSwitchOrWithExpressionContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AscendingKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AscendingKeywordRecommender.cs index 7676ae1f91bad..5671c1ed87b4f 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AscendingKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AscendingKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AscendingKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AscendingKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AscendingKeyword) { - public AscendingKeywordRecommender() - : base(SyntaxKind.AscendingKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.TargetToken.IsOrderByDirectionContext(); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AssemblyKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AssemblyKeywordRecommender.cs index 511ecb03a91c7..a7ea2679d1324 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AssemblyKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AssemblyKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AssemblyKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AssemblyKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AssemblyKeyword) { - public AssemblyKeywordRecommender() - : base(SyntaxKind.AssemblyKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var token = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AsyncKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AsyncKeywordRecommender.cs index 938e52df3c476..4522923364dcf 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AsyncKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AsyncKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class AsyncKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class AsyncKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.AsyncKeyword, isValidInPreprocessorContext: false) { - public AsyncKeywordRecommender() - : base(SyntaxKind.AsyncKeyword, isValidInPreprocessorContext: false) - { - } - private static readonly ISet s_validLocalFunctionModifiers = new HashSet(SyntaxFacts.EqualityComparer) { SyntaxKind.StaticKeyword, diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BaseKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BaseKeywordRecommender.cs index 1395a08503574..b78b3b3745e7b 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BaseKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BaseKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class BaseKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class BaseKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.BaseKeyword) { - public BaseKeywordRecommender() - : base(SyntaxKind.BaseKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // We need to at least be in a type declaration context. This prevents us from showing diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BoolKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BoolKeywordRecommender.cs index d8a0e47124241..4826bf41197fc 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BoolKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BoolKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class BoolKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class BoolKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.BoolKeyword) { - public BoolKeywordRecommender() - : base(SyntaxKind.BoolKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BreakKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BreakKeywordRecommender.cs index 0b2408309c513..12279599e2196 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BreakKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/BreakKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class BreakKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class BreakKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.BreakKeyword) { - public BreakKeywordRecommender() - : base(SyntaxKind.BreakKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByKeywordRecommender.cs index e0a41695d0bb2..7b77ea5eec5e8 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ByKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ByKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ByKeyword) { - public ByKeywordRecommender() - : base(SyntaxKind.ByKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // cases: diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByteKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByteKeywordRecommender.cs index c9b5ebfd4d1aa..bd33e4d8ac48e 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByteKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ByteKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ByteKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class ByteKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.ByteKeyword) { - public ByteKeywordRecommender() - : base(SyntaxKind.ByteKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CaseKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CaseKeywordRecommender.cs index d45fa895ef8ac..2a5e494498cc5 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CaseKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CaseKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class CaseKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class CaseKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.CaseKeyword) { - public CaseKeywordRecommender() - : base(SyntaxKind.CaseKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CatchKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CatchKeywordRecommender.cs index 3662ee41ebed9..9d34aaa5c5f09 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CatchKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CatchKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class CatchKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class CatchKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.CatchKeyword) { - public CatchKeywordRecommender() - : base(SyntaxKind.CatchKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.SyntaxTree.IsCatchOrFinallyContext(position, context.LeftToken); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CharKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CharKeywordRecommender.cs index 7f1da322b9aa7..68091052f4baa 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CharKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CharKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class CharKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class CharKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.CharKeyword) { - public CharKeywordRecommender() - : base(SyntaxKind.CharKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CheckedKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CheckedKeywordRecommender.cs index 606e0dfa120ee..a2cc6065078d8 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CheckedKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/CheckedKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class CheckedKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class CheckedKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.CheckedKeyword) { - public CheckedKeywordRecommender() - : base(SyntaxKind.CheckedKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (context.IsStatementContext || diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ChecksumKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ChecksumKeywordRecommender.cs index 24c0523e6d6ca..d35436aa98fd8 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ChecksumKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ChecksumKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ChecksumKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ChecksumKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ChecksumKeyword, isValidInPreprocessorContext: true) { - public ChecksumKeywordRecommender() - : base(SyntaxKind.ChecksumKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // # pragma | diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ClassKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ClassKeywordRecommender.cs index 9102e13a1777b..c0312fe1bb588 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ClassKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ClassKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ClassKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ClassKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ClassKeyword) { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -25,11 +25,6 @@ internal class ClassKeywordRecommender : AbstractSyntacticSingleKeywordRecommend SyntaxKind.FileKeyword, }; - public ClassKeywordRecommender() - : base(SyntaxKind.ClassKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ConstKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ConstKeywordRecommender.cs index 7c0fe78ee4912..af781fdb2f3d4 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ConstKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ConstKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ConstKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ConstKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ConstKeyword) { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -28,11 +28,6 @@ internal class ConstKeywordRecommender : AbstractSyntacticSingleKeywordRecommend SyntaxKind.PrivateKeyword, }; - public ConstKeywordRecommender() - : base(SyntaxKind.ConstKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ContinueKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ContinueKeywordRecommender.cs index 6ec1cc64b0e1b..48cd8fc9e7079 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ContinueKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ContinueKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ContinueKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ContinueKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ContinueKeyword) { - public ContinueKeywordRecommender() - : base(SyntaxKind.ContinueKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (!context.IsStatementContext) diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DecimalKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DecimalKeywordRecommender.cs index 89c52e2e156fa..0c2f72f500d67 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DecimalKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DecimalKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class DecimalKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class DecimalKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.DecimalKeyword) { - public DecimalKeywordRecommender() - : base(SyntaxKind.DecimalKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DefaultKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DefaultKeywordRecommender.cs index 4a44532fc58bb..188576daaea57 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DefaultKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DefaultKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class DefaultKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class DefaultKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.DefaultKeyword, isValidInPreprocessorContext: true) { - public DefaultKeywordRecommender() - : base(SyntaxKind.DefaultKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DefineKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DefineKeywordRecommender.cs index 695838bb564b1..c4e9b9b882d96 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DefineKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DefineKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class DefineKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class DefineKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.DefineKeyword, isValidInPreprocessorContext: true) { - public DefineKeywordRecommender() - : base(SyntaxKind.DefineKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext && context.SyntaxTree.IsBeforeFirstToken(position, cancellationToken); diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DescendingKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DescendingKeywordRecommender.cs index 2b3a0c1c0f2ae..75ceeb107e0b9 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DescendingKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DescendingKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class DescendingKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class DescendingKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.DescendingKeyword) { - public DescendingKeywordRecommender() - : base(SyntaxKind.DescendingKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.TargetToken.IsOrderByDirectionContext(); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DisableKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DisableKeywordRecommender.cs index ad3b3dd970523..d673115143674 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DisableKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DisableKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class DisableKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class DisableKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.DisableKeyword, isValidInPreprocessorContext: true) { - public DisableKeywordRecommender() - : base(SyntaxKind.DisableKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var previousToken1 = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoKeywordRecommender.cs index c08d2634c328e..ce5fd34ce6740 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class DoKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class DoKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.DoKeyword) { - public DoKeywordRecommender() - : base(SyntaxKind.DoKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsStatementContext || context.IsGlobalStatementContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoubleKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoubleKeywordRecommender.cs index d3186c219d6c3..dc7e2152708c4 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoubleKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DoubleKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class DoubleKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class DoubleKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.DoubleKeyword) { - public DoubleKeywordRecommender() - : base(SyntaxKind.DoubleKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs index 293458e9899f1..cf6ca16f5a621 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs @@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class DynamicKeywordRecommender : IKeywordRecommender +internal sealed class DynamicKeywordRecommender : IKeywordRecommender { private static bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { @@ -31,7 +31,7 @@ public ImmutableArray RecommendKeywords(int position, CSharp : []; } - protected static bool IsDynamicTypeContext( + private static bool IsDynamicTypeContext( int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ElifKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ElifKeywordRecommender.cs index 5ff98840b21f1..072f5cf512582 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ElifKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ElifKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ElifKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ElifKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ElifKeyword, isValidInPreprocessorContext: true) { - public ElifKeywordRecommender() - : base(SyntaxKind.ElifKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ElseKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ElseKeywordRecommender.cs index 2fe2b078a1522..6390290ae90bb 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ElseKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ElseKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ElseKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ElseKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ElseKeyword, isValidInPreprocessorContext: true) { - public ElseKeywordRecommender() - : base(SyntaxKind.ElseKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (context.IsPreProcessorKeywordContext) diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EnableKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EnableKeywordRecommender.cs index fc345c8f8eec4..b8c56a7511556 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EnableKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EnableKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class EnableKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class EnableKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.EnableKeyword, isValidInPreprocessorContext: true) { - public EnableKeywordRecommender() - : base(SyntaxKind.EnableKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var previousToken1 = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EndIfKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EndIfKeywordRecommender.cs index 3f88e5985b0eb..4c2f537f8ea66 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EndIfKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EndIfKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class EndIfKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class EndIfKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.EndIfKeyword, isValidInPreprocessorContext: true) { - public EndIfKeywordRecommender() - : base(SyntaxKind.EndIfKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EndRegionKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EndRegionKeywordRecommender.cs index 2ce9c088fca51..e97b33bef0bb3 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EndRegionKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EndRegionKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class EndRegionKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class EndRegionKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.EndRegionKeyword, isValidInPreprocessorContext: true, shouldFormatOnCommit: true) { - public EndRegionKeywordRecommender() - : base(SyntaxKind.EndRegionKeyword, isValidInPreprocessorContext: true, shouldFormatOnCommit: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EnumKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EnumKeywordRecommender.cs index d2c0ff0abe005..01ec29d56dfe0 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EnumKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EnumKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class EnumKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class EnumKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.EnumKeyword) { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -19,11 +19,6 @@ internal class EnumKeywordRecommender : AbstractSyntacticSingleKeywordRecommende SyntaxKind.ProtectedKeyword, }; - public EnumKeywordRecommender() - : base(SyntaxKind.EnumKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EqualsKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EqualsKeywordRecommender.cs index 6273639451bc5..94152eed802bd 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EqualsKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/EqualsKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class EqualsKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class EqualsKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.EqualsKeyword) { - public EqualsKeywordRecommender() - : base(SyntaxKind.EqualsKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // cases: diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ErrorKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ErrorKeywordRecommender.cs index c8aac6fad50b5..707f192319b97 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ErrorKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ErrorKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ErrorKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ErrorKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ErrorKeyword, isValidInPreprocessorContext: true) { - public ErrorKeywordRecommender() - : base(SyntaxKind.ErrorKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ExplicitKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ExplicitKeywordRecommender.cs index b0dbf2efebe31..b5613bc31c191 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ExplicitKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ExplicitKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ExplicitKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ExplicitKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ExplicitKeyword) { private static readonly ISet s_validNonInterfaceMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -27,11 +27,6 @@ internal class ExplicitKeywordRecommender : AbstractSyntacticSingleKeywordRecomm SyntaxKind.UnsafeKeyword, }; - public ExplicitKeywordRecommender() - : base(SyntaxKind.ExplicitKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (context.IsMemberDeclarationContext(validModifiers: s_validNonInterfaceMemberModifiers, validTypeDeclarations: SyntaxKindSet.ClassStructRecordTypeDeclarations, canBePartial: false, cancellationToken: cancellationToken)) diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ExternKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ExternKeywordRecommender.cs index 4826f6fe419f2..eae3fea673b0d 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ExternKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ExternKeywordRecommender.cs @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ExternKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ExternKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ExternKeyword) { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -42,11 +42,6 @@ internal class ExternKeywordRecommender : AbstractSyntacticSingleKeywordRecommen SyntaxKind.UnsafeKeyword }; - public ExternKeywordRecommender() - : base(SyntaxKind.ExternKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FalseKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FalseKeywordRecommender.cs index d51e8b52d8879..6f0c1104bbefd 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FalseKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FalseKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class FalseKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class FalseKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.FalseKeyword, isValidInPreprocessorContext: true) { - public FalseKeywordRecommender() - : base(SyntaxKind.FalseKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FileKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FileKeywordRecommender.cs index 73510f4b46dd1..826699f2aa505 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FileKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FileKeywordRecommender.cs @@ -11,17 +11,12 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class FileKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class FileKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.FileKeyword) { private static readonly ISet s_validModifiers = SyntaxKindSet.AllMemberModifiers .Where(s => s != SyntaxKind.FileKeyword && !SyntaxFacts.IsAccessibilityModifier(s)) .ToSet(); - public FileKeywordRecommender() - : base(SyntaxKind.FileKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return context.ContainingTypeDeclaration == null diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FinallyKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FinallyKeywordRecommender.cs index ab711d32b68ec..080bd52098674 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FinallyKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FinallyKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class FinallyKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class FinallyKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.FinallyKeyword) { - public FinallyKeywordRecommender() - : base(SyntaxKind.FinallyKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.SyntaxTree.IsCatchOrFinallyContext(position, context.LeftToken); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FixedKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FixedKeywordRecommender.cs index a7577b1acabfe..f360eab7ab89b 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FixedKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FixedKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class FixedKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class FixedKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.FixedKeyword) { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -21,11 +21,6 @@ internal class FixedKeywordRecommender : AbstractSyntacticSingleKeywordRecommend SyntaxKind.UnsafeKeyword, }; - public FixedKeywordRecommender() - : base(SyntaxKind.FixedKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => IsUnsafeStatementContext(context) || IsMemberDeclarationContext(context, cancellationToken); diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FloatKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FloatKeywordRecommender.cs index 5fd2119e67386..10b3b4312ec66 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FloatKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FloatKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class FloatKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class FloatKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.FloatKeyword) { - public FloatKeywordRecommender() - : base(SyntaxKind.FloatKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ForEachKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ForEachKeywordRecommender.cs index a6205dc9fc236..6f79827f24500 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ForEachKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ForEachKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ForEachKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ForEachKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ForEachKeyword) { - public ForEachKeywordRecommender() - : base(SyntaxKind.ForEachKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ForKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ForKeywordRecommender.cs index f9650905da950..4444c1465c0b0 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ForKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ForKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ForKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ForKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ForKeyword) { - public ForKeywordRecommender() - : base(SyntaxKind.ForKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsStatementContext || context.IsGlobalStatementContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FromKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FromKeywordRecommender.cs index 92e2383fa433a..c1f92982e8030 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FromKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/FromKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class FromKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class FromKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.FromKeyword) { - public FromKeywordRecommender() - : base(SyntaxKind.FromKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GetKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GetKeywordRecommender.cs index 0167db80144ac..aa2cf1e444176 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GetKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GetKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class GetKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class GetKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.GetKeyword) { - public GetKeywordRecommender() - : base(SyntaxKind.GetKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GlobalKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GlobalKeywordRecommender.cs index f2d7e65824754..6a29d5ba5d3a7 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GlobalKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GlobalKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class GlobalKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class GlobalKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.GlobalKeyword) { - public GlobalKeywordRecommender() - : base(SyntaxKind.GlobalKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GotoKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GotoKeywordRecommender.cs index 9e606dbe09025..8c2792cccae3e 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GotoKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GotoKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class GotoKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class GotoKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.GotoKeyword) { - public GotoKeywordRecommender() - : base(SyntaxKind.GotoKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsStatementContext || context.IsGlobalStatementContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GroupKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GroupKeywordRecommender.cs index 4980092241f3c..e8e6425185461 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GroupKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/GroupKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class GroupKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class GroupKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.GroupKeyword) { - public GroupKeywordRecommender() - : base(SyntaxKind.GroupKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var token = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/HiddenKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/HiddenKeywordRecommender.cs index 022299a64f1f4..ea1ec031491f1 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/HiddenKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/HiddenKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class HiddenKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class HiddenKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.HiddenKeyword, isValidInPreprocessorContext: true) { - public HiddenKeywordRecommender() - : base(SyntaxKind.HiddenKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // cases: diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IfKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IfKeywordRecommender.cs index 1499e9b475ada..21e71459b9371 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IfKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IfKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class IfKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class IfKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.IfKeyword, isValidInPreprocessorContext: true) { - public IfKeywordRecommender() - : base(SyntaxKind.IfKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ImplicitKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ImplicitKeywordRecommender.cs index 91665dc9014c9..d55f8a27a49fb 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ImplicitKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ImplicitKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ImplicitKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ImplicitKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ImplicitKeyword) { private static readonly ISet s_validNonInterfaceMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -27,11 +27,6 @@ internal class ImplicitKeywordRecommender : AbstractSyntacticSingleKeywordRecomm SyntaxKind.UnsafeKeyword, }; - public ImplicitKeywordRecommender() - : base(SyntaxKind.ImplicitKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (context.IsMemberDeclarationContext(validModifiers: s_validNonInterfaceMemberModifiers, validTypeDeclarations: SyntaxKindSet.ClassStructRecordTypeDeclarations, canBePartial: false, cancellationToken: cancellationToken)) diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs index 25ebc0dc3647e..fdfed14df36b1 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class InKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class InKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.InKeyword) { - public InKeywordRecommender() - : base(SyntaxKind.InKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InitKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InitKeywordRecommender.cs index 3121422afe03f..afa0035f02b9f 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InitKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InitKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class InitKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class InitKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.InitKeyword) { - public InitKeywordRecommender() - : base(SyntaxKind.InitKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InterfaceKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InterfaceKeywordRecommender.cs index ccd6bab4d1484..83774960dffc7 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InterfaceKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InterfaceKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class InterfaceKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class InterfaceKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.InterfaceKeyword) { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -20,11 +20,6 @@ internal class InterfaceKeywordRecommender : AbstractSyntacticSingleKeywordRecom SyntaxKind.UnsafeKeyword }; - public InterfaceKeywordRecommender() - : base(SyntaxKind.InterfaceKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InternalKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InternalKeywordRecommender.cs index 6836a4e78275d..4cb9888061af8 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InternalKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InternalKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class InternalKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class InternalKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.InternalKeyword) { - public InternalKeywordRecommender() - : base(SyntaxKind.InternalKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IntoKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IntoKeywordRecommender.cs index 4f12793e4f4e6..86e5a72f815a4 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IntoKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IntoKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class IntoKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class IntoKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.IntoKeyword) { - public IntoKeywordRecommender() - : base(SyntaxKind.IntoKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IsKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IsKeywordRecommender.cs index 4f7bcfc2072c5..b1602eda69473 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IsKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/IsKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class IsKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class IsKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.IsKeyword) { - public IsKeywordRecommender() - : base(SyntaxKind.IsKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // cases: diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/JoinKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/JoinKeywordRecommender.cs index 5b292040505d4..fac60b6838946 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/JoinKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/JoinKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class JoinKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class JoinKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.JoinKeyword) { - public JoinKeywordRecommender() - : base(SyntaxKind.JoinKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.SyntaxTree.IsValidContextForJoinClause(position, context.LeftToken); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LetKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LetKeywordRecommender.cs index 9880d572bc173..799bb5981d203 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LetKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LetKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class LetKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class LetKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.LetKeyword) { - public LetKeywordRecommender() - : base(SyntaxKind.LetKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var token = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LineKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LineKeywordRecommender.cs index 645eca23f69ce..6bbe5a76dcc6a 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LineKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LineKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class LineKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class LineKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.LineKeyword, isValidInPreprocessorContext: true) { - public LineKeywordRecommender() - : base(SyntaxKind.LineKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LoadKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LoadKeywordRecommender.cs index 41f1a6bbcbb78..789d3316b4968 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LoadKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LoadKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class LoadKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class LoadKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.LoadKeyword, isValidInPreprocessorContext: true) { - public LoadKeywordRecommender() - : base(SyntaxKind.LoadKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LockKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LockKeywordRecommender.cs index 687866b7874af..a0ffa8605ebd2 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LockKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LockKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class LockKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class LockKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.LockKeyword) { - public LockKeywordRecommender() - : base(SyntaxKind.LockKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsStatementContext || context.IsGlobalStatementContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LongKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LongKeywordRecommender.cs index 54cc4818a037d..eb46e429f065e 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LongKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/LongKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class LongKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class LongKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.LongKeyword) { - public LongKeywordRecommender() - : base(SyntaxKind.LongKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ManagedKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ManagedKeywordRecommender.cs index 843244716dd46..7b8323f12f409 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ManagedKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ManagedKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ManagedKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ManagedKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ManagedKeyword) { - public ManagedKeywordRecommender() - : base(SyntaxKind.ManagedKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.SyntaxTree.IsFunctionPointerCallingConventionContext(context.TargetToken); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ModuleKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ModuleKeywordRecommender.cs index a1d40d6d268a4..8bab53fe1f5ca 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ModuleKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ModuleKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ModuleKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ModuleKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ModuleKeyword) { - public ModuleKeywordRecommender() - : base(SyntaxKind.ModuleKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (context.IsTypeAttributeContext(cancellationToken)) diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NameOfKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NameOfKeywordRecommender.cs index 3046b484e68cc..8e52b33a7467b 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NameOfKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NameOfKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class NameOfKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class NameOfKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.NameOfKeyword) { - public NameOfKeywordRecommender() - : base(SyntaxKind.NameOfKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NamespaceKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NamespaceKeywordRecommender.cs index 4708ade62a49d..7a5b8c98e9d70 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NamespaceKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NamespaceKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class NamespaceKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class NamespaceKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.NamespaceKeyword) { - public NamespaceKeywordRecommender() - : base(SyntaxKind.NamespaceKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NewKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NewKeywordRecommender.cs index a8ba3376974ca..a9fe82cee4220 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NewKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NewKeywordRecommender.cs @@ -12,7 +12,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class NewKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class NewKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.NewKeyword) { private static readonly ISet s_validMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -30,7 +30,7 @@ internal class NewKeywordRecommender : AbstractSyntacticSingleKeywordRecommender SyntaxKind.VolatileKeyword, }; - protected static readonly ISet ValidTypeModifiers = new HashSet(SyntaxFacts.EqualityComparer) + private static readonly ISet ValidTypeModifiers = new HashSet(SyntaxFacts.EqualityComparer) { SyntaxKind.AbstractKeyword, SyntaxKind.InternalKeyword, @@ -42,11 +42,6 @@ internal class NewKeywordRecommender : AbstractSyntacticSingleKeywordRecommender SyntaxKind.UnsafeKeyword }; - public NewKeywordRecommender() - : base(SyntaxKind.NewKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotKeywordRecommender.cs index 580ac26655f37..047de30f2a829 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class NotKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class NotKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.NotKeyword) { - public NotKeywordRecommender() - : base(SyntaxKind.NotKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsAtStartOfPattern; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotnullKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotnullKeywordRecommender.cs index 16d25b78936d1..996ee34cf0871 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotnullKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NotnullKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class NotNullKeywordRecommender : IKeywordRecommender +internal sealed class NotNullKeywordRecommender : IKeywordRecommender { public ImmutableArray RecommendKeywords(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NullKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NullKeywordRecommender.cs index bc4d1b532abfb..201df1ecf8f59 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NullKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NullKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class NullKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class NullKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.NullKeyword) { - public NullKeywordRecommender() - : base(SyntaxKind.NullKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsAnyExpressionContext || context.IsStatementContext || diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NullableKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NullableKeywordRecommender.cs index de2074a42b9d3..ee8b1f254697a 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NullableKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/NullableKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class NullableKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class NullableKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.NullableKeyword, isValidInPreprocessorContext: true) { - public NullableKeywordRecommender() - : base(SyntaxKind.NullableKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ObjectKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ObjectKeywordRecommender.cs index 88e691ef9650b..e4b4c6b996d14 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ObjectKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ObjectKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ObjectKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class ObjectKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.ObjectKeyword) { - public ObjectKeywordRecommender() - : base(SyntaxKind.ObjectKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OnKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OnKeywordRecommender.cs index 3a837c275a228..df24c6cc1b69f 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OnKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OnKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class OnKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class OnKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.OnKeyword) { - public OnKeywordRecommender() - : base(SyntaxKind.OnKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // cases: diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OperatorKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OperatorKeywordRecommender.cs index d84e2761e63d2..1e833ae9a3755 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OperatorKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OperatorKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class OperatorKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class OperatorKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.OperatorKeyword) { - public OperatorKeywordRecommender() - : base(SyntaxKind.OperatorKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // cases: diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrKeywordRecommender.cs index 325167c1cb05b..026f7552bd6a0 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class OrKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class OrKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.OrKeyword) { - public OrKeywordRecommender() - : base(SyntaxKind.OrKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsAtEndOfPattern; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrderByKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrderByKeywordRecommender.cs index dbd6cd10a614e..b56b9616675b4 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrderByKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OrderByKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class OrderByKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class OrderByKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.OrderByKeyword) { - public OrderByKeywordRecommender() - : base(SyntaxKind.OrderByKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var token = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OutKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OutKeywordRecommender.cs index 1197922281e17..3185ca210629a 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OutKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OutKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class OutKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class OutKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.OutKeyword) { - public OutKeywordRecommender() - : base(SyntaxKind.OutKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OverrideKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OverrideKeywordRecommender.cs index 754299cd041cb..50c90bd7ec639 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OverrideKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/OverrideKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class OverrideKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class OverrideKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.OverrideKeyword) { private static readonly ISet s_validMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -23,11 +23,6 @@ internal class OverrideKeywordRecommender : AbstractSyntacticSingleKeywordRecomm SyntaxKind.AbstractKeyword, }; - public OverrideKeywordRecommender() - : base(SyntaxKind.OverrideKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (!context.IsMemberDeclarationContext( diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ParamsKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ParamsKeywordRecommender.cs index 51bca79b76354..309050b9264b9 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ParamsKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ParamsKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ParamsKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ParamsKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ParamsKeyword) { - public ParamsKeywordRecommender() - : base(SyntaxKind.ParamsKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.SyntaxTree.IsParamsModifierContext(position, context.LeftToken, cancellationToken); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PartialKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PartialKeywordRecommender.cs index 6a708de5cc59c..cf5fdf9fdd792 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PartialKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PartialKeywordRecommender.cs @@ -12,13 +12,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class PartialKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class PartialKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.PartialKeyword) { - public PartialKeywordRecommender() - : base(SyntaxKind.PartialKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PragmaKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PragmaKeywordRecommender.cs index 343e7a168d418..14753537a9009 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PragmaKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PragmaKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class PragmaKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class PragmaKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.PragmaKeyword, isValidInPreprocessorContext: true) { - public PragmaKeywordRecommender() - : base(SyntaxKind.PragmaKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PrivateKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PrivateKeywordRecommender.cs index dd696e8abad99..d55b64cf290af 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PrivateKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PrivateKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class PrivateKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class PrivateKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.PrivateKeyword) { - public PrivateKeywordRecommender() - : base(SyntaxKind.PrivateKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ProtectedKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ProtectedKeywordRecommender.cs index 5241f912c44a8..8bbf2040af5d3 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ProtectedKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ProtectedKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ProtectedKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ProtectedKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ProtectedKeyword) { - public ProtectedKeywordRecommender() - : base(SyntaxKind.ProtectedKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PublicKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PublicKeywordRecommender.cs index 095a3289e7738..8be51c700cbf4 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PublicKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/PublicKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class PublicKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class PublicKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.PublicKeyword) { - public PublicKeywordRecommender() - : base(SyntaxKind.PublicKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs index 074bcc4111aac..b6790f0fb13c3 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReadOnlyKeywordRecommender.cs @@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ReadOnlyKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ReadOnlyKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ReadOnlyKeyword) { private static readonly ISet s_validMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -23,11 +23,6 @@ internal class ReadOnlyKeywordRecommender : AbstractSyntacticSingleKeywordRecomm SyntaxKind.StaticKeyword, }; - public ReadOnlyKeywordRecommender() - : base(SyntaxKind.ReadOnlyKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RecordKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RecordKeywordRecommender.cs index e714ba81a1001..b6498e51623fd 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RecordKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RecordKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class RecordKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class RecordKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.RecordKeyword) { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -26,11 +26,6 @@ internal class RecordKeywordRecommender : AbstractSyntacticSingleKeywordRecommen SyntaxKind.FileKeyword, }; - public RecordKeywordRecommender() - : base(SyntaxKind.RecordKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RefKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RefKeywordRecommender.cs index 73c48681ebb1d..d9c2e053e263c 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RefKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RefKeywordRecommender.cs @@ -12,13 +12,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class RefKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class RefKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.RefKeyword) { - public RefKeywordRecommender() - : base(SyntaxKind.RefKeyword) - { - } - /// /// Same as with ref specific exclusions /// diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReferenceKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReferenceKeywordRecommender.cs index 08ee7bb6211c7..7fef0850b6520 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReferenceKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReferenceKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ReferenceKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ReferenceKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ReferenceKeyword, isValidInPreprocessorContext: true) { - public ReferenceKeywordRecommender() - : base(SyntaxKind.ReferenceKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RegionKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RegionKeywordRecommender.cs index 82456ae718e0a..2c95fa7443db3 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RegionKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RegionKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class RegionKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class RegionKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.RegionKeyword, isValidInPreprocessorContext: true, shouldFormatOnCommit: true) { - public RegionKeywordRecommender() - : base(SyntaxKind.RegionKeyword, isValidInPreprocessorContext: true, shouldFormatOnCommit: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsPreProcessorKeywordContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RemoveKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RemoveKeywordRecommender.cs index 05fad0d3880bd..769711c3b6c83 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RemoveKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RemoveKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class RemoveKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class RemoveKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.RemoveKeyword) { - public RemoveKeywordRecommender() - : base(SyntaxKind.RemoveKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.TargetToken.IsAccessorDeclarationContext(position, SyntaxKind.RemoveKeyword); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RequiredKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RequiredKeywordRecommender.cs index e6e4ac276dc54..69302638b1dea 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RequiredKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RequiredKeywordRecommender.cs @@ -11,17 +11,12 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class RequiredKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class RequiredKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.RequiredKeyword) { private static readonly ISet s_validModifiers = SyntaxKindSet.AllMemberModifiers.Where(s => s is not (SyntaxKind.RequiredKeyword or SyntaxKind.StaticKeyword or SyntaxKind.ReadOnlyKeyword or SyntaxKind.ConstKeyword)).ToSet(); private static readonly ISet s_validTypeDeclarations = SyntaxKindSet.ClassStructRecordTypeDeclarations; - public RequiredKeywordRecommender() - : base(SyntaxKind.RequiredKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return context.IsMemberDeclarationContext(s_validModifiers, s_validTypeDeclarations, canBePartial: true, cancellationToken); diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RestoreKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RestoreKeywordRecommender.cs index d061038fa0b36..c34a11a74d73d 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RestoreKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/RestoreKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class RestoreKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class RestoreKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.RestoreKeyword, isValidInPreprocessorContext: true) { - public RestoreKeywordRecommender() - : base(SyntaxKind.RestoreKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var previousToken1 = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReturnKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReturnKeywordRecommender.cs index 73026436d41e1..ee00a28734d29 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReturnKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReturnKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ReturnKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ReturnKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ReturnKeyword) { - public ReturnKeywordRecommender() - : base(SyntaxKind.ReturnKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SByteKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SByteKeywordRecommender.cs index 8ed9464600648..b560a631187b9 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SByteKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SByteKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class SByteKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class SByteKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.SByteKeyword) { - public SByteKeywordRecommender() - : base(SyntaxKind.SByteKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SealedKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SealedKeywordRecommender.cs index 47ea6d582d493..06f7427bd5e6a 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SealedKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SealedKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class SealedKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class SealedKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.SealedKeyword) { private static readonly ISet s_validNonInterfaceMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -45,11 +45,6 @@ internal class SealedKeywordRecommender : AbstractSyntacticSingleKeywordRecommen SyntaxKind.FileKeyword, }; - public SealedKeywordRecommender() - : base(SyntaxKind.SealedKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SelectKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SelectKeywordRecommender.cs index 628dc12cd2a45..2cc550777ef3f 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SelectKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SelectKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class SelectKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class SelectKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.SelectKeyword) { - public SelectKeywordRecommender() - : base(SyntaxKind.SelectKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var token = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SetKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SetKeywordRecommender.cs index b814c8efe45b6..aafb4473eaaf0 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SetKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SetKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class SetKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class SetKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.SetKeyword) { - public SetKeywordRecommender() - : base(SyntaxKind.SetKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ShortKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ShortKeywordRecommender.cs index ec64422318929..72016032d7fef 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ShortKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ShortKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ShortKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class ShortKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.ShortKeyword) { - public ShortKeywordRecommender() - : base(SyntaxKind.ShortKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SizeOfKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SizeOfKeywordRecommender.cs index 8118f88558edf..ab07ec1d945e0 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SizeOfKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SizeOfKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class SizeOfKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class SizeOfKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.SizeOfKeyword) { - public SizeOfKeywordRecommender() - : base(SyntaxKind.SizeOfKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StackAllocKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StackAllocKeywordRecommender.cs index 79e12b7bc40c7..32969cbf57c5b 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StackAllocKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StackAllocKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class StackAllocKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class StackAllocKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.StackAllocKeyword) { - public StackAllocKeywordRecommender() - : base(SyntaxKind.StackAllocKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // Beginning with C# 8.0, stackalloc expression can be used inside other expressions diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StaticKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StaticKeywordRecommender.cs index 6ecd476970359..d23bf64a99cc9 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StaticKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StaticKeywordRecommender.cs @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class StaticKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class StaticKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.StaticKeyword) { private static readonly ISet s_validTypeModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -73,11 +73,6 @@ internal class StaticKeywordRecommender : AbstractSyntacticSingleKeywordRecommen SyntaxKind.UnsafeKeyword }; - public StaticKeywordRecommender() - : base(SyntaxKind.StaticKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StringKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StringKeywordRecommender.cs index c249f8a4e6774..0edc8bb598b68 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StringKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StringKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal sealed class StringKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class StringKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.StringKeyword) { - public StringKeywordRecommender() - : base(SyntaxKind.StringKeyword) - { - } - protected override SpecialType SpecialType => SpecialType.System_String; protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StructKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StructKeywordRecommender.cs index 65e0c9813d0eb..904e59f4507f3 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StructKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/StructKeywordRecommender.cs @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class StructKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class StructKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.StructKeyword) { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -24,11 +24,6 @@ internal class StructKeywordRecommender : AbstractSyntacticSingleKeywordRecommen SyntaxKind.FileKeyword, }; - public StructKeywordRecommender() - : base(SyntaxKind.StructKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SwitchKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SwitchKeywordRecommender.cs index 37dd1c2392afd..5ef72fc3605fe 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SwitchKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/SwitchKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class SwitchKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class SwitchKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.SwitchKeyword) { - public SwitchKeywordRecommender() - : base(SyntaxKind.SwitchKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ThisKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ThisKeywordRecommender.cs index a6265c5f1f67e..771d543c67d29 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ThisKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ThisKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ThisKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ThisKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ThisKeyword) { - public ThisKeywordRecommender() - : base(SyntaxKind.ThisKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ThrowKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ThrowKeywordRecommender.cs index 9b5c3719e4a22..7731e70dbaf12 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ThrowKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ThrowKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ThrowKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class ThrowKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.ThrowKeyword) { - public ThrowKeywordRecommender() - : base(SyntaxKind.ThrowKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (context.IsStatementContext || context.IsGlobalStatementContext) diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TrueKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TrueKeywordRecommender.cs index e54d946462601..fe2f15f668fcc 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TrueKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TrueKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class TrueKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class TrueKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.TrueKeyword, isValidInPreprocessorContext: true) { - public TrueKeywordRecommender() - : base(SyntaxKind.TrueKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TryKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TryKeywordRecommender.cs index 61d43d87fb380..fd68d1c27327a 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TryKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TryKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class TryKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class TryKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.TryKeyword) { - public TryKeywordRecommender() - : base(SyntaxKind.TryKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsStatementContext || context.IsGlobalStatementContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeKeywordRecommender.cs index cbd7efb89671e..20568c3c43e18 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class TypeKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class TypeKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.TypeKeyword) { - public TypeKeywordRecommender() - : base(SyntaxKind.TypeKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsTypeAttributeContext(cancellationToken); } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeOfKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeOfKeywordRecommender.cs index 84418bc497561..201a37d676ac0 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeOfKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeOfKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class TypeOfKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class TypeOfKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.TypeOfKeyword) { - public TypeOfKeywordRecommender() - : base(SyntaxKind.TypeOfKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeVarKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeVarKeywordRecommender.cs index 50bbe50118d7c..573bbf764bb00 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeVarKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/TypeVarKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class TypeVarKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class TypeVarKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.TypeVarKeyword) { - public TypeVarKeywordRecommender() - : base(SyntaxKind.TypeVarKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var token = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UIntKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UIntKeywordRecommender.cs index 4a65540388bfe..f287a6b9e0eee 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UIntKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UIntKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class UIntKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class UIntKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.UIntKeyword) { - public UIntKeywordRecommender() - : base(SyntaxKind.UIntKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ULongKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ULongKeywordRecommender.cs index 11b33880b5da6..847d172e2261b 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ULongKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/ULongKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class ULongKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class ULongKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.ULongKeyword) { - public ULongKeywordRecommender() - : base(SyntaxKind.ULongKeyword) - { - } - protected override bool IsValidContextWorker(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UShortKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UShortKeywordRecommender.cs index d97ca289b7d34..d1bdbc1eda4aa 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UShortKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UShortKeywordRecommender.cs @@ -12,13 +12,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class UShortKeywordRecommender : AbstractSpecialTypePreselectingKeywordRecommender +internal sealed class UShortKeywordRecommender() : AbstractSpecialTypePreselectingKeywordRecommender(SyntaxKind.UShortKeyword) { - public UShortKeywordRecommender() - : base(SyntaxKind.UShortKeyword) - { - } - /// /// We set the of this item less than the default value so that /// completion selects the keyword over it as the user starts typing. diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UncheckedKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UncheckedKeywordRecommender.cs index 9edcd2becf758..e191af2005769 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UncheckedKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UncheckedKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class UncheckedKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class UncheckedKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.UncheckedKeyword) { - public UncheckedKeywordRecommender() - : base(SyntaxKind.UncheckedKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UndefKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UndefKeywordRecommender.cs index 18aacb19c9812..821960d7e7328 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UndefKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UndefKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class UndefKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class UndefKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.UndefKeyword, isValidInPreprocessorContext: true) { - public UndefKeywordRecommender() - : base(SyntaxKind.UndefKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UnmanagedKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UnmanagedKeywordRecommender.cs index a1745d7c8f2e8..58a6e822f7732 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UnmanagedKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UnmanagedKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class UnmanagedKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class UnmanagedKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.UnmanagedKeyword) { - public UnmanagedKeywordRecommender() - : base(SyntaxKind.UnmanagedKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return context.SyntaxTree.IsTypeParameterConstraintContext(position, context.LeftToken) || diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UnsafeKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UnsafeKeywordRecommender.cs index df0bb5739fa09..df7b112545684 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UnsafeKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UnsafeKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class UnsafeKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class UnsafeKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.UnsafeKeyword) { private static readonly ISet s_validTypeModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -60,11 +60,6 @@ internal class UnsafeKeywordRecommender : AbstractSyntacticSingleKeywordRecommen SyntaxKind.AsyncKeyword }; - public UnsafeKeywordRecommender() - : base(SyntaxKind.UnsafeKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var syntaxTree = context.SyntaxTree; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UsingKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UsingKeywordRecommender.cs index 4cdafe0a3aa7b..e3918c2f73bb5 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UsingKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/UsingKeywordRecommender.cs @@ -9,13 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class UsingKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class UsingKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.UsingKeyword) { - public UsingKeywordRecommender() - : base(SyntaxKind.UsingKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // cases: diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VarKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VarKeywordRecommender.cs index 1fb8f1fc15076..23e82d602dddd 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VarKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VarKeywordRecommender.cs @@ -9,12 +9,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class VarKeywordRecommender : IKeywordRecommender +internal sealed class VarKeywordRecommender : IKeywordRecommender { - public VarKeywordRecommender() - { - } - private static bool IsValidContext(CSharpSyntaxContext context) { if (context.IsStatementContext || diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VirtualKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VirtualKeywordRecommender.cs index 10ffd1b011c64..60877128448d8 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VirtualKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VirtualKeywordRecommender.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class VirtualKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class VirtualKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.VirtualKeyword) { private static readonly ISet s_validNonInterfaceMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -34,11 +34,6 @@ internal class VirtualKeywordRecommender : AbstractSyntacticSingleKeywordRecomme SyntaxKind.UnsafeKeyword, }; - public VirtualKeywordRecommender() - : base(SyntaxKind.VirtualKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (!context.IsMemberDeclarationContext( diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VolatileKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VolatileKeywordRecommender.cs index 8267b48c2b984..14db9f64c8841 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VolatileKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/VolatileKeywordRecommender.cs @@ -10,7 +10,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class VolatileKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class VolatileKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.VolatileKeyword) { private static readonly ISet s_validMemberModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -22,11 +22,6 @@ internal class VolatileKeywordRecommender : AbstractSyntacticSingleKeywordRecomm SyntaxKind.StaticKeyword, }; - public VolatileKeywordRecommender() - : base(SyntaxKind.VolatileKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WarningKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WarningKeywordRecommender.cs index 3e762bf3e53f8..11c2b8d1ea9eb 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WarningKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WarningKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class WarningKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class WarningKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.WarningKeyword, isValidInPreprocessorContext: true) { - public WarningKeywordRecommender() - : base(SyntaxKind.WarningKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { // # warning diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WarningsKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WarningsKeywordRecommender.cs index 7a142ef1080d8..a4dbf2fc7163b 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WarningsKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WarningsKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class WarningsKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class WarningsKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.WarningsKeyword, isValidInPreprocessorContext: true) { - public WarningsKeywordRecommender() - : base(SyntaxKind.WarningsKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { var previousToken1 = context.TargetToken; diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhenKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhenKeywordRecommender.cs index eaeebe9bed1c6..4b896f470d049 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhenKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhenKeywordRecommender.cs @@ -10,13 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class WhenKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class WhenKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.WhenKeyword, isValidInPreprocessorContext: true) { - public WhenKeywordRecommender() - : base(SyntaxKind.WhenKeyword, isValidInPreprocessorContext: true) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return context.IsCatchFilterContext || diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhereKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhereKeywordRecommender.cs index 54e09fcf7e941..30164f90c309f 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhereKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhereKeywordRecommender.cs @@ -11,13 +11,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class WhereKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class WhereKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.WhereKeyword) { - public WhereKeywordRecommender() - : base(SyntaxKind.WhereKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { return diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhileKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhileKeywordRecommender.cs index b1fc429f226ba..e36db8cfae7c1 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhileKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhileKeywordRecommender.cs @@ -8,13 +8,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class WhileKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class WhileKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.WhileKeyword) { - public WhileKeywordRecommender() - : base(SyntaxKind.WhileKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) { if (context.IsStatementContext || diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WithKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WithKeywordRecommender.cs index de122a95edc0c..4289f46d4156d 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WithKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WithKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class WithKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class WithKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.WithKeyword) { - public WithKeywordRecommender() - : base(SyntaxKind.WithKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => !context.IsInNonUserCode && context.IsIsOrAsOrSwitchOrWithExpressionContext; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/YieldKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/YieldKeywordRecommender.cs index 8792b57a6e950..e3cd6e56af5e5 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/YieldKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/YieldKeywordRecommender.cs @@ -7,13 +7,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders; -internal class YieldKeywordRecommender : AbstractSyntacticSingleKeywordRecommender +internal sealed class YieldKeywordRecommender() : AbstractSyntacticSingleKeywordRecommender(SyntaxKind.YieldKeyword) { - public YieldKeywordRecommender() - : base(SyntaxKind.YieldKeyword) - { - } - protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.IsStatementContext; } diff --git a/src/Features/Core/Portable/InitializeParameter/AbstractAddParameterCheckCodeRefactoringProvider.cs b/src/Features/Core/Portable/InitializeParameter/AbstractAddParameterCheckCodeRefactoringProvider.cs index 627d67cd72741..d0fa8ba6bfb07 100644 --- a/src/Features/Core/Portable/InitializeParameter/AbstractAddParameterCheckCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/InitializeParameter/AbstractAddParameterCheckCodeRefactoringProvider.cs @@ -10,7 +10,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Operations; @@ -19,7 +18,6 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.InitializeParameter; @@ -43,6 +41,17 @@ internal abstract class AbstractAddParameterCheckCodeRefactoringProvider< where TBinaryExpressionSyntax : TExpressionSyntax where TSimplifierOptions : SimplifierOptions { + private const string s_isPrefix = "Is"; + private const string s_throwIfPrefix = "ThrowIf"; + + private const string s_nullSuffix = "Null"; + private const string s_nullOrEmptySuffix = "NullOrEmpty"; + private const string s_nullOrWhiteSpaceSuffix = "NullOrWhiteSpace"; + + private const string s_throwIfNullName = s_throwIfPrefix + s_nullSuffix; + private const string s_throwIfNullOrEmptyName = s_throwIfPrefix + s_nullOrEmptySuffix; + private const string s_throwIfNullOrWhiteSpaceName = s_throwIfPrefix + s_nullOrWhiteSpaceSuffix; + protected abstract bool CanOffer(SyntaxNode body); protected abstract bool PrefersThrowExpression(TSimplifierOptions options); protected abstract string EscapeResourceString(string input); @@ -109,12 +118,12 @@ protected override async Task> GetRefactoringsForSing { result.Add(CodeAction.Create( FeaturesResources.Add_string_IsNullOrEmpty_check, - cancellationToken => AddStringCheckAsync(document, parameter, functionDeclaration, methodSymbol, blockStatementOpt, nameof(string.IsNullOrEmpty), simplifierOptions, cancellationToken), + cancellationToken => AddStringCheckAsync(document, parameter, functionDeclaration, methodSymbol, blockStatementOpt, s_nullOrEmptySuffix, simplifierOptions, cancellationToken), nameof(FeaturesResources.Add_string_IsNullOrEmpty_check))); result.Add(CodeAction.Create( FeaturesResources.Add_string_IsNullOrWhiteSpace_check, - cancellationToken => AddStringCheckAsync(document, parameter, functionDeclaration, methodSymbol, blockStatementOpt, nameof(string.IsNullOrWhiteSpace), simplifierOptions, cancellationToken), + cancellationToken => AddStringCheckAsync(document, parameter, functionDeclaration, methodSymbol, blockStatementOpt, s_nullOrWhiteSpaceSuffix, simplifierOptions, cancellationToken), nameof(FeaturesResources.Add_string_IsNullOrWhiteSpace_check))); } @@ -159,7 +168,7 @@ private async Task UpdateDocumentForRefactoringAsync( // commonly used in this regard according to telemetry and UX testing. if (parameter.Type.SpecialType == SpecialType.System_String) { - document = await AddStringCheckAsync(document, parameter, functionDeclaration, (IMethodSymbol)parameter.ContainingSymbol, blockStatementOpt, nameof(string.IsNullOrEmpty), lazySimplifierOptions, cancellationToken).ConfigureAwait(false); + document = await AddStringCheckAsync(document, parameter, functionDeclaration, (IMethodSymbol)parameter.ContainingSymbol, blockStatementOpt, s_nullOrEmptySuffix, lazySimplifierOptions, cancellationToken).ConfigureAwait(false); continue; } @@ -279,6 +288,9 @@ protected bool ParameterValidForNullCheck(Document document, IParameterSymbol pa if (IsIfNullCheck(statement, parameter)) return false; + if (IsAnyThrowIfNullInvocation(statement, parameter)) + return false; + if (ContainsNullCoalesceCheck( syntaxFacts, semanticModel, statement, parameter, cancellationToken)) @@ -291,11 +303,32 @@ protected bool ParameterValidForNullCheck(Document document, IParameterSymbol pa return true; } + private static bool IsAnyThrowIfNullInvocation(IOperation statement, IParameterSymbol? parameter) + { + if (statement is IExpressionStatementOperation + { + Operation: IInvocationOperation + { + TargetMethod: + { + ContainingType.Name: nameof(ArgumentNullException) or nameof(ArgumentException), + Name: s_throwIfNullName or s_throwIfNullOrEmptyName or s_throwIfNullOrWhiteSpaceName, + }, + Arguments: [{ Value: var argumentValue }, ..] + } + }) + { + if (argumentValue.UnwrapImplicitConversion() is IParameterReferenceOperation parameterReference) + return parameter is null || parameter.Equals(parameterReference.Parameter); + } + + return false; + } + private static bool IsStringCheck(IOperation condition, IParameterSymbol parameter) { - if (condition is IInvocationOperation invocation && - invocation.Arguments.Length == 1 && - IsParameterReference(invocation.Arguments[0].Value, parameter)) + if (condition is IInvocationOperation { Arguments: [{ Value: var argumentValue }] } invocation && + IsParameterReference(argumentValue, parameter)) { var targetMethod = invocation.TargetMethod; if (targetMethod?.Name is nameof(string.IsNullOrEmpty) or nameof(string.IsNullOrWhiteSpace)) @@ -337,13 +370,13 @@ private async Task AddStringCheckAsync( SyntaxNode functionDeclaration, IMethodSymbol method, IBlockOperation? blockStatementOpt, - string methodName, + string methodNameSuffix, TSimplifierOptions options, CancellationToken cancellationToken) { return await AddNullCheckStatementAsync( document, parameter, functionDeclaration, method, blockStatementOpt, - (s, g) => CreateStringCheckStatement(s.Compilation, g, parameter, methodName, options), + (s, g) => CreateStringCheckStatement(s.Compilation, g, parameter, methodNameSuffix, options), cancellationToken).ConfigureAwait(false); } @@ -383,23 +416,62 @@ private static async Task AddNullCheckStatementAsync( } private TStatementSyntax CreateNullCheckStatement(SemanticModel semanticModel, SyntaxGenerator generator, IParameterSymbol parameter, TSimplifierOptions options) - => CreateParameterCheckIfStatement( + { + var argumentNullExceptionType = semanticModel.Compilation.ArgumentNullExceptionType(); + if (parameter.Type.IsReferenceType && argumentNullExceptionType != null) + { + var throwIfNullMethod = argumentNullExceptionType + .GetMembers(s_throwIfNullName) + .OfType() + .FirstOrDefault(m => m.Parameters is [{ Type.SpecialType: SpecialType.System_Object }, ..]); + if (throwIfNullMethod != null) + { + return (TStatementSyntax)generator.ExpressionStatement(generator.InvocationExpression( + generator.MemberAccessExpression( + generator.TypeExpression(argumentNullExceptionType), + s_throwIfNullName), + generator.IdentifierName(parameter.Name))); + } + } + + return CreateParameterCheckIfStatement( (TExpressionSyntax)generator.CreateNullCheckExpression(generator.SyntaxGeneratorInternal, semanticModel, parameter.Name), (TStatementSyntax)generator.CreateThrowArgumentNullExceptionStatement(semanticModel.Compilation, parameter), options); + } private TStatementSyntax CreateStringCheckStatement( - Compilation compilation, SyntaxGenerator generator, IParameterSymbol parameter, string methodName, TSimplifierOptions options) + Compilation compilation, SyntaxGenerator generator, IParameterSymbol parameter, string methodNameSuffix, TSimplifierOptions options) { + var argumentExceptionType = compilation.ArgumentExceptionType(); + if (argumentExceptionType != null) + { + var throwMethodName = "ThrowIf" + methodNameSuffix; + var throwIfNullMethod = argumentExceptionType + .GetMembers(throwMethodName) + .OfType() + .FirstOrDefault(m => m.Parameters is [{ Type.SpecialType: SpecialType.System_String }, ..]); + if (throwIfNullMethod != null) + { + return (TStatementSyntax)generator.ExpressionStatement(generator.InvocationExpression( + generator.MemberAccessExpression( + generator.TypeExpression(argumentExceptionType), + throwMethodName), + generator.IdentifierName(parameter.Name))); + } + } + var stringType = compilation.GetSpecialType(SpecialType.System_String); // generates: if (string.IsXXX(s)) throw new ArgumentException("message", nameof(s)) + var isMethodName = s_isPrefix + methodNameSuffix; var condition = (TExpressionSyntax)generator.InvocationExpression( - generator.MemberAccessExpression( - generator.TypeExpression(stringType), - generator.IdentifierName(methodName)), - generator.Argument(generator.IdentifierName(parameter.Name))); - var throwStatement = (TStatementSyntax)generator.ThrowStatement(CreateArgumentException(compilation, generator, parameter, methodName)); + generator.MemberAccessExpression( + generator.TypeExpression(stringType), + generator.IdentifierName(isMethodName)), + generator.Argument(generator.IdentifierName(parameter.Name))); + var throwStatement = (TStatementSyntax)generator.ThrowStatement( + CreateArgumentException(compilation, generator, parameter, isMethodName)); return CreateParameterCheckIfStatement(condition, throwStatement, options); } @@ -465,6 +537,14 @@ private TStatementSyntax CreateStringCheckStatement( if (statement.IsImplicit) continue; + if (IsAnyThrowIfNullInvocation(statement, parameter: null)) + { + if (IsAnyThrowIfNullInvocation(statement, parameterSymbol)) + return statement; + + continue; + } + if (statement is IConditionalOperation ifStatement) { if (ContainsParameterReference(semanticModel, ifStatement.Condition, parameterSymbol, cancellationToken)) @@ -473,7 +553,7 @@ private TStatementSyntax CreateStringCheckStatement( continue; } - // Stop hunting after we hit something that isn't an if-statement + // Stop hunting after we hit something that isn't an if-statement or a ThrowIfNull invocation. break; } } diff --git a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnostics.cs b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnostics.cs index fde9ccf338bd9..88489fcb8b566 100644 --- a/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnostics.cs +++ b/src/LanguageServer/Protocol/Features/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnostics.cs @@ -18,9 +18,9 @@ internal partial class DiagnosticAnalyzerService { private partial class DiagnosticIncrementalAnalyzer { - public async Task> GetDiagnosticsForIdsAsync(Project project, DocumentId? documentId, ImmutableHashSet? diagnosticIds, Func? shouldIncludeAnalyzer, bool includeLocalDocumentDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken) + public Task> GetDiagnosticsForIdsAsync(Project project, DocumentId? documentId, ImmutableHashSet? diagnosticIds, Func? shouldIncludeAnalyzer, bool includeLocalDocumentDiagnostics, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken) { - return await ProduceProjectDiagnosticsAsync( + return ProduceProjectDiagnosticsAsync( project, diagnosticIds, shouldIncludeAnalyzer, // Ensure we compute and return diagnostics for both the normal docs and the additional docs in this // project if no specific document id was requested. @@ -29,23 +29,23 @@ public async Task> GetDiagnosticsForIdsAsync(Proj includeNonLocalDocumentDiagnostics, // return diagnostics specific to one project or document includeProjectNonLocalResult: documentId == null, - cancellationToken).ConfigureAwait(false); + cancellationToken); } - public async Task> GetProjectDiagnosticsForIdsAsync( + public Task> GetProjectDiagnosticsForIdsAsync( Project project, ImmutableHashSet? diagnosticIds, Func? shouldIncludeAnalyzer, bool includeNonLocalDocumentDiagnostics, CancellationToken cancellationToken) { - return await ProduceProjectDiagnosticsAsync( + return ProduceProjectDiagnosticsAsync( project, diagnosticIds, shouldIncludeAnalyzer, documentIds: [], includeLocalDocumentDiagnostics: false, includeNonLocalDocumentDiagnostics: includeNonLocalDocumentDiagnostics, includeProjectNonLocalResult: true, - cancellationToken).ConfigureAwait(false); + cancellationToken); } private async Task> ProduceProjectDiagnosticsAsync( diff --git a/src/VisualStudio/Core/Def/Workspace/VisualStudioSymbolNavigationService.cs b/src/VisualStudio/Core/Def/Workspace/VisualStudioSymbolNavigationService.cs index 6de40fd0dc600..dd9fd0caf3f98 100644 --- a/src/VisualStudio/Core/Def/Workspace/VisualStudioSymbolNavigationService.cs +++ b/src/VisualStudio/Core/Def/Workspace/VisualStudioSymbolNavigationService.cs @@ -154,7 +154,13 @@ internal sealed partial class VisualStudioSymbolNavigationService( ErrorHandler.ThrowOnFailure(windowFrame.SetProperty((int)__VSFPROPID5.VSFPROPID_OverrideToolTip, result.DocumentTooltip)); } + // Subtle issue. We may already be in a provisional-tab. 'Showing' the window frame here will cause it to + // to take over the curren provisional-tab, cause a wait-indicators in the original to be dismissed (causing + // cancellation). To avoid that problem, we disable cancellation from this point. While not ideal, it is + // not problematic as we already forced the document to be opened here. So actually navigating to the + // location in it is effectively free. windowFrame.Show(); + cancellationToken = default; var openedDocument = textBuffer?.AsTextContainer().GetRelatedDocuments().FirstOrDefault(); if (openedDocument != null) diff --git a/src/Workspaces/CSharpTest/Formatting/CSharpFormattingTestBase.cs b/src/Workspaces/CSharpTest/Formatting/CSharpFormattingTestBase.cs index 91bd5f6c19791..481000073bcce 100644 --- a/src/Workspaces/CSharpTest/Formatting/CSharpFormattingTestBase.cs +++ b/src/Workspaces/CSharpTest/Formatting/CSharpFormattingTestBase.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.UnitTests.Formatting; @@ -21,7 +22,7 @@ protected override SyntaxNode ParseCompilation(string text, ParseOptions? parseO => SyntaxFactory.ParseCompilationUnit(text, options: (CSharpParseOptions?)parseOptions); private protected Task AssertNoFormattingChangesAsync( - string code, + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, OptionsCollection? changedOptionSet = null, bool testWithTransformation = true, ParseOptions? parseOptions = null) @@ -30,8 +31,8 @@ private protected Task AssertNoFormattingChangesAsync( } private protected Task AssertFormatAsync( - string expected, - string code, + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expected, + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, OptionsCollection? changedOptionSet = null, bool testWithTransformation = true, ParseOptions? parseOptions = null) @@ -40,8 +41,8 @@ private protected Task AssertFormatAsync( } private protected Task AssertFormatAsync( - string expected, - string code, + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string expected, + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, IEnumerable spans, OptionsCollection? changedOptionSet = null, bool testWithTransformation = true, diff --git a/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs b/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs index ae5911669009c..eff9d9480881d 100644 --- a/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs +++ b/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Threading; using System.Threading.Tasks; @@ -15,10968 +13,12493 @@ using Xunit; using static Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions2; -namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Formatting -{ - using static CSharpSyntaxTokens; - - [Trait(Traits.Feature, Traits.Features.Formatting)] - public class FormattingTests : CSharpFormattingTestBase - { - [Fact] - public async Task Format1() - => await AssertFormatAsync("namespace A { }", "namespace A{}"); +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Formatting; - [Fact] - public async Task Format2() - { - var content = @"class A { - }"; +using static CSharpSyntaxTokens; - var expected = @"class A +[Trait(Traits.Feature, Traits.Features.Formatting)] +public sealed class FormattingTests : CSharpFormattingTestBase { -}"; - await AssertFormatAsync(expected, content); - } + [Fact] + public async Task Format1() + => await AssertFormatAsync("namespace A { }", "namespace A{}"); - [Fact] - public async Task Format3() - { - var content = @"class A - { -int i = 20 ; }"; + [Fact] + public async Task Format2() + { + var content = """ + class A { + } + """; - var expected = @"class A -{ - int i = 20; -}"; + var expected = """ + class A + { + } + """; + await AssertFormatAsync(expected, content); + } - await AssertFormatAsync(expected, content); - } + [Fact] + public async Task Format3() + { + var content = """ + class A + { + int i = 20 ; } + """; - [Fact] - public async Task Format4() - { - var content = @"class A - { -int i = 20 ; int j = 1 + 2 ; - T . S = Test ( 10 ) ; - }"; + var expected = """ + class A + { + int i = 20; + } + """; - var expected = @"class A -{ - int i = 20; int j = 1 + 2; - T.S = Test( 10 ); -}"; + await AssertFormatAsync(expected, content); + } - await AssertFormatAsync(expected, content); - } + [Fact] + public async Task Format4() + { + var content = """ + class A + { + int i = 20 ; int j = 1 + 2 ; + T . S = Test ( 10 ) ; + } + """; - [Fact] - public async Task Format5() - { - var content = @"class A - { - List < int > Method < TArg , TArg2 > ( TArg a, TArg2 b ) - { -int i = 20 ; int j = 1 + 2 ; - T . S = Test ( 10 ) ; - } }"; + var expected = """ + class A + { + int i = 20; int j = 1 + 2; + T.S = Test( 10 ); + } + """; - var expected = @"class A -{ - List Method(TArg a, TArg2 b) - { - int i = 20; int j = 1 + 2; - T.S = Test(10); + await AssertFormatAsync(expected, content); } -}"; - await AssertFormatAsync(expected, content); - } - - [Fact] - public async Task Format6() - { - var content = @"class A - { -A a = new A { - Property1 = 1, Property2 = 3, - Property3 = { 1 , 2 , 3 } }; - }"; - - var expected = @"class A -{ - A a = new A + [Fact] + public async Task Format5() { - Property1 = 1, - Property2 = 3, - Property3 = { 1, 2, 3 } - }; -}"; - - await AssertFormatAsync(expected, content); - } + var content = """ + class A + { + List < int > Method < TArg , TArg2 > ( TArg a, TArg2 b ) + { + int i = 20 ; int j = 1 + 2 ; + T . S = Test ( 10 ) ; + } } + """; - [Fact] - public async Task Format7() - { - var content = @"class A - { - var a = from i in new [ ] { 1 , 2 , 3 } where i > 10 select i ; -}"; + var expected = """ + class A + { + List Method(TArg a, TArg2 b) + { + int i = 20; int j = 1 + 2; + T.S = Test(10); + } + } + """; - var expected = @"class A -{ - var a = from i in new[] { 1, 2, 3 } where i > 10 select i; -}"; + await AssertFormatAsync(expected, content); + } - await AssertFormatAsync(expected, content); - } + [Fact] + public async Task Format6() + { + var content = """ + class A + { + A a = new A { + Property1 = 1, Property2 = 3, + Property3 = { 1 , 2 , 3 } }; + } + """; - [Fact] - public async Task Format8() - { - var content = @"class A - { -void Method() -{ - if (true) - { - } - else if (false) - { - } -} -}"; + var expected = """ + class A + { + A a = new A + { + Property1 = 1, + Property2 = 3, + Property3 = { 1, 2, 3 } + }; + } + """; - var expected = @"class A -{ - void Method() - { - if (true) - { - } - else if (false) - { - } + await AssertFormatAsync(expected, content); } -}"; - await AssertFormatAsync(expected, content); - } + [Fact] + public async Task Format7() + { + var content = """ + class A + { + var a = from i in new [ ] { 1 , 2 , 3 } where i > 10 select i ; + } + """; - [Fact] - public async Task Format9() - { - var content = @"class A - { -void Method() -{ - if (true) { } else if (false) { } -} -}"; + var expected = """ + class A + { + var a = from i in new[] { 1, 2, 3 } where i > 10 select i; + } + """; - var expected = @"class A -{ - void Method() - { - if (true) { } else if (false) { } + await AssertFormatAsync(expected, content); } -}"; - await AssertFormatAsync(expected, content); - } - - [Fact] - public async Task Format10() - { - var content = @"class A - { - var a = from i in new [ ] { 1 , 2 , 3 } -where i > 10 select i ; -}"; + [Fact] + public async Task Format8() + { + var content = """ + class A + { + void Method() + { + if (true) + { + } + else if (false) + { + } + } + } + """; - var expected = @"class A -{ - var a = from i in new[] { 1, 2, 3 } - where i > 10 - select i; -}"; + var expected = """ + class A + { + void Method() + { + if (true) + { + } + else if (false) + { + } + } + } + """; - await AssertFormatAsync(expected, content); - } + await AssertFormatAsync(expected, content); + } - [Fact] - public async Task ObjectInitializer() - { - await AssertFormatAsync(@"public class C -{ - public C() + [Fact] + public async Task Format9() { - C c = new C() - { - c = new C() + var content = """ + class A + { + void Method() { - goo = 1, - bar = 2 + if (true) { } else if (false) { } } - }; - } -}", @"public class C -{ - public C() - { - C c = new C() - { - c = new C() - { - goo = 1, - bar = 2 - } - }; - } -}"); - } + } + """; - [Fact] - public async Task AnonymousType() - { - await AssertFormatAsync(@"class C -{ - C() - { - var anonType = new - { - p3 = new + var expected = """ + class A { - p1 = 3, - p2 = null - }, - p4 = true - }; + void Method() + { + if (true) { } else if (false) { } + } + } + """; + + await AssertFormatAsync(expected, content); } -}", @"class C -{ - C() - { - var anonType = new + + [Fact] + public async Task Format10() { - p3= new - { - p1 = 3, - p2 = null - }, - p4 = true - }; + var content = """ + class A + { + var a = from i in new [ ] { 1 , 2 , 3 } + where i > 10 select i ; + } + """; + + var expected = """ + class A + { + var a = from i in new[] { 1, 2, 3 } + where i > 10 + select i; + } + """; + + await AssertFormatAsync(expected, content); } -}"); - } - [Fact] - public async Task MultilineLambda() - { - await AssertFormatAsync(@"class C -{ - C() + [Fact] + public async Task ObjectInitializer() { - System.Func ret = x => + await AssertFormatAsync(""" + public class C + { + public C() + { + C c = new C() { - System.Func ret2 = y => - { - y++; - return y; - }; - return x + 1; + c = new C() + { + goo = 1, + bar = 2 + } }; + } + } + """, """ + public class C + { + public C() + { + C c = new C() + { + c = new C() + { + goo = 1, + bar = 2 + } + }; + } + } + """); } -}", @"class C -{ - C() + + [Fact] + public async Task AnonymousType() { - System.Func ret = x => + await AssertFormatAsync(""" + class C + { + C() + { + var anonType = new { -System.Func ret2 = y => + p3 = new + { + p1 = 3, + p2 = null + }, + p4 = true + }; + } + } + """, """ + class C + { + C() + { + var anonType = new + { + p3= new { - y++; - return y; - }; - return x + 1; - }; + p1 = 3, + p2 = null + }, + p4 = true + }; + } + } + """); } -}"); - } - [Fact] - public async Task AnonymousMethod() - { - await AssertFormatAsync(@"class C -{ - C() + [Fact] + public async Task MultilineLambda() { - timer.Tick += delegate (object sender, EventArgs e) - { - MessageBox.Show(this, ""Timer ticked""); - }; + await AssertFormatAsync(""" + class C + { + C() + { + System.Func ret = x => + { + System.Func ret2 = y => + { + y++; + return y; + }; + return x + 1; + }; + } + } + """, """ + class C + { + C() + { + System.Func ret = x => + { + System.Func ret2 = y => + { + y++; + return y; + }; + return x + 1; + }; + } + } + """); } -}", @"class C -{ - C() + + [Fact] + public async Task AnonymousMethod() { - timer.Tick += delegate(object sender, EventArgs e) - { - MessageBox.Show(this, ""Timer ticked""); - }; + await AssertFormatAsync(""" + class C + { + C() + { + timer.Tick += delegate (object sender, EventArgs e) + { + MessageBox.Show(this, "Timer ticked"); + }; + } + } + """, """ + class C + { + C() + { + timer.Tick += delegate(object sender, EventArgs e) + { + MessageBox.Show(this, "Timer ticked"); + }; + } + } + """); } -}"); - } - [Fact] - public async Task Scen1() - { - await AssertFormatAsync(@"namespace Namespace1 -{ - class Program + [Fact] + public async Task Scen1() { - static int i = 1 + 2; - - static void Main(string[] args) - { - Program p = new Program(); - - if (i < 5) - i = 0; - - for (i = 0; i < 3; i++) - Console.WriteLine(i); - - while (i < 4) - i++; - - do + await AssertFormatAsync(""" + namespace Namespace1 { - } while (i < 4); + class Program + { + static int i = 1 + 2; - Method(i, ""hello"", true); + static void Main(string[] args) + { + Program p = new Program(); - } + if (i < 5) + i = 0; - static void Method(int i, string s, bool b) - { - } - } -}", @"namespace Namespace1 -{ -class Program -{ -static int i=1+2; + for (i = 0; i < 3; i++) + Console.WriteLine(i); -static void Main(string[] args) -{ -Program p=new Program(); + while (i < 4) + i++; -if (i<5) - i=0; - -for (i=0;i<3;i++) - Console.WriteLine(i); + do + { + } while (i < 4); -while (i<4) - i++; + Method(i, "hello", true); -do{ - }while(i<4); + } -Method(i,""hello"",true); + static void Method(int i, string s, bool b) + { + } + } + } + """, """ + namespace Namespace1 + { + class Program + { + static int i=1+2; -} + static void Main(string[] args) + { + Program p=new Program(); -static void Method(int i, string s, bool b) -{ -} -} -}"); - } + if (i<5) + i=0; + + for (i=0;i<3;i++) + Console.WriteLine(i); - [Fact] - public async Task Scen2() - { - await AssertFormatAsync(@"namespace MyNamespace -{ - class Class1 - { - } - enum E - { - } - namespace NestedNamespace - { - } -} + while (i<4) + i++; -namespace Namespace1 -{ - class Class1 - { - int i; - class NestedClass - { - } - T t; - T Method(RR r) where RR : Class1 - { - return default(T); - } - } + do{ + }while(i<4); - struct S - { - string field1; - bool field2; - public void Method() - { - } - } + Method(i,"hello",true); - enum E - { - Enum1 = 10, - Enum2, - Enum3 + } + + static void Method(int i, string s, bool b) + { + } + } + } + """); } - class Program + [Fact] + public async Task Scen2() { - static int i = 10; - - class NestedClass - { - int field; - class NestedClass2 + await AssertFormatAsync(""" + namespace MyNamespace { - int field; - class NestedClass3 + class Class1 { - enum E + } + enum E + { + } + namespace NestedNamespace + { + } + } + + namespace Namespace1 + { + class Class1 + { + int i; + class NestedClass + { + } + T t; + T Method(RR r) where RR : Class1 + { + return default(T); + } + } + + struct S + { + string field1; + bool field2; + public void Method() { } } - int Prop + + enum E { - get { return field; } - set { field = value; } + Enum1 = 10, + Enum2, + Enum3 } - public void Method() + + class Program { + static int i = 10; + + class NestedClass + { + int field; + class NestedClass2 + { + int field; + class NestedClass3 + { + enum E + { + } + } + int Prop + { + get { return field; } + set { field = value; } + } + public void Method() + { + } + } + } + + struct S + { + string field1; + bool field2; + public void Method() + { + } + } + + enum E + { + Enum1 = 10, + Enum2, + Enum3 + } + + public int Prop + { + get { return i; } + set { i = value; } + } + + static void Main() + { + { + Program p = new Program(); + NestedClass n = new NestedClass(); + } + + if (i < 10) + { + Console.WriteLine(i); + } + + switch (i) + { + case 1: + break; + case 2: + break; + default: + break; + } + + for (i = 0; i < 10; i++) + { + i++; + } + + while (i < 10) + { + i++; + } + + try + { + Console.WriteLine(); + } + catch + { + Console.WriteLine(); + } + finally + { + Console.WriteLine(); + } + + } + public void Method(T t) + { + Console.WriteLine(t.ToString()); + } + } } - } + """, """ + namespace MyNamespace + { + class Class1 + { + } + enum E + { + } + namespace NestedNamespace + { + } + } - struct S - { + namespace Namespace1 + { + class Class1 + { + int i; + class NestedClass + { + } + T t; + T Method(RR r) where RR : Class1 + { + return default(T); + } + } + + struct S + { string field1; - bool field2; + bool field2; public void Method() { } - } + } - enum E - { - Enum1 = 10, + enum E + { + Enum1=10, Enum2, Enum3 - } + } - public int Prop - { - get { return i; } - set { i = value; } - } + class Program + { + static int i = 10; - static void Main() - { + class NestedClass + { + int field; + class NestedClass2 { - Program p = new Program(); - NestedClass n = new NestedClass(); + int field; + class NestedClass3 + { + enum E + { + } } - - if (i < 10) + int Prop { - Console.WriteLine(i); + get {return field;} + set {field=value;} } - - switch (i) + public void Method() { - case 1: - break; - case 2: - break; - default: - break; } + } + } - for (i = 0; i < 10; i++) + struct S + { + string field1; + bool field2; + public void Method() { - i++; } + } - while (i < 10) + enum E { - i++; - } + Enum1 = 10, + Enum2, + Enum3 + } - try + public int Prop { - Console.WriteLine(); - } - catch + get {return i;} + set {i=value;} + } + + static void Main() + { + { + Program p=new Program(); + NestedClass n=new NestedClass(); + } + + if (i<10) { - Console.WriteLine(); + Console.WriteLine(i); } - finally + + switch (i) { - Console.WriteLine(); + case 1: + break; + case 2: + break; + default: + break; + } + + for (i=0;i<10;i++) + { + i++; } - } - public void Method(T t) - { - Console.WriteLine(t.ToString()); - } + while (i<10) + { + i++; + } - } -}", @"namespace MyNamespace -{ - class Class1 - { + try + { + Console.WriteLine(); } -enum E -{ -} - namespace NestedNamespace - { + catch + { + Console.WriteLine(); + } + finally + { + Console.WriteLine(); } -} - -namespace Namespace1 -{ -class Class1 -{ -int i; -class NestedClass -{ -} -T t; - T Method(RR r) where RR : Class1 - { - return default(T); - } - } - -struct S -{ -string field1; - bool field2; -public void Method() -{ -} -} -enum E -{ - Enum1=10, -Enum2, -Enum3 - } + } + public void Method(T t) + { + Console.WriteLine(t.ToString()); + } -class Program -{ -static int i = 10; + } + } + """); + } -class NestedClass -{ - int field; -class NestedClass2 -{ -int field; - class NestedClass3 -{ - enum E + [Fact] + public async Task Scen3() + { + await AssertFormatAsync(""" + namespace Namespace1 + { + class Program { + static void Main() + { + Program p = new Program(); + } } -} -int Prop -{ - get {return field;} - set {field=value;} -} -public void Method() -{ -} -} + } + """, """ + namespace Namespace1 + { + class Program + { + static void Main() + { + Program p=new Program(); + } + } + } + """); } -struct S -{ - string field1; - bool field2; -public void Method() -{ -} - } - -enum E -{ - Enum1 = 10, - Enum2, -Enum3 - } - -public int Prop -{ -get {return i;} -set {i=value;} - } - -static void Main() -{ -{ - Program p=new Program(); -NestedClass n=new NestedClass(); + [Fact] + public async Task Scen4() + { + await AssertFormatAsync(""" + class Class1 + { + // public void goo() + // { + // // TODO: Add the implementation for Class1.goo() here. + // + // } } + """, """ + class Class1 + { + // public void goo() + // { + // // TODO: Add the implementation for Class1.goo() here. + // + // } + } + """); + } -if (i<10) -{ - Console.WriteLine(i); -} - -switch (i) -{ - case 1: - break; - case 2: - break; -default: -break; + [Fact] + public async Task Scen5() + { + await AssertFormatAsync(""" + class Class1 + { + public void Method() + { + { + int i = 0; + System.Console.WriteLine(); + } + } + } + """, """ + class Class1 + { + public void Method() + { + { + int i = 0; + System.Console.WriteLine(); + } + } + } + """); } -for (i=0;i<10;i++) -{ - i++; -} - -while (i<10) -{ - i++; - } - -try -{ - Console.WriteLine(); - } -catch -{ - Console.WriteLine(); - } -finally -{ - Console.WriteLine(); + [Fact] + public async Task Scen6() + { + await AssertFormatAsync(""" + namespace Namespace1 + { + class OuterClass + { + class InnerClass + { + } + } } - -} -public void Method(T t) -{ - Console.WriteLine(t.ToString()); + """, """ + namespace Namespace1 + { + class OuterClass + { + class InnerClass + { } - -} -}"); - } - - [Fact] - public async Task Scen3() - { - await AssertFormatAsync(@"namespace Namespace1 -{ - class Program - { - static void Main() - { - Program p = new Program(); - } + } + } + """); } -}", @"namespace Namespace1 -{ -class Program -{ -static void Main() -{ -Program p=new Program(); -} -} -}"); - } - - [Fact] - public async Task Scen4() - { - await AssertFormatAsync(@"class Class1 -{ - // public void goo() - // { - // // TODO: Add the implementation for Class1.goo() here. - // - // } -}", @"class Class1 -{ - // public void goo() -// { -// // TODO: Add the implementation for Class1.goo() here. -// -// } -}"); - } - [Fact] - public async Task Scen5() - { - await AssertFormatAsync(@"class Class1 -{ - public void Method() + [Fact] + public async Task Scen7() { - { + await AssertFormatAsync(""" + class Class1 + { + public void Method() + { + int i = 0; + switch (i) + { + case 0: + break; + } + if (i > 0) goto z; + i = -i; + z: + i = 2 * i; + } + } + """, """ + class Class1 + { + public void Method() + { int i = 0; - System.Console.WriteLine(); - } - } -}", @"class Class1 -{ -public void Method() -{ -{ -int i = 0; - System.Console.WriteLine(); -} -} -}"); - } - - [Fact] - public async Task Scen6() - { - await AssertFormatAsync(@"namespace Namespace1 -{ - class OuterClass - { - class InnerClass - { - } - } -}", @"namespace Namespace1 -{ -class OuterClass -{ -class InnerClass -{ -} -} -}"); - } - - [Fact] - public async Task Scen7() - { - await AssertFormatAsync(@"class Class1 -{ - public void Method() - { - int i = 0; - switch (i) - { + switch (i) + { case 0: - break; - } - if (i > 0) goto z; - i = -i; - z: - i = 2 * i; + break; + } + if (i > 0) goto z; + i = -i; + z: + i = 2 * i; + } + } + """); } -}", @"class Class1 -{ -public void Method() -{ -int i = 0; -switch (i) -{ -case 0: -break; -} -if (i > 0) goto z; -i = -i; -z: -i = 2 * i; -} -}"); - } - [Fact] - public async Task Scen8() - { - await AssertFormatAsync(@"class Class1 -{ - public void Method() + [Fact] + public async Task Scen8() { - int i = 10; - } -}", @"class Class1 - { + await AssertFormatAsync(""" + class Class1 + { public void Method() - { + { int i = 10; - } -}"); - } + } + } + """, """ + class Class1 + { + public void Method() + { + int i = 10; + } + } + """); + } - [Fact] - public async Task IndentStatementsInMethod() - { - await AssertFormatAsync(@"class C -{ - void Goo() + [Fact] + public async Task IndentStatementsInMethod() { - int x = 0; - int y = 0; - int z = 0; + await AssertFormatAsync(""" + class C + { + void Goo() + { + int x = 0; + int y = 0; + int z = 0; + } + } + """, """ + class C + { + void Goo() + { + int x = 0; + int y = 0; + int z = 0; + } + } + """); } -}", @"class C -{ - void Goo() + + [Fact] + public async Task IndentFieldsInClass() { - int x = 0; - int y = 0; - int z = 0; + await AssertFormatAsync(""" + class C + { + int a = 10; + int b; + int c; + } + """, """ + class C + { + int a = 10; + int b; + int c; + } + """); } -}"); - } - - [Fact] - public async Task IndentFieldsInClass() - { - await AssertFormatAsync(@"class C -{ - int a = 10; - int b; - int c; -}", @"class C -{ - int a = 10; - int b; - int c; -}"); - } - [Fact] - public async Task IndentUserDefaultSettingTest() - { - await AssertFormatAsync(@"class Class2 -{ - public void nothing() + [Fact] + public async Task IndentUserDefaultSettingTest() { - nothing_again(() => + await AssertFormatAsync(""" + class Class2 { - Console.WriteLine(""Nothing""); - }); - label1: - int f = 5; - label2: - switch (f) - { - case 1: + public void nothing() { - break; + nothing_again(() => + { + Console.WriteLine("Nothing"); + }); + label1: + int f = 5; + label2: + switch (f) + { + case 1: + { + break; + } + case 2: + int d = f + f; + label3: + d = d - f; + break; + default: + { + int g = f * f; + g = g - f; + break; + } + } + return; + } + + public void nothing_again(Action a) + { + l: + goto l; } - case 2: + } + """, """ + class Class2 + { + public void nothing() + { + nothing_again(() => + { + Console.WriteLine("Nothing"); + }); + label1: + int f = 5; + label2: + switch (f) + { + case 1: + { + break; + } + case 2: int d = f + f; label3: d = d - f; break; - default: - { - int g = f * f; - g = g - f; - break; + default: + { + int g = f * f; + g = g - f; + break; + } + } + return; + } + + public void nothing_again(Action a) + { + l: + goto l; + } } - } - return; + """); } - public void nothing_again(Action a) - { - l: - goto l; - } -}", @"class Class2 + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/766133")] + public async Task RelativeIndentationToFirstTokenInBaseTokenWithObjectInitializers() { - public void nothing() - { - nothing_again(() => - { - Console.WriteLine(""Nothing""); - }); -label1: - int f = 5; -label2: - switch (f) - { - case 1: + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - break; - } - case 2: - int d = f + f; -label3: - d = d - f; - break; - default: - { - int g = f * f; - g = g - f; - break; - } - } - return; - } + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, + }; + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + var summa = new D { + A = 0, + B = 4 + }; + } + } - public void nothing_again(Action a) - { - l: - goto l; - } - }"); - } + class D + { + public int A { get; set; } + public int B { get; set; } + } + """, """ + class Program + { + static void Main(string[] args) + { + var summa = new D + { + A = 0, + B = 4 + }; + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/766133")] - public async Task RelativeIndentationToFirstTokenInBaseTokenWithObjectInitializers() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class D { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, - }; - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) - { - var summa = new D { - A = 0, - B = 4 - }; + public int A { get; set; } + public int B { get; set; } + } + """, changingOptions); } -} -class D -{ - public int A { get; set; } - public int B { get; set; } -}", @"class Program -{ - static void Main(string[] args) + [Fact] + public async Task RemoveSpacingAroundBinaryOperatorsShouldMakeAtLeastOneSpaceForIsAndAsKeywords() { - var summa = new D + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - A = 0, - B = 4 + { CSharpFormattingOptions2.SpacingAroundBinaryOperator, BinaryOperatorSpacingOptions.Remove } }; - } -} - -class D -{ - public int A { get; set; } - public int B { get; set; } -}", changingOptions); - } - - [Fact] - public async Task RemoveSpacingAroundBinaryOperatorsShouldMakeAtLeastOneSpaceForIsAndAsKeywords() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + await AssertFormatAsync(""" + class Class2 { - { CSharpFormattingOptions2.SpacingAroundBinaryOperator, BinaryOperatorSpacingOptions.Remove } - }; - await AssertFormatAsync(@"class Class2 -{ - public void nothing() - { - var a = 1*2+3-4/5; - a+=1; - object o = null; - string s = o as string; - bool b = o is string; + public void nothing() + { + var a = 1*2+3-4/5; + a+=1; + object o = null; + string s = o as string; + bool b = o is string; + } + } + """, """ + class Class2 + { + public void nothing() + { + var a = 1 * 2 + 3 - 4 / 5; + a += 1; + object o = null; + string s = o as string; + bool b = o is string; + } + } + """, changingOptions); } -}", @"class Class2 - { - public void nothing() - { - var a = 1 * 2 + 3 - 4 / 5; - a += 1; - object o = null; - string s = o as string; - bool b = o is string; - } - }", changingOptions); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772298")] - public async Task IndentUserSettingNonDefaultTest_OpenBracesOfLambdaWithNoNewLine() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { IndentBraces, true }, - { IndentBlock, false }, - { IndentSwitchSection, false }, - { IndentSwitchCaseSection, false }, - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.LambdaExpressionBody, false) }, - { LabelPositioning, LabelPositionOptions.LeftMost } - }; - - await AssertFormatAsync(@"class Class2 + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772298")] + public async Task IndentUserSettingNonDefaultTest_OpenBracesOfLambdaWithNoNewLine() { - public void nothing() + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - nothing_again(() => { - Console.WriteLine(""Nothing""); - }); - } - }", @"class Class2 -{ - public void nothing() - { - nothing_again(() => + { IndentBraces, true }, + { IndentBlock, false }, + { IndentSwitchSection, false }, + { IndentSwitchCaseSection, false }, + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.LambdaExpressionBody, false) }, + { LabelPositioning, LabelPositionOptions.LeftMost } + }; + + await AssertFormatAsync(""" + class Class2 + { + public void nothing() + { + nothing_again(() => { + Console.WriteLine("Nothing"); + }); + } + } + """, """ + class Class2 { - Console.WriteLine(""Nothing""); - }); + public void nothing() + { + nothing_again(() => + { + Console.WriteLine("Nothing"); + }); + } + } + """, changedOptionSet: changingOptions); } -}", changedOptionSet: changingOptions); - } - [Fact] - public async Task IndentUserSettingNonDefaultTest() + [Fact] + public async Task IndentUserSettingNonDefaultTest() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { IndentBraces, true }, - { IndentBlock, false }, - { IndentSwitchSection, false }, - { IndentSwitchCaseSection, false }, - { IndentSwitchCaseSectionWhenBlock, false }, - { LabelPositioning, LabelPositionOptions.LeftMost } - }; - - await AssertFormatAsync(@"class Class2 - { - public void nothing() - { - nothing_again(() => - { - Console.WriteLine(""Nothing""); - }); -label1: - int f = 5; -label2: - switch (f) - { - case 1: - { - break; - } - case 2: - int d = f + f; -label3: - d = d - f; - break; - default: - { - int g = f * f; - g = g - f; - break; - } - } - return; - } + { IndentBraces, true }, + { IndentBlock, false }, + { IndentSwitchSection, false }, + { IndentSwitchCaseSection, false }, + { IndentSwitchCaseSectionWhenBlock, false }, + { LabelPositioning, LabelPositionOptions.LeftMost } + }; - public void nothing_again(Action a) - { -l: - goto l; - } - }", @"class Class2 -{ - public void nothing() - { - nothing_again(() => - { - Console.WriteLine(""Nothing""); - }); - label1: - int f = 5; - label2: - switch (f) - { - case 1: + await AssertFormatAsync(""" + class Class2 { - break; - } - case 2: + public void nothing() + { + nothing_again(() => + { + Console.WriteLine("Nothing"); + }); + label1: + int f = 5; + label2: + switch (f) + { + case 1: + { + break; + } + case 2: int d = f + f; label3: d = d - f; break; - default: + default: + { + int g = f * f; + g = g - f; + break; + } + } + return; + } + + public void nothing_again(Action a) + { + l: + goto l; + } + } + """, """ + class Class2 + { + public void nothing() { - int g = f * f; - g = g - f; - break; + nothing_again(() => + { + Console.WriteLine("Nothing"); + }); + label1: + int f = 5; + label2: + switch (f) + { + case 1: + { + break; + } + case 2: + int d = f + f; + label3: + d = d - f; + break; + default: + { + int g = f * f; + g = g - f; + break; + } + } + return; } - } - return; - } - public void nothing_again(Action a) - { - l: - goto l; + public void nothing_again(Action a) + { + l: + goto l; + } + } + """, changedOptionSet: changingOptions); } -}", changedOptionSet: changingOptions); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] - public async Task IndentSwitch_IndentCase_IndentWhenBlock() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { IndentSwitchSection, true }, - { IndentSwitchCaseSection, true }, - { IndentSwitchCaseSectionWhenBlock, true }, - }; - await AssertFormatAsync( -@"class Class2 -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] + public async Task IndentSwitch_IndentCase_IndentWhenBlock() { - switch (i) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - case 0: + { IndentSwitchSection, true }, + { IndentSwitchCaseSection, true }, + { IndentSwitchCaseSectionWhenBlock, true }, + }; + + await AssertFormatAsync( + """ + class Class2 + { + void M() + { + switch (i) + { + case 0: + { + } + case 1: + break; + } + } + } + """, + """ + class Class2 + { + void M() { + switch (i) { + case 0: { } - case 1: + case 1: break; - } - } -}", -@"class Class2 -{ - void M() - { - switch (i) { - case 0: { - } - case 1: - break; + } + } } + """, changedOptionSet: changingOptions); } -}", changedOptionSet: changingOptions); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] - public async Task IndentSwitch_IndentCase_NoIndentWhenBlock() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { IndentSwitchSection, true }, - { IndentSwitchCaseSection, true }, - { IndentSwitchCaseSectionWhenBlock, false }, - }; - - await AssertFormatAsync( -@"class Class2 -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] + public async Task IndentSwitch_IndentCase_NoIndentWhenBlock() { - switch (i) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - case 0: + { IndentSwitchSection, true }, + { IndentSwitchCaseSection, true }, + { IndentSwitchCaseSectionWhenBlock, false }, + }; + + await AssertFormatAsync( + """ + class Class2 { + void M() + { + switch (i) + { + case 0: + { + } + case 1: + break; + } + } } - case 1: + """, + """ + class Class2 + { + void M() + { + switch (i) { + case 0: { + } + case 1: break; - } - } -}", -@"class Class2 -{ - void M() - { - switch (i) { - case 0: { - } - case 1: - break; + } + } } + """, changedOptionSet: changingOptions); } -}", changedOptionSet: changingOptions); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] - public async Task IndentSwitch_NoIndentCase_IndentWhenBlock() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { IndentSwitchSection, true }, - { IndentSwitchCaseSection, false }, - { IndentSwitchCaseSectionWhenBlock, true }, - }; - await AssertFormatAsync( -@"class Class2 -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] + public async Task IndentSwitch_NoIndentCase_IndentWhenBlock() { - switch (i) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - case 0: + { IndentSwitchSection, true }, + { IndentSwitchCaseSection, false }, + { IndentSwitchCaseSectionWhenBlock, true }, + }; + + await AssertFormatAsync( + """ + class Class2 + { + void M() { + switch (i) + { + case 0: + { + } + case 1: + break; + } } - case 1: - break; - } - } -}", -@"class Class2 -{ - void M() - { - switch (i) { - case 0: { - } - case 1: - break; } - } -}", changedOptionSet: changingOptions); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] - public async Task IndentSwitch_NoIndentCase_NoIndentWhenBlock() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + """, + """ + class Class2 { - { IndentSwitchSection, true }, - { IndentSwitchCaseSection, false }, - { IndentSwitchCaseSectionWhenBlock, false }, - }; + void M() + { + switch (i) { + case 0: { + } + case 1: + break; + } + } + } + """, changedOptionSet: changingOptions); + } - await AssertFormatAsync( -@"class Class2 -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] + public async Task IndentSwitch_NoIndentCase_NoIndentWhenBlock() { - switch (i) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - case 0: + { IndentSwitchSection, true }, + { IndentSwitchCaseSection, false }, + { IndentSwitchCaseSectionWhenBlock, false }, + }; + + await AssertFormatAsync( + """ + class Class2 { + void M() + { + switch (i) + { + case 0: + { + } + case 1: + break; + } + } } - case 1: - break; - } - } -}", -@"class Class2 -{ - void M() - { - switch (i) { - case 0: { - } - case 1: - break; + """, + """ + class Class2 + { + void M() + { + switch (i) { + case 0: { + } + case 1: + break; + } + } } + """, changedOptionSet: changingOptions); } -}", changedOptionSet: changingOptions); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] - public async Task NoIndentSwitch_IndentCase_IndentWhenBlock() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { IndentSwitchSection, false }, - { IndentSwitchCaseSection, true }, - { IndentSwitchCaseSectionWhenBlock, true }, - }; - await AssertFormatAsync( -@"class Class2 -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] + public async Task NoIndentSwitch_IndentCase_IndentWhenBlock() { - switch (i) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - case 0: + { IndentSwitchSection, false }, + { IndentSwitchCaseSection, true }, + { IndentSwitchCaseSectionWhenBlock, true }, + }; + + await AssertFormatAsync( + """ + class Class2 { + void M() + { + switch (i) + { + case 0: + { + } + case 1: + break; + } + } } - case 1: - break; - } - } -}", -@"class Class2 -{ - void M() - { - switch (i) { - case 0: { - } - case 1: - break; + """, + """ + class Class2 + { + void M() + { + switch (i) { + case 0: { + } + case 1: + break; + } + } } + """, changedOptionSet: changingOptions); } -}", changedOptionSet: changingOptions); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] - public async Task NoIndentSwitch_IndentCase_NoIndentWhenBlock() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { IndentSwitchSection, false }, - { IndentSwitchCaseSection, true }, - { IndentSwitchCaseSectionWhenBlock, false }, - }; - await AssertFormatAsync( -@"class Class2 -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] + public async Task NoIndentSwitch_IndentCase_NoIndentWhenBlock() { - switch (i) - { - case 0: + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - } - case 1: - break; - } - } -}", -@"class Class2 -{ - void M() - { - switch (i) { - case 0: { - } - case 1: - break; - } - } -}", changedOptionSet: changingOptions); - } + { IndentSwitchSection, false }, + { IndentSwitchCaseSection, true }, + { IndentSwitchCaseSectionWhenBlock, false }, + }; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] - public async Task NoIndentSwitch_NoIndentCase_IndentWhenBlock() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + await AssertFormatAsync( + """ + class Class2 { - { IndentSwitchSection, false }, - { IndentSwitchCaseSection, false }, - { IndentSwitchCaseSectionWhenBlock, true }, - }; + void M() + { + switch (i) + { + case 0: + { + } + case 1: + break; + } + } + } + """, + """ + class Class2 + { + void M() + { + switch (i) { + case 0: { + } + case 1: + break; + } + } + } + """, changedOptionSet: changingOptions); + } - await AssertFormatAsync( -@"class Class2 -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] + public async Task NoIndentSwitch_NoIndentCase_IndentWhenBlock() { - switch (i) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - case 0: + { IndentSwitchSection, false }, + { IndentSwitchCaseSection, false }, + { IndentSwitchCaseSectionWhenBlock, true }, + }; + + await AssertFormatAsync( + """ + class Class2 { + void M() + { + switch (i) + { + case 0: + { + } + case 1: + break; + } + } } - case 1: - break; - } - } -}", -@"class Class2 -{ - void M() - { - switch (i) { - case 0: { - } - case 1: - break; + """, + """ + class Class2 + { + void M() + { + switch (i) { + case 0: { + } + case 1: + break; + } + } } + """, changedOptionSet: changingOptions); } -}", changedOptionSet: changingOptions); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] - public async Task NoIndentSwitch_NoIndentCase_NoIndentWhenBlock() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20009")] + public async Task NoIndentSwitch_NoIndentCase_NoIndentWhenBlock() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { IndentSwitchSection, false }, + { IndentSwitchCaseSection, false }, + { IndentSwitchCaseSectionWhenBlock, false }, + }; + + await AssertFormatAsync( + """ + class Class2 { - { IndentSwitchSection, false }, - { IndentSwitchCaseSection, false }, - { IndentSwitchCaseSectionWhenBlock, false }, + void M() + { + switch (i) + { + case 0: + { + } + case 1: + break; + } + } + } + """, + """ + class Class2 + { + void M() + { + switch (i) { + case 0: { + } + case 1: + break; + } + } + } + """, changedOptionSet: changingOptions); + } + + [Fact] + public async Task TestWrappingDefault() + { + await AssertFormatAsync(""" + class Class5 + { + delegate void Del(int x); + public int Age { get { int age = 0; return age; } } + public int Age2 + { + get { int age2 = 0; return age2; } + set { int age2 = value; } + } + void bar() + { + int x = 0; + if (x == 1) x = 2; else x = 3; + do { x = 4; } while (x != 4); + switch (x) { case 1: break; case 2: break; default: break; } + Del d = delegate (int k) { Console.WriteLine(); Console.WriteLine(); }; + } + } + """, """ + class Class5 + { + delegate void Del(int x); + public int Age { get { int age = 0; return age; } } + public int Age2 + { + get { int age2 = 0; return age2; } + set { int age2 = value; } + } + void bar() + { + int x = 0; + if(x == 1) x = 2; else x =3; + do { x = 4; } while (x != 4); + switch (x) { case 1: break; case 2: break; default: break; } + Del d = delegate(int k) { Console.WriteLine(); Console.WriteLine(); }; + } + } + """); + } + + [Fact] + public async Task TestWrappingNonDefault_FormatBlock() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.WrappingPreserveSingleLine, false } + }; + await AssertFormatAsync(""" + class Class5 + { + delegate void Del(int x); + public int Age + { + get + { + int age = 0; return age; + } + } + public int Age2 + { + get + { + int age2 = 0; return age2; + } + set + { + int age2 = value; + } + } + void bar() + { + int x = 0; + if (x == 1) x = 2; else x = 3; + do { x = 4; } while (x != 4); + switch (x) + { + case 1: break; + case 2: break; + default: break; + } + Del d = delegate (int k) { Console.WriteLine(); Console.WriteLine(); }; + } + void goo() + { + int xx = 0; int zz = 0; + } + } + class goo + { + int x = 0; + } + """, """ + class Class5 + { + delegate void Del(int x); + public int Age { get { int age = 0; return age; } } + public int Age2 + { + get { int age2 = 0; return age2; } + set { int age2 = value; } + } + void bar() + { + int x = 0; + if(x == 1) x = 2; else x =3; + do { x = 4; } while (x != 4); + switch (x) { case 1: break; case 2: break; default: break; } + Del d = delegate(int k) { Console.WriteLine(); Console.WriteLine(); }; + } + void goo() { int xx = 0; int zz = 0;} + } + class goo{int x = 0;} + """, changingOptions); + } + + [Fact] + public async Task TestWrappingNonDefault_FormatStatmtMethDecl() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } + }; + await AssertFormatAsync(""" + class Class5 + { + delegate void Del(int x); + public int Age { get { int age = 0; return age; } } + public int Age2 + { + get { int age2 = 0; return age2; } + set { int age2 = value; } + } + void bar() + { + int x = 0; + if (x == 1) + x = 2; + else + x = 3; + do + { x = 4; } while (x != 4); + switch (x) + { + case 1: + break; + case 2: + break; + default: + break; + } + Del d = delegate (int k) + { Console.WriteLine(); Console.WriteLine(); }; + } + void goo() { int y = 0; int z = 0; } + } + class goo + { + int x = 0; + } + """, """ + class Class5 + { + delegate void Del(int x); + public int Age { get { int age = 0; return age; } } + public int Age2 + { + get { int age2 = 0; return age2; } + set { int age2 = value; } + } + void bar() + { + int x = 0; + if(x == 1) x = 2; else x =3; + do { x = 4; } while (x != 4); + switch (x) { case 1: break; case 2: break; default: break; } + Del d = delegate(int k) { Console.WriteLine(); Console.WriteLine(); }; + } + void goo(){int y=0; int z =0 ;} + } + class goo + { + int x = 0; + } + """, changingOptions); + } + + [Fact] + public async Task TestWrappingNonDefault() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.WrappingPreserveSingleLine, false }, + { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } + }; + await AssertFormatAsync(""" + class Class5 + { + delegate void Del(int x); + public int Age + { + get + { + int age = 0; + return age; + } + } + public int Age2 + { + get + { + int age2 = 0; + return age2; + } + set + { + int age2 = value; + } + } + void bar() + { + int x = 0; + if (x == 1) + x = 2; + else + x = 3; + do + { + x = 4; + } while (x != 4); + switch (x) + { + case 1: + break; + case 2: + break; + default: + break; + } + Del d = delegate (int k) + { + Console.WriteLine(); + Console.WriteLine(); + }; + } + } + class goo + { + int x = 0; + } + """, """ + class Class5 + { + delegate void Del(int x); + public int Age { get { int age = 0; return age; } } + public int Age2 + { + get { int age2 = 0; return age2; } + set { int age2 = value; } + } + void bar() + { + int x = 0; + if(x == 1) x = 2; else x =3; + do { x = 4; } while (x != 4); + switch (x) { case 1: break; case 2: break; default: break; } + Del d = delegate(int k) { Console.WriteLine(); Console.WriteLine(); }; + } + } + class goo{int x = 0;} + """, changingOptions); + } + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991480")] + public async Task TestLeaveStatementMethodDeclarationSameLineNotAffectingForStatement() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } + }; + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + for (int d = 0; d < 10; ++d) + { } + } + } + """, """ + class Program + { + static void Main(string[] args) + { + for (int d = 0; d < 10; ++d) { } + } + } + """, changingOptions); + } + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/751789")] + public async Task NewLineForOpenBracesDefault() + { + await AssertFormatAsync(""" + class f00 + { + void br() + { + Func ret = x => + { + return x + 1; + }; + var obj = new + { + // ... + }; + if (true) + { + System.Console.WriteLine(""); + } + else + { + } + timer.Tick += delegate (object sender, EventArgs e) + + + { + MessageBox.Show(this, "Timer ticked"); }; - await AssertFormatAsync( -@"class Class2 -{ - void M() + var obj1 = new goo + { + }; + + async void LocalFunction() + { + } + + try + { + } + catch (Exception e) + { + } + finally + { } + + using (someVar) + { + } + + switch (switchVar) + { + default: + break; + } + } + } + + namespace NS1 + { + public class goo : System.Object + + + + { + public int f { get; set; } + } + } + """, """ + class f00 + { + void br() { + Func ret = x => + { + return x + 1; + }; + var obj = new + { + // ... + }; + if(true) + { + System.Console.WriteLine(""); + } + else + { + } + timer.Tick += delegate (object sender, EventArgs e) + + + { + MessageBox.Show(this, "Timer ticked"); + }; + + var obj1 = new goo + { + }; + + async void LocalFunction() { + } + + try + { + } + catch (Exception e) + { + } + finally + {} + + using (someVar) + { + } + + switch (switchVar) + { + default: + break; + } + } + } + + namespace NS1 { + public class goo : System.Object + + + + { + public int f { get; set; } + } + } + """); + } + + [Fact, WorkItem("https://developercommunity.visualstudio.com/content/problem/8808/c-structure-guide-lines-for-unsafe-fixed.html")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/751789")] + public async Task NewLineForOpenBracesNonDefault() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { NewLineBeforeOpenBrace, NewLineBeforeOpenBracePlacement.None } + }; + await AssertFormatAsync(""" + class f00 { + void br() { + Func ret = x => { + return x + 1; + }; + var obj = new { + // ... + }; + if (true) { + System.Console.WriteLine(""); + } + else { + } + timer.Tick += delegate (object sender, EventArgs e) { + MessageBox.Show(this, "Timer ticked"); + }; + + var obj1 = new goo { + }; + + async void LocalFunction() { + } + + try { + } + catch (Exception e) { + } + finally { } + + using (someVar) { + } + + switch (switchVar) { + default: + break; + } + + unsafe { + } + + fixed (int* p = &i) { + } + } + } + + namespace NS1 { + public class goo : System.Object { + } + } + """, """ + class f00 + { + void br() { + Func ret = x => + { + return x + 1; + }; + var obj = new + { + // ... + }; + if(true) + { + System.Console.WriteLine(""); + } + else + { + } + timer.Tick += delegate (object sender, EventArgs e) + + + { + MessageBox.Show(this, "Timer ticked"); + }; + + var obj1 = new goo + { + }; + + async void LocalFunction() + { + } + + try + { + } + catch (Exception e) + { + } + finally + {} + + using (someVar) + { + } + + switch (switchVar) + { + default: + break; + } + + unsafe + { + } + + fixed (int* p = &i) + { + } + } + } + + namespace NS1 { + public class goo : System.Object + + + + { + } + } + """, changingOptions); + } + + [Fact] + public async Task NewLineForKeywordDefault() + { + await AssertFormatAsync(""" + class c + { + void f00() + { + + try + { + // ... + } + catch (Exception e) + { + // ... + } + finally + { + // ... + } + + if (a > b) + { + return 3; + } + else + { + return 0; + } + } + } + """, + """ + class c + { + void f00(){ + + try + { + // ... + } catch (Exception e) + { + // ... + } finally + { + // ... + } + + if (a > b) + { + return 3; + } else + { + return 0; + } + } + } + """); + } + + [Fact] + public async Task NewLineForKeywordNonDefault() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineForElse, false }, + { CSharpFormattingOptions2.NewLineForCatch, false }, + { CSharpFormattingOptions2.NewLineForFinally, false } + }; + await AssertFormatAsync(""" + class c + { + void f00() + { + + try + { + // ... + } catch (Exception e) + { + // ... + } finally + { + // ... + } + if (a > b) + { + return 3; + } else + { + return 0; + } + } + } + """, """ + class c + { + void f00(){ + + try + { + // ... + } + + + catch (Exception e) + { + // ... + } + + + finally + { + // ... + } + if (a > b) + { + return 3; + } + + else + { + return 0; + } + } + } + """, changingOptions); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33458")] + public async Task NoNewLineForElseChecksBraceOwner() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { NewLineForElse, false }, + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, false) } + }; + + await AssertFormatAsync(""" + class Class + { + void Method() + { + if (true) + for (int i = 0; i < 10; i++) { + Method(); + } + else + return; + } + } + """, """ + class Class + { + void Method() + { + if (true) + for (int i = 0; i < 10; i++) { + Method(); + } else + return; + } + } + """, changedOptionSet: changingOptions); + } + + [Fact] + public async Task NewLineForExpressionDefault() + { + await AssertFormatAsync(""" + class f00 + { + void br() + { + var queryLowNums = from num in numbers + where num < 5 + select num; + + var queryLowNums = + + from num in numbers + where num < 5 + select num; + + var q = from c in cust + from o in c.Orders + orderby o.Total descending + select new { c.Name, c.OrderID }; + var obj = new + { + X1 = 0, + Y1 = 1, + X2 = 2, + Y2 = 3 + }; + var obj1 = new { X1 = 0, Y1 = 1, X2 = 2, Y2 = 3 }; + MyObject obj = new MyObject + { + X1 = 0, + Y1 = 1, + X2 = 2, + Y2 = 3 + }; + MyObject obj = new MyObject { X1 = 0, Y1 = 1, X2 = 2, Y2 = 3 }; + } + } + """, """ + class f00 + { + void br() + { + var queryLowNums = from num in numbers where num < 5 + select num; + + var queryLowNums = + + from num in numbers where num < 5 + select num; + + var q = from c in cust + from o in c.Orders orderby o.Total descending + select new { c.Name, c.OrderID }; + var obj = new { X1 = 0, Y1 = 1, + X2 = 2, + Y2 = 3 + }; + var obj1 = new { X1 = 0, Y1 = 1, X2 = 2, Y2 = 3 }; + MyObject obj = new MyObject { X1 = 0, Y1 = 1, + X2 = 2, + Y2 = 3 + }; + MyObject obj = new MyObject { X1 = 0, Y1 = 1, X2 = 2, Y2 = 3 }; + } + } + """); + } + + [Fact] + public async Task NewLineForExpressionNonDefault() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineForMembersInObjectInit, false }, + { CSharpFormattingOptions2.NewLineForMembersInAnonymousTypes, false }, + { CSharpFormattingOptions2.NewLineForClausesInQuery, false } + }; + await AssertFormatAsync(""" + class f00 + { + void br() + { + + var queryLowNums = from num in numbers where num < 5 + select num; + + var queryLowNums = + + from num in numbers where num < 5 + select num; + + var q = from c in cust + from o in c.Orders orderby o.Total descending + select new { c.Name, c.OrderID }; + var obj = new + { + X1 = 0, Y1 = 1, + X2 = 2, + Y2 = 3 + }; + MyObject obj = new MyObject + { + X1 = 0, Y1 = 1, + X2 = 2, + Y2 = 3 + }; + } + } + """, """ + class f00 + { + void br() + { + + var queryLowNums = from num in numbers where num < 5 + select num; + + var queryLowNums = + + from num in numbers where num < 5 + select num; + + var q = from c in cust + from o in c.Orders orderby o.Total descending + select new { c.Name, c.OrderID }; + var obj = new { X1 = 0, Y1 = 1, + X2 = 2, + Y2 = 3 + }; + MyObject obj = new MyObject { X1 = 0, Y1 = 1, + X2 = 2, + Y2 = 3 + }; + } + } + """, changingOptions); + } + + [Fact] + public async Task Enums_Bug2586() + { + await AssertFormatAsync(""" + enum E + { + a = 10, + b, + c + } + """, """ + enum E + { + a = 10, + b, + c + } + """); + } + + [Fact] + public async Task DoNotInsertLineBreaksInSingleLineEnum() + => await AssertFormatAsync(@"enum E { a = 10, b, c }", @"enum E { a = 10, b, c }"); + + [Fact] + public async Task AlreadyFormattedSwitchIsNotFormatted_Bug2588() + { + await AssertFormatAsync(""" + class C + { + void M() + { + switch (3) + { + case 0: + break; + } + } + } + """, """ + class C + { + void M() + { + switch (3) + { + case 0: + break; + } + } + } + """); + } + + [Fact] + public async Task BreaksAreAlignedInSwitchCasesFormatted_Bug2587() + { + await AssertFormatAsync(""" + class C + { + void M() + { + switch (3) + { + case 0: + break; + } + } + } + """, """ + class C + { + void M() + { + switch (3) + { + case 0: + break; + } + } + } + """); + } + + [Fact] + public async Task BreaksAndBracesAreAlignedInSwitchCasesWithBracesFormatted_Bug2587() + { + await AssertFormatAsync(""" + class C + { + void M() + { + switch (3) + { + case 0: + { + break; + } + } + } + } + """, """ + class C + { + void M() + { + switch (3) + { + case 0: + { + break; + } + } + } + } + """); + } + + [Fact] + public async Task LineBreaksAreNotInsertedForSwitchCasesOnASingleLine1() + { + await AssertFormatAsync(""" + class C + { + void M() + { + switch (3) + { + case 0: break; + default: break; + } + } + } + """, """ + class C + { + void M() + { + switch (3) + { + case 0: break; + default: break; + } + } + } + """); + } + + [Fact] + public async Task LineBreaksAreNotInsertedForSwitchCasesOnASingleLine2() + { + await AssertFormatAsync(""" + class C + { + void M() + { + switch (3) + { + case 0: { break; } + default: { break; } + } + } + } + """, """ + class C + { + void M() + { + switch (3) + { + case 0: { break; } + default: { break; } + } + } + } + """); + } + + [Fact] + public async Task FormatLabelAndGoto1_Bug2588() + { + await AssertFormatAsync(""" + class C + { + void M() + { + Goo: + goto Goo; + } + } + """, """ + class C + { + void M() + { + Goo: + goto Goo; + } + } + """); + } + + [Fact] + public async Task FormatLabelAndGoto2_Bug2588() + { + await AssertFormatAsync(""" + class C + { + void M() + { + int x = 0; + Goo: + goto Goo; + } + } + """, """ + class C + { + void M() + { + int x = 0; + Goo: + goto Goo; + } + } + """); + } + + [Fact] + public async Task FormatNestedLabelAndGoto1_Bug2588() { - switch (i) - { - case 0: - { - } - case 1: - break; - } + await AssertFormatAsync(""" + class C + { + void M() + { + if (true) + { + Goo: + goto Goo; + } + } + } + """, """ + class C + { + void M() + { + if (true) + { + Goo: + goto Goo; + } + } + } + """); } -}", -@"class Class2 -{ - void M() + + [Fact] + public async Task FormatNestedLabelAndGoto2_Bug2588() { - switch (i) { - case 0: { + await AssertFormatAsync(""" + class C + { + void M() + { + if (true) + { + int x = 0; + Goo: + goto Goo; + } + } + } + """, """ + class C + { + void M() + { + if (true) + { + int x = 0; + Goo: + goto Goo; + } + } + } + """); } - case 1: - break; + + [Fact] + public async Task AlreadyFormattedGotoLabelIsNotFormatted1_Bug2588() + { + await AssertFormatAsync(""" + class C + { + void M() + { + Goo: + goto Goo; + } + } + """, """ + class C + { + void M() + { + Goo: + goto Goo; + } } + """); } -}", changedOptionSet: changingOptions); - } - [Fact] - public async Task TestWrappingDefault() - { - await AssertFormatAsync(@"class Class5 -{ - delegate void Del(int x); - public int Age { get { int age = 0; return age; } } - public int Age2 + [Fact] + public async Task AlreadyFormattedGotoLabelIsNotFormatted2_Bug2588() { - get { int age2 = 0; return age2; } - set { int age2 = value; } + await AssertFormatAsync(""" + class C + { + void M() + { + Goo: goto Goo; + } + } + """, """ + class C + { + void M() + { + Goo: goto Goo; + } + } + """); } - void bar() + + [Fact] + public async Task AlreadyFormattedGotoLabelIsNotFormatted3_Bug2588() { - int x = 0; - if (x == 1) x = 2; else x = 3; - do { x = 4; } while (x != 4); - switch (x) { case 1: break; case 2: break; default: break; } - Del d = delegate (int k) { Console.WriteLine(); Console.WriteLine(); }; + await AssertFormatAsync(""" + class C + { + void M() + { + int x = 0; + Goo: + goto Goo; + } + } + """, """ + class C + { + void M() + { + int x = 0; + Goo: + goto Goo; + } + } + """); } -}", @"class Class5 + + [Fact] + public async Task DoNotAddLineBreakBeforeWhere1_Bug2582() { - delegate void Del(int x); - public int Age { get { int age = 0; return age; } } - public int Age2 - { - get { int age2 = 0; return age2; } - set { int age2 = value; } - } - void bar() - { - int x = 0; - if(x == 1) x = 2; else x =3; - do { x = 4; } while (x != 4); - switch (x) { case 1: break; case 2: break; default: break; } - Del d = delegate(int k) { Console.WriteLine(); Console.WriteLine(); }; - } - }"); - } + await AssertFormatAsync(""" + class C + { + void M() where T : I + { + } + } + """, """ + class C + { + void M() where T : I + { + } + } + """); + } - [Fact] - public async Task TestWrappingNonDefault_FormatBlock() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + [Fact] + public async Task DoNotAddLineBreakBeforeWhere2_Bug2582() + { + await AssertFormatAsync(""" + class C where T : I { - { CSharpFormattingOptions2.WrappingPreserveSingleLine, false } - }; - await AssertFormatAsync(@"class Class5 -{ - delegate void Del(int x); - public int Age + } + """, """ + class C where T : I + { + } + """); + } + + [Fact] + public async Task DoNotAddSpaceAfterUnaryMinus() { - get - { - int age = 0; return age; - } + await AssertFormatAsync(""" + class C + { + void M() + { + int x = -1; + } + } + """, """ + class C + { + void M() + { + int x = -1; + } + } + """); } - public int Age2 + + [Fact] + public async Task DoNotAddSpaceAfterUnaryPlus() { - get - { - int age2 = 0; return age2; - } - set - { - int age2 = value; - } + await AssertFormatAsync(""" + class C + { + void M() + { + int x = +1; + } + } + """, """ + class C + { + void M() + { + int x = +1; + } + } + """); } - void bar() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545909")] + public async Task DoNotAddSpaceAfterIncrement() { - int x = 0; - if (x == 1) x = 2; else x = 3; - do { x = 4; } while (x != 4); - switch (x) - { - case 1: break; - case 2: break; - default: break; - } - Del d = delegate (int k) { Console.WriteLine(); Console.WriteLine(); }; + var code = """ + class C + { + void M(int[] i) + { + ++i[0]; + } + } + """; + await AssertFormatAsync(code, code); } - void goo() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545909")] + public async Task DoNotAddSpaceBeforeIncrement() { - int xx = 0; int zz = 0; + var code = """ + class C + { + void M(int[] i) + { + i[0]++; + } + } + """; + await AssertFormatAsync(code, code); } -} -class goo -{ - int x = 0; -}", @"class Class5 -{ - delegate void Del(int x); - public int Age { get { int age = 0; return age; } } - public int Age2 - { - get { int age2 = 0; return age2; } - set { int age2 = value; } - } - void bar() - { - int x = 0; - if(x == 1) x = 2; else x =3; - do { x = 4; } while (x != 4); - switch (x) { case 1: break; case 2: break; default: break; } - Del d = delegate(int k) { Console.WriteLine(); Console.WriteLine(); }; - } - void goo() { int xx = 0; int zz = 0;} -} -class goo{int x = 0;}", changingOptions); - } - [Fact] - public async Task TestWrappingNonDefault_FormatStatmtMethDecl() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545909")] + public async Task DoNotAddSpaceAfterDecrement() + { + var code = """ + class C { - { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } - }; - await AssertFormatAsync(@"class Class5 -{ - delegate void Del(int x); - public int Age { get { int age = 0; return age; } } - public int Age2 - { - get { int age2 = 0; return age2; } - set { int age2 = value; } - } - void bar() - { - int x = 0; - if (x == 1) - x = 2; - else - x = 3; - do - { x = 4; } while (x != 4); - switch (x) - { - case 1: - break; - case 2: - break; - default: - break; - } - Del d = delegate (int k) - { Console.WriteLine(); Console.WriteLine(); }; + void M(int[] i) + { + --i[0]; + } + } + """; + await AssertFormatAsync(code, code); } - void goo() { int y = 0; int z = 0; } -} -class goo -{ - int x = 0; -}", @"class Class5 -{ - delegate void Del(int x); - public int Age { get { int age = 0; return age; } } - public int Age2 - { - get { int age2 = 0; return age2; } - set { int age2 = value; } - } - void bar() - { - int x = 0; - if(x == 1) x = 2; else x =3; - do { x = 4; } while (x != 4); - switch (x) { case 1: break; case 2: break; default: break; } - Del d = delegate(int k) { Console.WriteLine(); Console.WriteLine(); }; - } - void goo(){int y=0; int z =0 ;} -} -class goo -{ - int x = 0; -}", changingOptions); - } - [Fact] - public async Task TestWrappingNonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545909")] + public async Task DoNotAddSpaceBeforeDecrement() + { + var code = """ + class C { - { CSharpFormattingOptions2.WrappingPreserveSingleLine, false }, - { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } - }; - await AssertFormatAsync(@"class Class5 -{ - delegate void Del(int x); - public int Age + void M(int[] i) + { + i[0]--; + } + } + """; + await AssertFormatAsync(code, code); + } + + [Fact] + public async Task Anchoring() { - get - { - int age = 0; - return age; - } + await AssertFormatAsync(""" + class C + { + void M() + { + Console.WriteLine("Goo", + 0, 1, + 2); + } + } + """, """ + class C + { + void M() + { + Console.WriteLine("Goo", + 0, 1, + 2); + } + } + """); } - public int Age2 + + [Fact] + public async Task Exclamation() { - get - { - int age2 = 0; - return age2; - } - set - { - int age2 = value; - } + await AssertFormatAsync(""" + class C + { + void M() + { + if (!true) ; + } + } + """, """ + class C + { + void M() + { + if ( ! true ) ; + } + } + """); } - void bar() + + [Fact] + public async Task StartAndEndTrivia() { - int x = 0; - if (x == 1) - x = 2; - else - x = 3; - do - { - x = 4; - } while (x != 4); - switch (x) - { - case 1: - break; - case 2: - break; - default: - break; - } - Del d = delegate (int k) - { - Console.WriteLine(); - Console.WriteLine(); - }; + await AssertFormatAsync(""" + + + + class C { } + + + + + + """, """ + + + + class C { } + + + + + + """); } -} -class goo -{ - int x = 0; -}", @"class Class5 -{ - delegate void Del(int x); - public int Age { get { int age = 0; return age; } } - public int Age2 - { - get { int age2 = 0; return age2; } - set { int age2 = value; } - } - void bar() - { - int x = 0; - if(x == 1) x = 2; else x =3; - do { x = 4; } while (x != 4); - switch (x) { case 1: break; case 2: break; default: break; } - Del d = delegate(int k) { Console.WriteLine(); Console.WriteLine(); }; - } -} -class goo{int x = 0;}", changingOptions); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991480")] - public async Task TestLeaveStatementMethodDeclarationSameLineNotAffectingForStatement() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } - }; - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) - { - for (int d = 0; d < 10; ++d) - { } - } -}", @"class Program -{ - static void Main(string[] args) - { - for (int d = 0; d < 10; ++d) { } + [Fact] + public async Task FirstTriviaAndAnchoring1() + { + await AssertFormatAsync(""" + + namespace N + { + class C + { + void Method() + { + int i = + 1 + + + 3; + } + } + } + + + + + """, """ + + namespace N { + class C { + void Method() { + int i = + 1 + + + 3; + } + } + } + + + + + """); } -}", changingOptions); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/751789")] - public async Task NewLineForOpenBracesDefault() - { - await AssertFormatAsync(@"class f00 -{ - void br() + [Fact] + public async Task FirstTriviaAndAnchoring2() { - Func ret = x => - { - return x + 1; - }; - var obj = new - { - // ... - }; - if (true) - { - System.Console.WriteLine(""""); - } - else - { - } - timer.Tick += delegate (object sender, EventArgs e) + await AssertFormatAsync(""" + namespace N + { + class C + { + int i = + 1 + + + 3; + } + } -{ - MessageBox.Show(this, ""Timer ticked""); -}; - var obj1 = new goo - { - }; - async void LocalFunction() - { - } - try - { - } - catch (Exception e) - { - } - finally - { } + """, """ + + namespace N { + class C { + int i = + 1 + + + 3; + } + } - using (someVar) - { - } + - switch (switchVar) - { - default: - break; - } + + """); } -} -namespace NS1 -{ - public class goo : System.Object + [Fact] + public async Task FirstTriviaAndAnchoring3() + { + await AssertFormatAsync(""" + class C + { + int i = + 1 + + + 3; + } - { - public int f { get; set; } - } -}", @"class f00 -{ - void br() { -Func ret = x => - { - return x + 1; - }; -var obj = new - { - // ... - }; -if(true) -{ - System.Console.WriteLine(""""); - } -else -{ -} - timer.Tick += delegate (object sender, EventArgs e) -{ - MessageBox.Show(this, ""Timer ticked""); - }; -var obj1 = new goo + """, """ + + + class C { + int i = + 1 + + + 3; + } + + + + + """); + } + + [Fact] + public async Task Base1() + { + await AssertFormatAsync(""" + class C { - }; + C() : base() + { + } + } + """, """ + class C + { + C ( ) : base ( ) + { + } + } + """); + } - async void LocalFunction() { - } + [Fact] + public async Task This1() + { + await AssertFormatAsync(""" + class C + { + C(int i) : this() + { + } - try - { - } - catch (Exception e) - { - } - finally - {} + C() { } + } + """, """ + class C + { + C ( int i ) : this ( ) + { + } - using (someVar) - { - } + C ( ) { } + } + """); + } - switch (switchVar) - { - default: - break; - } -} -} + [Fact] + public async Task QueryExpression1() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + var q = + from c in from b in cs select b select c; + } + } + """, """ + class C + { + int Method() + { + var q = + from c in from b in cs select b select c; + } + } + """); + } + + [Fact] + public async Task QueryExpression2() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + var q = from c in + from b in cs + select b + select c; + } + } + """, """ + class C + { + int Method() + { + var q = from c in + from b in cs + select b + select c; + } + } + """); + } + + [Fact] + public async Task QueryExpression3() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + var q = from c in Get(1 + + 2 + + 3) + from b in Get(1 + + 2 + + 3) + select new { b, c }; + } + } + """, """ + class C + { + int Method() + { + var q = from c in Get(1 + + 2 + + 3) + from b in Get(1 + + 2 + + 3) + select new { b, c }; + } + } + """); + } -namespace NS1 { -public class goo : System.Object + [Fact] + public async Task QueryExpression4() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + var q = + from c in + from b in cs + select b + select c; + } + } + """, """ + class C + { + int Method() + { + var q = + from c in + from b in cs + select b + select c; + } + } + """); + } + [Fact] + public async Task Label1() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + L: int i = 10; + } + } + """, """ + class C + { + int Method() + { + L : int i = 10 ; + } + } + """); + } + [Fact] + public async Task Label2() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + int x = 1; + L: int i = 10; + } + } + """, """ + class C + { + int Method() + { + int x = 1 ; + L : int i = 10 ; + } + } + """); + } -{ - public int f { get; set; } -} -}"); - } + [Fact] + public async Task Label3() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + int x = 1; + L: + int i = 10; + } + } + """, """ + class C + { + int Method() + { + int x = 1 ; + L : + int i = 10 ; + } + } + """); + } - [Fact, WorkItem("https://developercommunity.visualstudio.com/content/problem/8808/c-structure-guide-lines-for-unsafe-fixed.html")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/751789")] - public async Task NewLineForOpenBracesNonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + [Fact] + public async Task Label4() + { + await AssertFormatAsync(""" + class C { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBracePlacement.None } - }; - await AssertFormatAsync(@"class f00 { - void br() { - Func ret = x => { - return x + 1; - }; - var obj = new { - // ... - }; - if (true) { - System.Console.WriteLine(""""); - } - else { - } - timer.Tick += delegate (object sender, EventArgs e) { - MessageBox.Show(this, ""Timer ticked""); - }; + int Method() + { + int x = 1; + L: int i = 10; + int next = 30; + } + } + """, """ + class C + { + int Method() + { + int x = 1 ; + L : int i = 10 ; + int next = 30; + } + } + """); + } - var obj1 = new goo { - }; + [Fact] + public async Task Label5() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + L: int i = 10; + int next = 30; + } + } + """, """ + class C + { + int Method() + { + L : int i = 10 ; + int next = 30; + } + } + """); + } - async void LocalFunction() { - } + [Fact] + public async Task Label6() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + L: + int i = 10; + int next = 30; + } + } + """, """ + class C + { + int Method() + { + L : + int i = 10 ; + int next = 30; + } + } + """); + } - try { - } - catch (Exception e) { - } - finally { } + [Fact] + public async Task Label7() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + int i2 = 1; + L: + int i = 10; + int next = 30; + } + } + """, """ + class C + { + int Method() + { + int i2 = 1 ; + L : + int i = 10 ; + int next = 30; + } + } + """); + } - using (someVar) { - } + [Fact] + public async Task Label8() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + L: + int i = + 10; + } + } + """, """ + class C + { + int Method() + { + L: + int i = + 10; + } + } + """); + } - switch (switchVar) { - default: - break; - } + [Fact] + public async Task AutoProperty() + { + await AssertFormatAsync(""" + class Class + { + private int Age { get; set; } + public string Names { get; set; } + } + """, """ + class Class + { + private int Age{get; set; } + public string Names { get; set;} + } + """); + } - unsafe { - } + [Fact] + public async Task NormalPropertyGet() + { + await AssertFormatAsync(""" + class Class + { + private string name; + public string Names + { + get + { + return name; + } + } + } + """, """ + class Class + { + private string name; + public string Names + { + get + { + return name; + } + } + } + """); + } - fixed (int* p = &i) { - } + [Fact] + public async Task NormalPropertyBoth() + { + await AssertFormatAsync(""" + class Class + { + private string name; + public string Names + { + get + { + return name; + } + set + { + name = value; + } + } + } + """, """ + class Class + { + private string name; + public string Names + { + get + { + return name; + } + set + { + name = value; + } + } + } + """); } -} -namespace NS1 { - public class goo : System.Object { + [Fact] + public async Task ErrorHandling1() + { + await AssertFormatAsync(""" + class C + { + int Method() + { + int a b c; + } + } + """, """ + class C + { + int Method() + { + int a b c ; + } + } + """); } -}", @"class f00 -{ - void br() { -Func ret = x => -{ - return x + 1; - }; -var obj = new - { - // ... - }; -if(true) -{ - System.Console.WriteLine(""""); - } -else -{ -} - timer.Tick += delegate (object sender, EventArgs e) - - -{ - MessageBox.Show(this, ""Timer ticked""); - }; -var obj1 = new goo + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537763")] + public async Task NullableType() + { + await AssertFormatAsync(""" + class Program { - }; - - async void LocalFunction() + static void Main(string[] args) + { + int? i = 10; + } + } + """, """ + class Program { + static void Main(string[] args) + { + int ? i = 10; + } + } + """); } - try - { - } - catch (Exception e) - { - } - finally - {} - - using (someVar) - { - } - - switch (switchVar) - { - default: - break; - } - - unsafe -{ - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537766")] + public async Task SuppressWrappingOnBraces() + { + await AssertFormatAsync(""" + class Class1 + { } - fixed (int* p = &i) -{ - } -} -} + """, """ + class Class1 + {} -namespace NS1 { -public class goo : System.Object + """); + } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537824")] + public async Task DoWhile() + { + await AssertFormatAsync(""" + public class Class1 + { + void Goo() + { + do + { + } while (true); + } + } + """, """ + public class Class1 + { + void Goo() + { + do + { + }while (true); + } + } -{ -} -}", changingOptions); - } + """); + } - [Fact] - public async Task NewLineForKeywordDefault() - { - await AssertFormatAsync(@"class c -{ - void f00() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537774")] + public async Task SuppressWrappingBug() { + await AssertFormatAsync(""" + class Class1 + { + int Goo() + { + return 0; + } + } - try - { - // ... - } - catch (Exception e) - { - // ... - } - finally - { - // ... - } + """, """ + class Class1 + { + int Goo() + {return 0; + } + } - if (a > b) - { - return 3; - } - else - { - return 0; - } + """); } -}", - @"class c -{ -void f00(){ - -try -{ - // ... -} catch (Exception e) -{ - // ... -} finally -{ - // ... -} -if (a > b) -{ - return 3; -} else -{ - return 0; -} -} -}"); - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537768")] + public async Task PreserveLineForAttribute() + { + await AssertFormatAsync(""" + class Class1 + { + [STAThread] + static void Main(string[] args) + { + } + } - [Fact] - public async Task NewLineForKeywordNonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + """, """ + class Class1 { - { CSharpFormattingOptions2.NewLineForElse, false }, - { CSharpFormattingOptions2.NewLineForCatch, false }, - { CSharpFormattingOptions2.NewLineForFinally, false } - }; - await AssertFormatAsync(@"class c -{ - void f00() - { + [STAThread] + static void Main(string[] args) + { + } + } - try - { - // ... - } catch (Exception e) - { - // ... - } finally - { - // ... - } - if (a > b) - { - return 3; - } else - { - return 0; - } + """); } -}", @"class c -{ -void f00(){ -try -{ - // ... -} + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537878")] + public async Task NoFormattingOnMissingTokens() + { + await AssertFormatAsync(""" + namespace ClassLibrary1 + { + class Class1 + { + void Goo() + { + if (true) + } + } + } + """, """ + namespace ClassLibrary1 + { + class Class1 + { + void Goo() + { + if (true) + } + } + } -catch (Exception e) -{ - // ... -} + """); + } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537783")] + public async Task UnaryExpression() + { + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + int a = 6; + a = a++ + 5; + } + } - finally -{ - // ... -} -if (a > b) -{ - return 3; -} + """, """ + class Program + { + static void Main(string[] args) + { + int a = 6; + a = a++ + 5; + } + } -else -{ - return 0; -} -} -}", changingOptions); - } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33458")] - public async Task NoNewLineForElseChecksBraceOwner() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537885")] + public async Task Pointer() + { + await AssertFormatAsync(""" + class Program { - { NewLineForElse, false }, - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, false) } - }; + static void Main(string[] args) + { + int* p; + } + } - await AssertFormatAsync(@"class Class -{ - void Method() - { - if (true) - for (int i = 0; i < 10; i++) { - Method(); + """, """ + class Program + { + static void Main(string[] args) + { + int* p; + } } - else - return; + + """); } -}", @"class Class -{ - void Method() + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50723")] + public async Task TuplePointer() { - if (true) - for (int i = 0; i < 10; i++) { - Method(); - } else - return; + var properlyFormattedCode = """ + public unsafe static class Program + { + public static void Main(string[] args) + { + int* intPointer = null; + (int, int)* intIntPointer = null; + } + } + + """; + await AssertFormatAsync(properlyFormattedCode, properlyFormattedCode); } -}", changedOptionSet: changingOptions); - } - [Fact] - public async Task NewLineForExpressionDefault() - { - await AssertFormatAsync(@"class f00 -{ - void br() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537886")] + public async Task Tild() { - var queryLowNums = from num in numbers - where num < 5 - select num; - - var queryLowNums = + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + int j = 103; + j = ~7; + } + } - from num in numbers - where num < 5 - select num; + """, """ + class Program + { + static void Main(string[] args) + { + int j = 103; + j = ~7; + } + } - var q = from c in cust - from o in c.Orders - orderby o.Total descending - select new { c.Name, c.OrderID }; - var obj = new - { - X1 = 0, - Y1 = 1, - X2 = 2, - Y2 = 3 - }; - var obj1 = new { X1 = 0, Y1 = 1, X2 = 2, Y2 = 3 }; - MyObject obj = new MyObject - { - X1 = 0, - Y1 = 1, - X2 = 2, - Y2 = 3 - }; - MyObject obj = new MyObject { X1 = 0, Y1 = 1, X2 = 2, Y2 = 3 }; + """); } -}", @"class f00 -{ - void br() - { -var queryLowNums = from num in numbers where num < 5 - select num; - -var queryLowNums = - - from num in numbers where num < 5 - select num; - - var q = from c in cust -from o in c.Orders orderby o.Total descending - select new { c.Name, c.OrderID }; -var obj = new { X1 = 0, Y1 = 1, - X2 = 2, - Y2 = 3 - }; -var obj1 = new { X1 = 0, Y1 = 1, X2 = 2, Y2 = 3 }; - MyObject obj = new MyObject { X1 = 0, Y1 = 1, - X2 = 2, - Y2 = 3 - }; -MyObject obj = new MyObject { X1 = 0, Y1 = 1, X2 = 2, Y2 = 3 }; - } -}"); - } - [Fact] - public async Task NewLineForExpressionNonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineForMembersInObjectInit, false }, - { CSharpFormattingOptions2.NewLineForMembersInAnonymousTypes, false }, - { CSharpFormattingOptions2.NewLineForClausesInQuery, false } - }; - await AssertFormatAsync(@"class f00 -{ - void br() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537884")] + public async Task ArrayInitializer1() { + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + int[] arr = {1,2, + 3,4 + }; + } + } - var queryLowNums = from num in numbers where num < 5 - select num; - - var queryLowNums = - - from num in numbers where num < 5 - select num; + """, """ + class Program + { + static void Main(string[] args) + { + int[] arr = {1,2, + 3,4 + }; + } + } - var q = from c in cust - from o in c.Orders orderby o.Total descending - select new { c.Name, c.OrderID }; - var obj = new - { - X1 = 0, Y1 = 1, - X2 = 2, - Y2 = 3 - }; - MyObject obj = new MyObject - { - X1 = 0, Y1 = 1, - X2 = 2, - Y2 = 3 - }; + """); } -}", @"class f00 -{ - void br() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537884")] + public async Task ArrayInitializer2() { + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + int[] arr = new int[] {1,2, + 3,4 + }; + } + } + + """, """ + class Program + { + static void Main(string[] args) + { + int[] arr = new int [] {1,2, + 3,4 + }; + } + } -var queryLowNums = from num in numbers where num < 5 - select num; + """); + } -var queryLowNums = + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537884")] + public async Task ImplicitArrayInitializer() + { + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + var arr = new[] {1,2, + 3,4 + }; + } + } - from num in numbers where num < 5 - select num; + """, """ + class Program + { + static void Main(string[] args) + { + var arr = new [] {1,2, + 3,4 + } ; + } + } - var q = from c in cust -from o in c.Orders orderby o.Total descending - select new { c.Name, c.OrderID }; -var obj = new { X1 = 0, Y1 = 1, - X2 = 2, - Y2 = 3 - }; - MyObject obj = new MyObject { X1 = 0, Y1 = 1, - X2 = 2, - Y2 = 3 - }; + """); } -}", changingOptions); - } - [Fact] - public async Task Enums_Bug2586() - { - await AssertFormatAsync(@"enum E -{ - a = 10, - b, - c -}", @"enum E -{ - a = 10, - b, - c -}"); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] + public async Task StackAllocArrayInitializer0() + { + await AssertFormatAsync(""" + F(stackalloc int[] + { + 1, + 2, + }); + """, """ + F(stackalloc int[] + { + 1, + 2, + } ); + """); + } - [Fact] - public async Task DoNotInsertLineBreaksInSingleLineEnum() - => await AssertFormatAsync(@"enum E { a = 10, b, c }", @"enum E { a = 10, b, c }"); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] + public async Task StackAllocArrayInitializer0_Implicit() + { + await AssertFormatAsync(""" + F(stackalloc[] + { + 1, + 2, + } + ); + """, """ + F( stackalloc [] + { + 1, + 2, + } + ); + """); + } - [Fact] - public async Task AlreadyFormattedSwitchIsNotFormatted_Bug2588() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] + public async Task StackAllocArrayInitializer1() { - switch (3) - { - case 0: - break; - } + await AssertFormatAsync(""" + F( + stackalloc int[] + { + 1,2, + 3,4 + } + ); + """, """ + F( + stackalloc int[] + { + 1,2, + 3,4 + } + ); + """); } -}", @"class C -{ - void M() + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] + public async Task StackAllocArrayInitializer1_Implicit() { - switch (3) - { - case 0: - break; - } + await AssertFormatAsync(""" + F( + stackalloc[] + { + 1,2, + 3,4 + } + ); + """, """ + F( + stackalloc [] + { + 1,2, + 3,4 + } + ); + """); } -}"); - } - [Fact] - public async Task BreaksAreAlignedInSwitchCasesFormatted_Bug2587() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] + public async Task StackAllocArrayInitializer2() { - switch (3) - { - case 0: - break; - } + await AssertFormatAsync(""" + var x = (stackalloc int[] {1,2, + 3 + }); + """, """ + var x = (stackalloc int[] {1,2, + 3 + }); + """); } -}", @"class C -{ - void M() + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] + public async Task StackAllocArrayInitializer2_Implicit() { - switch (3) - { - case 0: - break; - } + await AssertFormatAsync(""" + var x = (stackalloc[] + {1, + 2, 3 + }); + """, """ + var x = (stackalloc [] + {1, + 2, 3 + }); + """); } -}"); - } - [Fact] - public async Task BreaksAndBracesAreAlignedInSwitchCasesWithBracesFormatted_Bug2587() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537884")] + public async Task CollectionInitializer() { - switch (3) - { - case 0: + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) { - break; + var arr = new List {1,2, + 3,4 + }; } - } - } -}", @"class C -{ - void M() - { - switch (3) - { - case 0: + } + + """, """ + class Program { - break; + static void Main(string[] args) + { + var arr = new List {1,2, + 3,4 + }; } - } + } + + """); } -}"); - } - [Fact] - public async Task LineBreaksAreNotInsertedForSwitchCasesOnASingleLine1() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537916")] + public async Task AddressOfOperator() { - switch (3) - { - case 0: break; - default: break; - } + await AssertFormatAsync(""" + unsafe class Class1 + { + void Method() + { + int a = 12; + int* p = &a; + } + } + + """, """ + unsafe class Class1 + { + void Method() + { + int a = 12; + int* p = &a; + } + } + + """); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537885")] + public async Task DereferenceOperator() { - switch (3) - { - case 0: break; - default: break; - } + await AssertFormatAsync(""" + unsafe class Class1 + { + void Method() + { + int a = 12; + int* p = &a; + Console.WriteLine(*p); + } + } + + """, """ + unsafe class Class1 + { + void Method() + { + int a = 12; + int* p = & a; + Console.WriteLine(* p); + } + } + + """); } -}"); - } - [Fact] - public async Task LineBreaksAreNotInsertedForSwitchCasesOnASingleLine2() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537905")] + public async Task Namespaces() { - switch (3) - { - case 0: { break; } - default: { break; } - } + await AssertFormatAsync(""" + using System; + using System.Data; + """, @"using System; using System.Data;"); } -}", @"class C -{ - void M() + + [Fact] + public async Task NamespaceDeclaration() { - switch (3) - { - case 0: { break; } - default: { break; } - } + await AssertFormatAsync(""" + namespace N + { + } + """, """ + namespace N + { + } + """); } -}"); - } - [Fact] - public async Task FormatLabelAndGoto1_Bug2588() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537902")] + public async Task DoWhile1() { - Goo: - goto Goo; + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + do { } + while (i < 4); + } + } + """, """ + class Program + { + static void Main(string[] args) + { + do { } + while (i < 4); + } + } + """); } -}", @"class C -{ - void M() + + [Fact] + public async Task NewConstraint() { -Goo: -goto Goo; + await AssertFormatAsync(""" + class Program + { + void Test(T t) where T : new() + { + } + } + """, """ + class Program + { + void Test(T t) where T : new ( ) + { + } + } + """); } -}"); - } - [Fact] - public async Task FormatLabelAndGoto2_Bug2588() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact] + public async Task UnaryExpressionWithInitializer() { - int x = 0; - Goo: - goto Goo; + await AssertFormatAsync(""" + using System; + using System.Collections.Generic; + using System.Linq; + + class Program + { + static void Main(string[] args) + { + if ((new int[] { 1, 2, 3 }).Any()) + { + return; + } + } + } + """, """ + using System; + using System.Collections.Generic; + using System.Linq; + + class Program + { + static void Main(string[] args) + { + if ((new int[] { 1, 2, 3 } ).Any()) + { + return; + } + } + } + """); } -}", @"class C -{ - void M() + + [Fact] + public async Task Attributes1() { -int x = 0; -Goo: -goto Goo; + await AssertFormatAsync(""" + class Program + { + [Flags] public void Method() { } + } + """, """ + class Program + { + [ Flags ] public void Method ( ) { } + } + """); } -}"); - } - [Fact] - public async Task FormatNestedLabelAndGoto1_Bug2588() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact] + public async Task Attributes2() { - if (true) - { - Goo: - goto Goo; - } + await AssertFormatAsync(""" + class Program + { + [Flags] + public void Method() { } + } + """, """ + class Program + { + [ Flags ] + public void Method ( ) { } + } + """); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538288")] + public async Task ColonColon1() { -if (true) -{ -Goo: -goto Goo; -} + await AssertFormatAsync(""" + class Program + { + public void Method() + { + throw new global::System.NotImplementedException(); + } + } + """, """ + class Program + { + public void Method ( ) { + throw new global :: System.NotImplementedException(); + } + } + """); } -}"); - } - [Fact] - public async Task FormatNestedLabelAndGoto2_Bug2588() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538354")] + public async Task BugFix3939() { - if (true) - { - int x = 0; - Goo: - goto Goo; - } + await AssertFormatAsync(""" + using + System. + Collections. + Generic; + """, """ + using + System. + Collections. + Generic; + """); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538354")] + public async Task Tab1() + => await AssertFormatAsync(@"using System;", @" using System;"); + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538329")] + public async Task SuppressLinkBreakInIfElseStatement() { -if (true) -{ -int x = 0; -Goo: -goto Goo; -} + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + int a; + if (true) a = 10; + else a = 11; + } + } + """, """ + class Program + { + static void Main(string[] args) + { + int a; + if (true) a = 10; + else a = 11; + } + } + """); } -}"); - } - [Fact] - public async Task AlreadyFormattedGotoLabelIsNotFormatted1_Bug2588() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538464")] + public async Task BugFix4087() { - Goo: - goto Goo; + await AssertFormatAsync(""" + class Program + { + static void Main(string[] args) + { + Func fun = x => { return x + 1; } + } + } + """, """ + class Program + { + static void Main(string[] args) + { + Func fun = x => { return x + 1; } + } + } + """); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538511")] + public async Task AttributeTargetSpecifier() { - Goo: - goto Goo; + var code = """ + public class Class1 + { + [method : + void Test() + { + } + } + """; + + var expected = """ + public class Class1 + { + [method: + void Test() + { + } + } + """; + + await AssertFormatAsync(expected, code); } -}"); - } - [Fact] - public async Task AlreadyFormattedGotoLabelIsNotFormatted2_Bug2588() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538635")] + public async Task Finalizer() { - Goo: goto Goo; + var code = """ + public class Class1 + { + ~ Class1() { } + } + """; + + var expected = """ + public class Class1 + { + ~Class1() { } + } + """; + + await AssertFormatAsync(expected, code); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538743")] + public async Task BugFix4442() { - Goo: goto Goo; + var code = """ + class Program + { + static void Main(string[] args) + { + string str = "ab,die|wo"; + string[] a = str.Split(new char[] { ',', '|' }) + ; + } + } + """; + + await AssertFormatAsync(code, code); } -}"); - } - [Fact] - public async Task AlreadyFormattedGotoLabelIsNotFormatted3_Bug2588() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538658")] + public async Task BugFix4328() { - int x = 0; - Goo: - goto Goo; + var code = """ + class Program + { + static void Main(string[] args) + { + double d = new double (); + } + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + { + double d = new double(); + } + } + """; + await AssertFormatAsync(expected, code); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538658")] + public async Task BugFix4515() { - int x = 0; - Goo: - goto Goo; + var code = """ + class Program + { + static void Main(string[] args) + { + var t = typeof ( System.Object ) ; + var t1 = default ( System.Object ) ; + var t2 = sizeof ( System.Object ) ; + } + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + { + var t = typeof(System.Object); + var t1 = default(System.Object); + var t2 = sizeof(System.Object); + } + } + """; + await AssertFormatAsync(expected, code); } -}"); - } - [Fact] - public async Task DoNotAddLineBreakBeforeWhere1_Bug2582() - { - await AssertFormatAsync(@"class C -{ - void M() where T : I + [Fact] + public async Task CastExpressionTest() { + var code = """ + class Program + { + static void Main(string[] args) + { + var a = (int) 1; + } + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + { + var a = (int)1; + } + } + """; + await AssertFormatAsync(expected, code); } -}", @"class C -{ - void M() where T : I + + [Fact] + public async Task NamedParameter() { + var code = """ + class Program + { + static void Main(string[] args) + { + Main ( args : null ) ; + } + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + { + Main(args: null); + } + } + """; + await AssertFormatAsync(expected, code); } -}"); - } - - [Fact] - public async Task DoNotAddLineBreakBeforeWhere2_Bug2582() - { - await AssertFormatAsync(@"class C where T : I -{ -}", @"class C where T : I -{ -}"); - } - [Fact] - public async Task DoNotAddSpaceAfterUnaryMinus() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact] + public async Task RefReadonlyParameters() { - int x = -1; + var code = """ + class C + { + int this [ ref readonly int x , ref readonly int y ] { get ; set ; } + void M ( ref readonly int x , ref readonly int y ) { } + } + """; + var expected = """ + class C + { + int this[ref readonly int x, ref readonly int y] { get; set; } + void M(ref readonly int x, ref readonly int y) { } + } + """; + await AssertFormatAsync(expected, code); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539259")] + public async Task BugFix5143() { - int x = -1; + var code = """ + class Program + { + static void Main(string[] args) + { + int x = Goo ( + delegate ( int x ) { return x ; } ) ; + } + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + { + int x = Goo( + delegate (int x) { return x; }); + } + } + """; + await AssertFormatAsync(expected, code); } -}"); - } - [Fact] - public async Task DoNotAddSpaceAfterUnaryPlus() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539338")] + public async Task BugFix5251() { - int x = +1; + var code = """ + class Program + { + public static string Goo { get; private set; } + } + """; + var expected = """ + class Program + { + public static string Goo { get; private set; } + } + """; + await AssertFormatAsync(expected, code); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539358")] + public async Task BugFix5277() { - int x = +1; + var code = """ + + #if true + #endif + + """; + var expected = """ + + #if true + #endif + + """; + await AssertFormatAsync(expected, code); } -}"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545909")] - public async Task DoNotAddSpaceAfterIncrement() - { - var code = @"class C -{ - void M(int[] i) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539542")] + public async Task BugFix5544() { - ++i[0]; + var code = """ + + class Program + { + unsafe static void Main(string[] args) + { + Program* p; + p -> Goo = 5; + } + } + + """; + var expected = """ + + class Program + { + unsafe static void Main(string[] args) + { + Program* p; + p->Goo = 5; + } + } + + """; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(code, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545909")] - public async Task DoNotAddSpaceBeforeIncrement() - { - var code = @"class C -{ - void M(int[] i) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539587")] + public async Task BugFix5602() { - i[0]++; + var code = """ + class Bug + { + public static void func() + { + long b = // + } + } + """; + var expected = """ + class Bug + { + public static void func() + { + long b = // + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(code, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545909")] - public async Task DoNotAddSpaceAfterDecrement() - { - var code = @"class C -{ - void M(int[] i) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539616")] + public async Task BugFix5637() { - --i[0]; + var code = """ + class Bug + { + // test + public static void func() + { + } + } + """; + var expected = """ + class Bug + { + // test + public static void func() + { + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(code, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545909")] - public async Task DoNotAddSpaceBeforeDecrement() - { - var code = @"class C -{ - void M(int[] i) + [Fact] + public async Task GenericType() { - i[0]--; + var code = """ + class Bug + { + class N : Bug< T [ ] > + { + } + } + """; + var expected = """ + class Bug + { + class N : Bug + { + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(code, code); - } - [Fact] - public async Task Anchoring() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539878")] + public async Task BugFix5978() { - Console.WriteLine(""Goo"", - 0, 1, - 2); + var code = """ + class Program + { + static void Main(string[] args) + { + int i = 3; + label4: + if (i < 5) + { + label5: + if (i == 4) + { + } + else + { + System.Console.WriteLine("a"); + } + } + } + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + { + int i = 3; + label4: + if (i < 5) + { + label5: + if (i == 4) + { + } + else + { + System.Console.WriteLine("a"); + } + } + } + } + """; + await AssertFormatAsync(expected, code); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539878")] + public async Task BugFix5979() { - Console.WriteLine(""Goo"", - 0, 1, - 2); + var code = """ + delegate int del(int i); + class Program + { + static void Main(string[] args) + { + del q = x => + { + label2: goto label1; + label1: return x; + }; + } + } + """; + var expected = """ + delegate int del(int i); + class Program + { + static void Main(string[] args) + { + del q = x => + { + label2: goto label1; + label1: return x; + }; + } + } + """; + await AssertFormatAsync(expected, code); } -}"); - } - [Fact] - public async Task Exclamation() - { - await AssertFormatAsync(@"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539891")] + public async Task BugFix5993() { - if (!true) ; + var code = """ + public class MyClass + { + public static void Main() + { + lab1: + { + lab1:// CS0158 + goto lab1; + } + } + } + """; + var expected = """ + public class MyClass + { + public static void Main() + { + lab1: + { + lab1:// CS0158 + goto lab1; + } + } + } + """; + await AssertFormatAsync(expected, code); } -}", @"class C -{ - void M() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540315")] + public async Task BugFix6536() { - if ( ! true ) ; + var code = """ + public class MyClass + { + public static void Main() + { + int i = - - 1 + + + 1 + - + 1 + - + 1 ; + } + } + """; + var expected = """ + public class MyClass + { + public static void Main() + { + int i = - -1 + + +1 + -+1 + -+1; + } + } + """; + await AssertFormatAsync(expected, code); } -}"); - } - - [Fact] - public async Task StartAndEndTrivia() - { - await AssertFormatAsync(@" - - -class C { } - - + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540801")] + public async Task BugFix7211() + { + var code = """ + class Program + { + static void Main(string[] args) + { + while (0 > new int[] { 1 }.Length) + { + System.Console.WriteLine("Hello"); + } + } + } + """; -", @" - - -class C { } - - - - -"); - } + var expected = """ + class Program + { + static void Main(string[] args) + { + while (0 > new int[] { 1 }.Length) + { + System.Console.WriteLine("Hello"); + } + } + } + """; + await AssertFormatAsync(expected, code); + } - [Fact] - public async Task FirstTriviaAndAnchoring1() - { - await AssertFormatAsync(@" -namespace N -{ - class C + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541035")] + public async Task BugFix7564_1() { - void Method() - { - int i = - 1 - + - 3; - } + var code = """ + class Program + { + static void Main(string[] args) + { + while (null != new int[] { 1 }) + { + System.Console.WriteLine("Hello"); + } + } + } + """; + + var expected = """ + class Program + { + static void Main(string[] args) + { + while (null != new int[] { 1 }) + { + System.Console.WriteLine("Hello"); + } + } + } + """; + await AssertFormatAsync(expected, code); } -} + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541035")] + public async Task BugFix7564_2() + { + var code = """ + class Program + { + static void Main(string[] args) + { + foreach (var f in new int[] { 5 }) + { + Console.WriteLine(f); + } + } + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + { + foreach (var f in new int[] { 5 }) + { + Console.WriteLine(f); + } + } + } + """; + await AssertFormatAsync(expected, code); + } -", @" -namespace N { - class C { - void Method() { - int i = - 1 - + - 3; - } -} -} + [Fact, WorkItem(8385, "DevDiv_Projects/Roslyn")] + public async Task NullCoalescingOperator() + { + var code = """ + class C + { + void M() + { + object o2 = null??null; + } + } + """; + var expected = """ + class C + { + void M() + { + object o2 = null ?? null; + } + } + """; + await AssertFormatAsync(expected, code); + } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541925")] + public async Task QueryContinuation() + { + var code = """ + using System.Linq; + class C + { + static void Main(string[] args) + { + var temp = from x in "abc" + let z = x.ToString() + select z into w + select w; + } + } + """; -"); - } + var expected = """ + using System.Linq; + class C + { + static void Main(string[] args) + { + var temp = from x in "abc" + let z = x.ToString() + select z into w + select w; + } + } + """; + await AssertFormatAsync(expected, code); + } - [Fact] - public async Task FirstTriviaAndAnchoring2() - { - await AssertFormatAsync(@" -namespace N -{ - class C + [Fact] + public async Task QueryContinuation2() { - int i = - 1 - + - 3; + var code = """ + using System.Linq; + class C + { + static void Main(string[] args) + { + var temp = from x in "abc" select x into + } + } + """; + + var expected = """ + using System.Linq; + class C + { + static void Main(string[] args) + { + var temp = from x in "abc" + select x into + } + } + """; + await AssertFormatAsync(expected, code); } -} + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542305")] + public async Task AttributeFormatting1() + { + var code = """ + class Program + { + void AddClass(string name,[OptionalAttribute] object position,[OptionalAttribute] object bases) + { + } + } + """; + var expected = """ + class Program + { + void AddClass(string name, [OptionalAttribute] object position, [OptionalAttribute] object bases) + { + } + } + """; + await AssertFormatAsync(expected, code); + } -", @" -namespace N { - class C { - int i = - 1 - + - 3; -} -} + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542304")] + public async Task CloseBracesInArgumentList() + { + var code = """ + class Program + { + static void Main(string[] args) + { + var relativeIndentationGetter = new Lazy(() => + { + var indentationDelta = operation.IndentationDeltaOrPosition * this.OptionSet.IndentationSize; + var baseIndentation = this.tokenStream.GetCurrentColumn(operation.BaseToken); - + return baseIndentation + indentationDelta; + } , isThreadSafe: true); + } + } + """; -"); - } + var expected = """ + class Program + { + static void Main(string[] args) + { + var relativeIndentationGetter = new Lazy(() => + { + var indentationDelta = operation.IndentationDeltaOrPosition * this.OptionSet.IndentationSize; + var baseIndentation = this.tokenStream.GetCurrentColumn(operation.BaseToken); - [Fact] - public async Task FirstTriviaAndAnchoring3() - { - await AssertFormatAsync(@" + return baseIndentation + indentationDelta; + }, isThreadSafe: true); + } + } + """; + await AssertFormatAsync(expected, code); + } -class C -{ - int i = - 1 - + - 3; -} + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542538")] + public async Task MissingTokens() + { + var code = """ + using System; + delegate void myDelegate(int name = 1); + class innerClass + { + public innerClass() + { + myDelegate x = (int y=1) => { return; }; + } + } + """; + var expected = """ + using System; + delegate void myDelegate(int name = 1); + class innerClass + { + public innerClass() + { + myDelegate x = (int y = 1) => { return; }; + } + } + """; + await AssertFormatAsync(expected, code); + } -", @" - - class C { - int i = - 1 - + - 3; -} - + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542199")] + public async Task ColumnOfVeryFirstToken() + { + var code = @" W )b"; + var expected = @"W )b"; -"); - } + await AssertFormatAsync(expected, code); + } - [Fact] - public async Task Base1() - { - await AssertFormatAsync(@"class C -{ - C() : base() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542718")] + public async Task EmptySuppressionSpan() { - } -}", @" class C - { - C ( ) : base ( ) + var code = """ + enum E + { + a,, + } + """; + + var expected = """ + enum E { + a,, } - } "); - } + """; - [Fact] - public async Task This1() - { - await AssertFormatAsync(@"class C -{ - C(int i) : this() - { + await AssertFormatAsync(expected, code); } - C() { } -}", @" class C + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542790")] + public async Task LabelInSwitch() + { + var code = """ + class test { - C ( int i ) : this ( ) + public static void Main() + { + string target = "t1"; + switch (target) + { + case "t1": + label1: + goto label1; + case "t2": + label2: + goto label2; + } + } + } + """; + + var expected = """ + class test { + public static void Main() + { + string target = "t1"; + switch (target) + { + case "t1": + label1: + goto label1; + case "t2": + label2: + goto label2; + } + } } + """; - C ( ) { } - } "); - } + await AssertFormatAsync(expected, code); + } - [Fact] - public async Task QueryExpression1() - { - await AssertFormatAsync(@"class C -{ - int Method() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543112")] + public void FormatArbitaryNode() { - var q = - from c in from b in cs select b select c; - } -}", @" class C + var expected = """ + public int Prop { - int Method() - { - var q = - from c in from b in cs select b select c; - } - } "); - } + get + { + return c; + } - [Fact] - public async Task QueryExpression2() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - var q = from c in - from b in cs - select b - select c; - } -}", @" class C + set + { + c = value; + } + } + """; + + var property = SyntaxFactory.PropertyDeclaration( + attributeLists: [], + [PublicKeyword], + SyntaxFactory.ParseTypeName("int"), + null, + SyntaxFactory.Identifier("Prop"), + SyntaxFactory.AccessorList([ + SyntaxFactory.AccessorDeclaration( + SyntaxKind.GetAccessorDeclaration, + SyntaxFactory.Block(SyntaxFactory.ParseStatement("return c;"))), + SyntaxFactory.AccessorDeclaration( + SyntaxKind.SetAccessorDeclaration, + SyntaxFactory.Block(SyntaxFactory.ParseStatement("c = value;")))])); + + Assert.NotNull(property); + using var workspace = new AdhocWorkspace(); + var newProperty = Formatter.Format(property, workspace.Services.SolutionServices, CSharpSyntaxFormattingOptions.Default, CancellationToken.None); + + Assert.Equal(expected, newProperty.ToFullString()); + } + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543140")] + public async Task OmittedTypeArgument() + { + var code = """ + using System; + using System.Collections.Generic; + using System.Linq; + + class Program { - int Method() - { - var q = from c in - from b in cs - select b - select c; - } - } "); - } + static void Main(string[] args) + { + Console.WriteLine(typeof(Dictionary<, >).IsGenericTypeDefinition); + } + } + """; - [Fact] - public async Task QueryExpression3() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - var q = from c in Get(1 + - 2 + - 3) - from b in Get(1 + - 2 + - 3) - select new { b, c }; - } -}", @"class C -{ - int Method() - { - var q = from c in Get(1 + - 2 + - 3) - from b in Get(1 + - 2 + - 3) - select new { b, c }; - } -}"); - } + var expected = """ + using System; + using System.Collections.Generic; + using System.Linq; - [Fact] - public async Task QueryExpression4() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - var q = - from c in - from b in cs - select b - select c; - } -}", @" class C + class Program { - int Method() - { - var q = - from c in - from b in cs - select b - select c; - } - } "); - } + static void Main(string[] args) + { + Console.WriteLine(typeof(Dictionary<,>).IsGenericTypeDefinition); + } + } + """; - [Fact] - public async Task Label1() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - L: int i = 10; + await AssertFormatAsync(expected, code); } -}", @" class C - { - int Method() - { - L : int i = 10 ; - } - } "); - } - [Fact] - public async Task Label2() - { - await AssertFormatAsync(@"class C -{ - int Method() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543131")] + public async Task TryAfterLabel() { - int x = 1; - L: int i = 10; - } -}", @" class C + var code = """ + using System; + class Program { - int Method() - { -int x = 1 ; - L : int i = 10 ; - } - } "); - } + static object lockObj = new object(); + static int Main() + { + int sum = 0; + lock (lockObj) + try + { sum = 0; } + catch (Exception ex) + { Console.WriteLine(ex); } + return sum; + } + } + """; - [Fact] - public async Task Label3() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - int x = 1; - L: - int i = 10; - } -}", @" class C + var expected = """ + using System; + class Program { - int Method() - { -int x = 1 ; - L : -int i = 10 ; - } - } "); - } + static object lockObj = new object(); + static int Main() + { + int sum = 0; + lock (lockObj) + try + { sum = 0; } + catch (Exception ex) + { Console.WriteLine(ex); } + return sum; + } + } + """; - [Fact] - public async Task Label4() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - int x = 1; - L: int i = 10; - int next = 30; + await AssertFormatAsync(expected, code); } -}", @" class C - { - int Method() - { -int x = 1 ; - L : int i = 10 ; - int next = 30; - } - } "); - } - [Fact] - public async Task Label5() - { - await AssertFormatAsync(@"class C -{ - int Method() + [Fact] + public async Task QueryContinuation1() { - L: int i = 10; - int next = 30; - } -}", @" class C + var code = """ + using System.Linq; + + class Program { - int Method() - { - L : int i = 10 ; - int next = 30; - } - } "); - } + static void Main(string[] args) + { + var q = from arg in args + group arg by arg.Length into final + where final + .Select(c => c) + .Distinct() + .Count() > 0 + select final; + } + } + """; - [Fact] - public async Task Label6() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - L: - int i = 10; - int next = 30; - } -}", @" class C + var expected = """ + using System.Linq; + + class Program { - int Method() - { - L : -int i = 10 ; - int next = 30; - } - } "); - } + static void Main(string[] args) + { + var q = from arg in args + group arg by arg.Length into final + where final + .Select(c => c) + .Distinct() + .Count() > 0 + select final; + } + } + """; - [Fact] - public async Task Label7() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - int i2 = 1; - L: - int i = 10; - int next = 30; + await AssertFormatAsync(expected, code); } -}", @" class C - { - int Method() - { - int i2 = 1 ; - L : -int i = 10 ; - int next = 30; - } - } "); - } - [Fact] - public async Task Label8() - { - await AssertFormatAsync(@"class C -{ - int Method() + [Fact] + public async Task TestCSharpFormattingSpacingOptions() { - L: - int i = - 10; - } -}", @" class C - { - int Method() - { - L: - int i = - 10; - } - } "); - } + var text = + """ - [Fact] - public async Task AutoProperty() - { - await AssertFormatAsync(@"class Class -{ - private int Age { get; set; } - public string Names { get; set; } -}", @" class Class -{ - private int Age{get; set; } - public string Names { get; set;} -}"); - } + interface f1 + { } - [Fact] - public async Task NormalPropertyGet() - { - await AssertFormatAsync(@"class Class -{ - private string name; - public string Names - { - get - { - return name; - } - } -}", @"class Class -{ - private string name; - public string Names - { - get - { - return name; - } - } -}"); - } + interface f2 : f1 { } - [Fact] - public async Task NormalPropertyBoth() - { - await AssertFormatAsync(@"class Class -{ - private string name; - public string Names - { - get - { - return name; - } - set - { - name = value; - } - } -}", @"class Class -{ - private string name; - public string Names - { - get - { - return name; - } - set - { - name = value; - } - } -}"); - } + struct d2 : f1 { } - [Fact] - public async Task ErrorHandling1() - { - await AssertFormatAsync(@"class C -{ - int Method() - { - int a b c; - } -}", @" class C + class goo : System . Object { - int Method() - { - int a b c ; - } - } "); - } + public int bar = 1* 2; + public void goobar ( ) + { + goobar ( ); + } + public int toofoobar( int i , int j ) + { + int s = ( int ) ( 34 ); + if ( i < 0 ) + { + } + return toofoobar( i,j ); + } + public string parfoobar(string [ ] str) + { + for(int i = 0 ; i < 28 ; i++) { } + return str[ 5 ]; + } + } + """; + var expectedFormattedText = + """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537763")] - public async Task NullableType() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) - { - int? i = 10; - } -}", @"class Program -{ - static void Main(string[] args) - { - int ? i = 10; - } -}"); - } + interface f1 + { } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537766")] - public async Task SuppressWrappingOnBraces() - { - await AssertFormatAsync(@"class Class1 -{ } -", @"class Class1 -{} -"); - } + interface f2 : f1 { } + + struct d2 : f1 { } + + class goo : System.Object + { + public int bar = 1 * 2; + public void goobar() + { + goobar(); + } + public int toofoobar(int i, int j) + { + int s = (int)(34); + if (i < 0) + { + } + return toofoobar(i, j); + } + public string parfoobar(string[] str) + { + for (int i = 0; i < 28; i++) { } + return str[5]; + } + } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537824")] - public async Task DoWhile() - { - await AssertFormatAsync(@"public class Class1 -{ - void Goo() - { - do - { - } while (true); - } -} -", @"public class Class1 -{ - void Goo() - { - do - { - }while (true); + await AssertFormatAsync(expectedFormattedText, text); } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537774")] - public async Task SuppressWrappingBug() - { - await AssertFormatAsync(@"class Class1 -{ - int Goo() + [Fact] + public async Task SpacingFixInTokenBasedForIfAndSwitchCase() { - return 0; - } -} -", @"class Class1 -{ - int Goo() - {return 0; + var code = """ + class Class5{ + void bar() + { + if(x == 1) + x = 2; else x = 3; + switch (x) { + case 1: break; case 2: break; default: break;} + } + } + """; + var expectedCode = """ + class Class5 + { + void bar() + { + if (x == 1) + x = 2; + else x = 3; + switch (x) + { + case 1: break; + case 2: break; + default: break; + } + } + } + """; + await AssertFormatAsync(expectedCode, code); } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537768")] - public async Task PreserveLineForAttribute() - { - await AssertFormatAsync(@"class Class1 -{ - [STAThread] - static void Main(string[] args) - { - } -} -", @"class Class1 -{ - [STAThread] -static void Main(string[] args) + [Fact] + public async Task SpacingInDeconstruction() { - } -} -"); - } + var code = """ + class Class5{ + void bar() + { + var(x,y)=(1,2); + } + } + """; + var expectedCode = """ + class Class5 + { + void bar() + { + var (x, y) = (1, 2); + } + } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537878")] - public async Task NoFormattingOnMissingTokens() - { - await AssertFormatAsync(@"namespace ClassLibrary1 -{ - class Class1 - { - void Goo() - { - if (true) - } + await AssertFormatAsync(expectedCode, code); } -} -", @"namespace ClassLibrary1 -{ - class Class1 - { - void Goo() - { - if (true) - } - } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537783")] - public async Task UnaryExpression() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) - { - int a = 6; - a = a++ + 5; - } -} -", @"class Program -{ - static void Main(string[] args) + [Fact] + public async Task SpacingInNullableTuple() { - int a = 6; - a = a++ + 5; + var code = """ + class Class5 + { + void bar() + { + (int, string) ? x = (1, "hello"); + } + } + """; + var expectedCode = """ + class Class5 + { + void bar() + { + (int, string)? x = (1, "hello"); + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537885")] - public async Task Pointer() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact] + public async Task SpacingInTupleArrayCreation() { - int* p; + var code = """ + class C + { + void bar() + { + (string a, string b)[] ab = new(string a, string b) [1]; + } + } + """; + var expectedCode = """ + class C + { + void bar() + { + (string a, string b)[] ab = new (string a, string b)[1]; + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -", @"class Program -{ - static void Main(string[] args) + + [Fact] + public async Task SpacingInTupleArrayCreation2() { - int* p; + var code = """ + class C + { + void bar() + { + (string a, string b)[] ab = new( + } + } + """; + var expectedCode = """ + class C + { + void bar() + { + (string a, string b)[] ab = new( + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50723")] - public async Task TuplePointer() - { - var properlyFormattedCode = @"public unsafe static class Program -{ - public static void Main(string[] args) + [Fact] + public async Task SpacingInImplicitObjectCreation() { - int* intPointer = null; - (int, int)* intIntPointer = null; + var code = """ + class C + { + void bar() + { + C a = new (); + } + } + """; + var expectedCode = """ + class C + { + void bar() + { + C a = new(); + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -"; - await AssertFormatAsync(properlyFormattedCode, properlyFormattedCode); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537886")] - public async Task Tild() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact] + public async Task FormatRecursivePattern_Positional() { - int j = 103; - j = ~7; + var code = """ + class C + { + void M() { _ = this is ( 1 , 2 ) ; } + } + """; + var expectedCode = """ + class C + { + void M() { _ = this is (1, 2); } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -", @"class Program -{ - static void Main(string[] args) + + [Fact] + public async Task FormatRecursivePattern_Positional_Singleline() { - int j = 103; - j = ~7; + var code = """ + class C + { + void M() { + _ = this is ( 1 , 2 ) ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is (1, 2); + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537884")] - public async Task ArrayInitializer1() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact] + public async Task FormatRecursivePattern_Positional_Multiline() { - int[] arr = {1,2, - 3,4 - }; + var code = """ + class C + { + void M() { + _ = this is ( 1 , + 2 , + 3 ) ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is (1, + 2, + 3); + } + } + """; + await AssertFormatAsync(expectedCode, code); } -} -", @"class Program -{ - static void Main(string[] args) + + [Fact] + public async Task FormatRecursivePattern_Positional_Multiline2() { - int[] arr = {1,2, - 3,4 - }; + var code = """ + class C + { + void M() { + _ = this is ( 1 , + 2 , + 3 ) ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is (1, + 2, + 3); + } + } + """; + await AssertFormatAsync(expectedCode, code); } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537884")] - public async Task ArrayInitializer2() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact] + public async Task FormatRecursivePattern_Positional_Multiline3() { - int[] arr = new int[] {1,2, - 3,4 - }; + var code = """ + class C + { + void M() { + _ = this is + ( 1 , + 2 , + 3 ) ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is + (1, + 2, + 3); + } + } + """; + await AssertFormatAsync(expectedCode, code); } -} -", @"class Program -{ - static void Main(string[] args) + + [Fact] + public async Task FormatRecursivePattern_Positional_Multiline4() { - int[] arr = new int [] {1,2, - 3,4 - }; + var code = """ + class C + { + void M() { + _ = this is + ( 1 , + 2 , 3 ) ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is + (1, + 2, 3); + } + } + """; + await AssertFormatAsync(expectedCode, code); } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537884")] - public async Task ImplicitArrayInitializer() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact] + public async Task FormatRecursivePattern_Properties_Singleline() { - var arr = new[] {1,2, - 3,4 - }; + var code = """ + class C + { + void M() { _ = this is C{ P1 : 1 } ; } + } + """; + var expectedCode = """ + class C + { + void M() { _ = this is C { P1: 1 }; } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -", @"class Program -{ - static void Main(string[] args) + + [Fact] + public async Task FormatRecursivePattern_Properties_Multiline() { - var arr = new [] {1,2, - 3,4 - } ; + var code = """ + class C + { + void M() { + _ = this is + { + P1 : 1 , + P2 : 2 + } ; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is + { + P1: 1, + P2: 2 + }; + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] - public async Task StackAllocArrayInitializer0() - { - await AssertFormatAsync(""" - F(stackalloc int[] - { - 1, - 2, - }); - """, """ - F(stackalloc int[] + [Fact] + public async Task FormatRecursivePattern_Properties_Multiline2() + { + var code = """ + class C + { + void M() { + _ = this is { + P1 : 1 , + P2 : 2 + } ; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is { - 1, - 2, - } ); - """); - } + P1: 1, + P2: 2 + }; + } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] - public async Task StackAllocArrayInitializer0_Implicit() - { - await AssertFormatAsync(""" - F(stackalloc[] - { - 1, - 2, - } - ); - """, """ - F( stackalloc [] - { - 1, - 2, - } - ); - """); - } + await AssertFormatAsync(expectedCode, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] - public async Task StackAllocArrayInitializer1() - { - await AssertFormatAsync(""" - F( - stackalloc int[] - { - 1,2, - 3,4 - } - ); - """, """ - F( - stackalloc int[] + [Fact] + public async Task FormatRecursivePattern_Properties_Multiline3() + { + var code = """ + class C + { + void M() { + _ = this is { + P1 : 1 , + P2 : 2, P3: 3 + } ; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is { - 1,2, - 3,4 - } - ); - """); - } + P1: 1, + P2: 2, P3: 3 + }; + } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] - public async Task StackAllocArrayInitializer1_Implicit() - { - await AssertFormatAsync(""" - F( - stackalloc[] - { - 1,2, - 3,4 - } - ); - """, """ - F( - stackalloc [] - { - 1,2, - 3,4 - } - ); - """); - } + await AssertFormatAsync(expectedCode, code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27268")] + public async Task FormatRecursivePattern_NoSpaceBetweenTypeAndPositionalSubpattern() + { + var code = """ + class C + { + void M() { + _ = this is C( 1 , 2 ){} ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is C(1, 2) { }; + } + } + """; + // no space separates the type and the positional pattern + await AssertFormatAsync(expectedCode, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] - public async Task StackAllocArrayInitializer2() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27268")] + public async Task FormatRecursivePattern_PreferSpaceBetweenTypeAndPositionalSubpattern() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - await AssertFormatAsync(""" - var x = (stackalloc int[] {1,2, - 3 - }); - """, """ - var x = (stackalloc int[] {1,2, - 3 - }); - """); - } + { CSharpFormattingOptions2.SpaceAfterMethodCallName, true } + }; + var code = """ + class C + { + void M() { + _ = this is C( 1 , 2 ){} ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is C (1, 2) { }; + } + } + """; + await AssertFormatAsync(expectedCode, code, changedOptionSet: changingOptions); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65498")] - public async Task StackAllocArrayInitializer2_Implicit() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27268")] + public async Task FormatRecursivePattern_PreferSpaceInsidePositionalSubpatternParentheses() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - await AssertFormatAsync(""" - var x = (stackalloc[] - {1, - 2, 3 - }); - """, """ - var x = (stackalloc [] - {1, - 2, 3 - }); - """); - } + { CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, true } + }; + var code = """ + class C + { + void M() { + _ = this is C( 1 , 2 ){} ; + _ = this is C( ){} ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is C( 1, 2 ) { }; + _ = this is C() { }; + } + } + """; + await AssertFormatAsync(expectedCode, code, changedOptionSet: changingOptions); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537884")] - public async Task CollectionInitializer() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27268")] + public async Task FormatRecursivePattern_PreferSpaceInsideEmptyPositionalSubpatternParentheses() { - var arr = new List {1,2, - 3,4 + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses, true } }; + var code = """ + class C + { + void M() { + _ = this is C( 1 , 2 ){} ; + _ = this is C( ){} ; } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is C(1, 2) { }; + _ = this is C( ) { }; + } + } + """; + await AssertFormatAsync(expectedCode, code, changedOptionSet: changingOptions); } -} -", @"class Program -{ - static void Main(string[] args) + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/34683")] + public async Task FormatRecursivePattern_InBinaryOperation() { - var arr = new List {1,2, - 3,4 + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, true } }; + var code = """ + class C + { + void M() + { + return + typeWithAnnotations is { } && true; + } + } + """; + var expectedCode = code; + await AssertFormatAsync(expectedCode, code, changedOptionSet: changingOptions); } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537916")] - public async Task AddressOfOperator() - { - await AssertFormatAsync(@"unsafe class Class1 -{ - void Method() + [Fact] + public async Task FormatPropertyPattern_MultilineAndEmpty() { - int a = 12; - int* p = &a; + var code = """ + class C + { + void M() { + _ = this is + { + }; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is + { + }; + } + } + """; + await AssertFormatAsync(expectedCode, code); } -} -", @"unsafe class Class1 -{ - void Method() + + [Fact] + public async Task FormatSwitchExpression_IndentArms() { - int a = 12; - int* p = &a; + var code = """ + class C + { + void M() { + _ = this switch + { + { P1: 1} => true, + (0, 1) => true, + _ => false + }; + + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this switch + { + { P1: 1 } => true, + (0, 1) => true, + _ => false + }; + + } + } + """; + await AssertFormatAsync(expectedCode, code); } -} -"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537885")] - public async Task DereferenceOperator() - { - await AssertFormatAsync(@"unsafe class Class1 -{ - void Method() + [Fact] + public async Task FormatPropertyPattern_FollowedByInvocation() { - int a = 12; - int* p = &a; - Console.WriteLine(*p); + var code = """ + class C + { + void M() { + _ = this is { } + M(); + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is { } + M(); + } + } + """; + // although 'M' will be parsed into the pattern on line above, we should not wrap the pattern + await AssertFormatAsync(expectedCode, code); } -} -", @"unsafe class Class1 -{ - void Method() + + [Fact] + public async Task FormatPositionalPattern_FollowedByInvocation() { - int a = 12; - int* p = & a; - Console.WriteLine(* p); + var code = """ + class C + { + void M() { + _ = this is (1, 2) { } + M(); + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is (1, 2) { } + M(); + } + } + """; + // although 'M' will be parsed into the pattern on line above, we should not wrap the pattern + await AssertFormatAsync(expectedCode, code); } -} -"); - } - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537905")] - public async Task Namespaces() - { - await AssertFormatAsync(@"using System; -using System.Data;", @"using System; using System.Data;"); - } - [Fact] - public async Task NamespaceDeclaration() - { - await AssertFormatAsync(@"namespace N -{ -}", @"namespace N + [Fact] + public async Task FormatPositionalPattern_FollowedByScope() { -}"); - } + var code = """ + class C + { + void M() { + _ = this is (1, 2) + { + M(); + } + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is (1, 2) + { + M(); + } + } + } + """; + // You should not invoke Format on incomplete code and expect nice results + await AssertFormatAsync(expectedCode, code); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537902")] - public async Task DoWhile1() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact] + public async Task FormatSwitchExpression_MultilineAndNoArms() { - do { } - while (i < 4); + var code = """ + class C + { + void M() { + _ = this switch + { + }; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this switch + { + }; + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", @"class Program -{ - static void Main(string[] args) + + [Fact] + public async Task FormatSwitchExpression_ExpressionAnchoredToArm() { - do { } - while (i < 4); + var code = """ + class C + { + void M() { + _ = this switch + { + { P1: 1} + => true, + (0, 1) + => true, + _ + => false + }; + + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this switch + { + { P1: 1 } + => true, + (0, 1) + => true, + _ + => false + }; + + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}"); - } - [Fact] - public async Task NewConstraint() - { - await AssertFormatAsync(@"class Program -{ - void Test(T t) where T : new() + [Fact] + public async Task FormatSwitchExpression_NoSpaceBeforeColonInArm() { + var code = """ + class C + { + void M() { + _ = this switch + { + { P1: 1} + => true, + (0, 1) + => true, + _ + => false + }; + + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this switch + { + { P1: 1 } + => true, + (0, 1) + => true, + _ + => false + }; + + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", @"class Program -{ - void Test(T t) where T : new ( ) + + [Fact] + public async Task FormatSwitchExpression_ArmCommaWantsNewline() { - } -}"); - } + var code = """ + class C + { + void M() { + _ = this switch + { + { P1: 1} => true, + (0, 1) => true, _ => false + }; - [Fact] - public async Task UnaryExpressionWithInitializer() - { - await AssertFormatAsync(@"using System; -using System.Collections.Generic; -using System.Linq; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this switch + { + { P1: 1 } => true, + (0, 1) => true, + _ => false + }; -class Program -{ - static void Main(string[] args) - { - if ((new int[] { 1, 2, 3 }).Any()) - { - return; - } + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", @"using System; -using System.Collections.Generic; -using System.Linq; -class Program -{ - static void Main(string[] args) + [Fact] + public async Task FormatSwitchExpression_ArmCommaPreservesLines() { - if ((new int[] { 1, 2, 3 } ).Any()) - { - return; - } - } -}"); - } + var code = """ + class C + { + void M() { + _ = this switch + { + { P1: 1} => true, - [Fact] - public async Task Attributes1() - { - await AssertFormatAsync(@"class Program -{ - [Flags] public void Method() { } -}", @"class Program -{ - [ Flags ] public void Method ( ) { } -}"); - } + (0, 1) => true, _ => false + }; - [Fact] - public async Task Attributes2() - { - await AssertFormatAsync(@"class Program -{ - [Flags] - public void Method() { } -}", @"class Program -{ - [ Flags ] -public void Method ( ) { } -}"); - } + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this switch + { + { P1: 1 } => true, - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538288")] - public async Task ColonColon1() - { - await AssertFormatAsync(@"class Program -{ - public void Method() - { - throw new global::System.NotImplementedException(); + (0, 1) => true, + _ => false + }; + + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", @"class Program -{ -public void Method ( ) { - throw new global :: System.NotImplementedException(); -} -}"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538354")] - public async Task BugFix3939() - { - await AssertFormatAsync(@"using - System. - Collections. - Generic;", @" using - System. - Collections. - Generic;"); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33839")] + public async Task FormatSwitchExpression_ExpressionBody() + { + var code = """ + + public class Test + { + public object Method(int i) + => i switch + { + 1 => 'a', + 2 => 'b', + _ => null, + }; + } + """; + var expectedCode = """ + + public class Test + { + public object Method(int i) + => i switch + { + 1 => 'a', + 2 => 'b', + _ => null, + }; + } + """; + + await AssertFormatAsync(expectedCode, code); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538354")] - public async Task Tab1() - => await AssertFormatAsync(@"using System;", @" using System;"); + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/72196")] + [InlineData("[]")] + [InlineData("[a]")] + [InlineData("[a, b]")] + [InlineData("[..]")] + [InlineData("[var a, .., var b]")] + [InlineData("[{ } a, null]")] + [InlineData("[a, []]")] + public async Task FormatSwitchExpression_ListPatternAligned(string listPattern) + { + var code = $$""" + class C + { + void M() + { + _ = Array.Empty() switch + { + {{listPattern}} => 0, + _ => 1, + }; + } + } + """; + var expectedCode = $$""" + class C + { + void M() + { + _ = Array.Empty() switch + { + {{listPattern}} => 0, + _ => 1, + }; + } + } + """; + await AssertFormatAsync(expectedCode, code); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538329")] - public async Task SuppressLinkBreakInIfElseStatement() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact] + public async Task FormatSwitchWithPropertyPattern() { - int a; - if (true) a = 10; - else a = 11; + var code = """ + class C + { + void M() + { + switch (this) + { + case { P1: 1, P2: { P3: 3, P4: 4 } }: + break; + } + } + } + """; + var expectedCode = """ + class C + { + void M() + { + switch (this) + { + case { P1: 1, P2: { P3: 3, P4: 4 } }: + break; + } + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", @"class Program -{ - static void Main(string[] args) + + [Fact] + public async Task FormatSwitchWithPropertyPattern_Singleline() { - int a; - if (true) a = 10; - else a = 11; + var code = """ + class C + { + void M() + { + switch (this) + { + case { P1: 1, P2: { P3: 3, P4: 4 } }: break; + } + } + } + """; + var expectedCode = """ + class C + { + void M() + { + switch (this) + { + case { P1: 1, P2: { P3: 3, P4: 4 } }: break; + } + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -}"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538464")] - public async Task BugFix4087() - { - await AssertFormatAsync(@"class Program -{ - static void Main(string[] args) + [Fact] + public async Task FormatSwitchWithPropertyPattern_Singleline2() { - Func fun = x => { return x + 1; } + var code = """ + class C + { + void M() + { + switch (this) + { + case { P1: 1, P2: { P3: 3, P4: 4 } }: System.Console.Write(1); + break; + } + } + } + """; + var expectedCode = """ + class C + { + void M() + { + switch (this) + { + case { P1: 1, P2: { P3: 3, P4: 4 } }: + System.Console.Write(1); + break; + } + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", @"class Program -{ - static void Main(string[] args) + + [Fact] + public async Task SpacingInTupleExtension() { - Func fun = x => { return x + 1; } + var code = """ + static class Class5 + { + static void Extension(this(int, string) self) { } + } + """; + var expectedCode = """ + static class Class5 + { + static void Extension(this (int, string) self) { } + } + """; + + await AssertFormatAsync(expectedCode, code); } -}"); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538511")] - public async Task AttributeTargetSpecifier() - { - var code = @"public class Class1 -{ - [method : - void Test() + [Fact] + public async Task SpacingInNestedDeconstruction() { + var code = """ + class Class5{ + void bar() + { + ( int x1 , var( x2,x3 ) )=(1,(2,3)); + } + } + """; + var expectedCode = """ + class Class5 + { + void bar() + { + (int x1, var (x2, x3)) = (1, (2, 3)); + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -}"; - var expected = @"public class Class1 -{ - [method: - void Test() + [Fact] + public async Task SpacingInSuppressNullableWarningExpression() { + var code = + """ + class C + { + static object F() + { + object? o[] = null; + object? x = null; + object? y = null; + return x ! ?? (y) ! ?? o[0] !; + } + } + """; + var expectedCode = + """ + class C + { + static object F() + { + object? o[] = null; + object? x = null; + object? y = null; + return x! ?? (y)! ?? o[0]!; + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -}"; - await AssertFormatAsync(expected, code); - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545335")] + public async Task PreprocessorOnSameLine() + { + var code = """ + class C + { + }#line default - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538635")] - public async Task Finalizer() - { - var code = @"public class Class1 -{ - ~ Class1() { } -}"; + #line hidden + """; - var expected = @"public class Class1 -{ - ~Class1() { } -}"; + var expected = """ + class C + { + }#line default - await AssertFormatAsync(expected, code); - } + #line hidden + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538743")] - public async Task BugFix4442() - { - var code = @"class Program -{ - static void Main(string[] args) - { - string str = ""ab,die|wo""; - string[] a = str.Split(new char[] { ',', '|' }) - ; + await AssertFormatAsync(expected, code); } -}"; - - await AssertFormatAsync(code, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538658")] - public async Task BugFix4328() - { - var code = @"class Program -{ - static void Main(string[] args) - { - double d = new double (); - } -}"; - var expected = @"class Program -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545626")] + public async Task ArraysInAttributes() { - double d = new double(); - } -}"; - await AssertFormatAsync(expected, code); - } + var code = """ + [A(X = new int[] { 1 })] + public class A : Attribute + { + public int[] X; + } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538658")] - public async Task BugFix4515() - { - var code = @"class Program -{ - static void Main(string[] args) - { - var t = typeof ( System.Object ) ; - var t1 = default ( System.Object ) ; - var t2 = sizeof ( System.Object ) ; - } -}"; - var expected = @"class Program -{ - static void Main(string[] args) - { - var t = typeof(System.Object); - var t1 = default(System.Object); - var t2 = sizeof(System.Object); - } -}"; - await AssertFormatAsync(expected, code); - } + var expected = """ + [A(X = new int[] { 1 })] + public class A : Attribute + { + public int[] X; + } + """; - [Fact] - public async Task CastExpressionTest() - { - var code = @"class Program -{ - static void Main(string[] args) - { - var a = (int) 1; - } -}"; - var expected = @"class Program -{ - static void Main(string[] args) - { - var a = (int)1; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact] - public async Task NamedParameter() - { - var code = @"class Program -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530580")] + public async Task NoNewLineAfterBraceInExpression() { - Main ( args : null ) ; - } -}"; - var expected = @"class Program -{ - static void Main(string[] args) - { - Main(args: null); - } -}"; - await AssertFormatAsync(expected, code); - } - - [Fact] - public async Task RefReadonlyParameters() - { - var code = """ - class C + var code = """ + public class A + { + void Method() { - int this [ ref readonly int x , ref readonly int y ] { get ; set ; } - void M ( ref readonly int x , ref readonly int y ) { } + var po = cancellationToken.CanBeCanceled ? + new ParallelOptions() { CancellationToken = cancellationToken } : + defaultParallelOptions; } - """; - var expected = """ - class C + } + """; + + var expected = """ + public class A + { + void Method() { - int this[ref readonly int x, ref readonly int y] { get; set; } - void M(ref readonly int x, ref readonly int y) { } + var po = cancellationToken.CanBeCanceled ? + new ParallelOptions() { CancellationToken = cancellationToken } : + defaultParallelOptions; } - """; - await AssertFormatAsync(expected, code); - } + } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539259")] - public async Task BugFix5143() - { - var code = @"class Program -{ - static void Main(string[] args) - { - int x = Goo ( - delegate ( int x ) { return x ; } ) ; + await AssertFormatAsync(expected, code); } -}"; - var expected = @"class Program -{ - static void Main(string[] args) + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530580")] + public async Task NoIndentForNestedUsingWithoutBraces() { - int x = Goo( - delegate (int x) { return x; }); - } -}"; - await AssertFormatAsync(expected, code); - } + var code = """ + class C + { + void M() + { + using (null) + using (null) + { + } + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539338")] - public async Task BugFix5251() - { - var code = @"class Program -{ - public static string Goo { get; private set; } -}"; - var expected = @"class Program -{ - public static string Goo { get; private set; } -}"; - await AssertFormatAsync(expected, code); - } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539358")] - public async Task BugFix5277() - { - var code = @" -#if true - #endif -"; - var expected = @" -#if true -#endif -"; - await AssertFormatAsync(expected, code); - } + var expected = """ + class C + { + void M() + { + using (null) + using (null) + { + } + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539542")] - public async Task BugFix5544() - { - var code = @" -class Program -{ - unsafe static void Main(string[] args) - { - Program* p; - p -> Goo = 5; - } -} -"; - var expected = @" -class Program -{ - unsafe static void Main(string[] args) - { - Program* p; - p->Goo = 5; + """; + + await AssertFormatAsync(expected, code); } -} -"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539587")] - public async Task BugFix5602() - { - var code = @" class Bug - { - public static void func() - { - long b = // - } - }"; - var expected = @"class Bug -{ - public static void func() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530580")] + public async Task NoIndentForNestedUsingWithoutBraces2() { - long b = // - } -}"; - await AssertFormatAsync(expected, code); - } + var code = """ + class C + { + void M() + { + using (null) + using (null) + using (null) + { + } + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539616")] - public async Task BugFix5637() - { - var code = @"class Bug -{ - // test - public static void func() - { - } -}"; - var expected = @"class Bug -{ - // test - public static void func() - { - } -}"; - await AssertFormatAsync(expected, code); - } + """; - [Fact] - public async Task GenericType() - { - var code = @"class Bug -{ - class N : Bug< T [ ] > - { - } -}"; - var expected = @"class Bug -{ - class N : Bug - { - } -}"; - await AssertFormatAsync(expected, code); - } + var expected = """ + class C + { + void M() + { + using (null) + using (null) + using (null) + { + } + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539878")] - public async Task BugFix5978() - { - var code = @"class Program -{ - static void Main(string[] args) - { - int i = 3; - label4: - if (i < 5) - { - label5: -if (i == 4) -{ -} -else -{ -System.Console.WriteLine(""a""); -} - } + """; + + await AssertFormatAsync(expected, code); } -}"; - var expected = @"class Program -{ - static void Main(string[] args) + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530580")] + public async Task NoIndentForNestedUsingWithoutBraces3() { - int i = 3; - label4: - if (i < 5) - { - label5: - if (i == 4) + var code = """ + class C { + void M() + { + using (null) + using (null) + using (null) + { + } + } } - else + + """; + + var expected = """ + class C { - System.Console.WriteLine(""a""); + void M() + { + using (null) + using (null) + using (null) + { + } + } } - } - } -}"; - await AssertFormatAsync(expected, code); - } - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539878")] - public async Task BugFix5979() - { - var code = @"delegate int del(int i); -class Program -{ - static void Main(string[] args) - { - del q = x => - { - label2: goto label1; - label1: return x; - }; - } -}"; - var expected = @"delegate int del(int i); -class Program -{ - static void Main(string[] args) - { - del q = x => - { - label2: goto label1; - label1: return x; - }; - } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539891")] - public async Task BugFix5993() - { - var code = @"public class MyClass -{ - public static void Main() - { - lab1: - { - lab1:// CS0158 - goto lab1; - } - } -}"; - var expected = @"public class MyClass -{ - public static void Main() - { - lab1: - { - lab1:// CS0158 - goto lab1; - } - } -}"; - await AssertFormatAsync(expected, code); - } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540315")] - public async Task BugFix6536() - { - var code = @"public class MyClass -{ - public static void Main() - { - int i = - - 1 + + + 1 + - + 1 + - + 1 ; - } -}"; - var expected = @"public class MyClass -{ - public static void Main() - { - int i = - -1 + + +1 + -+1 + -+1; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540801")] - public async Task BugFix7211() - { - var code = @"class Program -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546678")] + public async Task UnicodeWhitespace() { - while (0 > new int[] { 1 }.Length) - { - System.Console.WriteLine(""Hello""); - } - } -}"; + var code = "\u001A"; - var expected = @"class Program -{ - static void Main(string[] args) - { - while (0 > new int[] { 1 }.Length) - { - System.Console.WriteLine(""Hello""); - } + await AssertFormatAsync("", code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541035")] - public async Task BugFix7564_1() - { - var code = @"class Program -{ - static void Main(string[] args) + [Fact, WorkItem(17431, "DevDiv_Projects/Roslyn")] + public async Task NoElasticRuleOnRegularFile() { - while (null != new int[] { 1 }) - { - System.Console.WriteLine(""Hello""); - } - } -}"; + var code = """ + class Consumer + { + public int P + { + } + } + """; - var expected = @"class Program -{ - static void Main(string[] args) - { - while (null != new int[] { 1 }) - { - System.Console.WriteLine(""Hello""); - } + var expected = """ + class Consumer + { + public int P + { + } + } + """; + + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541035")] - public async Task BugFix7564_2() - { - var code = @"class Program -{ - static void Main(string[] args) + [Fact, WorkItem(584599, "DevDiv_Projects/Roslyn")] + public async Task CaseSection() { - foreach (var f in new int[] { 5 }) - { - Console.WriteLine(f); - } + var code = """ + class C + { + void Method() + { + switch(i) + { + // test1 + case 1: + // test2 + case 2: + // test3 + int i2 = 10; + // test 4 + case 4: + // test 5 + } + } + } + """; + + var expected = """ + class C + { + void Method() + { + switch (i) + { + // test1 + case 1: + // test2 + case 2: + // test3 + int i2 = 10; + // test 4 + case 4: + // test 5 + } + } + } + """; + + await AssertFormatAsync(expected, code); } -}"; - var expected = @"class Program -{ - static void Main(string[] args) + [Fact, WorkItem(553654, "DevDiv_Projects/Roslyn")] + public async Task Bugfix_553654_LabelStatementIndenting() { - foreach (var f in new int[] { 5 }) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - Console.WriteLine(f); - } + { CSharpFormattingOptions2.LabelPositioning, LabelPositionOptions.LeftMost } + }; + + var code = """ + class Program + { + void F() + { + foreach (var x in new int[] { }) + { + goo: + int a = 1; + } + } + } + """; + + var expected = """ + class Program + { + void F() + { + foreach (var x in new int[] { }) + { + goo: + int a = 1; + } + } + } + """; + await AssertFormatAsync(expected, code, changingOptions); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem(8385, "DevDiv_Projects/Roslyn")] - public async Task NullCoalescingOperator() - { - var code = @"class C -{ - void M() + [Fact, WorkItem(707064, "DevDiv_Projects/Roslyn")] + public async Task Bugfix_707064_SpaceAfterSecondSemiColonInFor() { - object o2 = null??null; + var code = """ + class Program + { + void F() + { + for (int i = 0; i < 5;) + { + } + } + } + """; + + var expected = """ + class Program + { + void F() + { + for (int i = 0; i < 5;) + { + } + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - var expected = @"class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772313")] + public async Task Bugfix_772313_ReturnKeywordBeforeQueryClauseDoesNotTriggerNewLineOnFormat() { - object o2 = null ?? null; + var code = """ + class C + { + int M() + { + return from c in " + select c; + } + } + """; + + var expected = """ + class C + { + int M() + { + return from c in " + select c; + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541925")] - public async Task QueryContinuation() - { - var code = @"using System.Linq; -class C -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772304")] + public async Task Bugfix_772313_PreserveMethodParameterIndentWhenAttributePresent() { - var temp = from x in ""abc"" - let z = x.ToString() - select z into w - select w; + var code = """ + class C + { + void M + ( + [In] + bool b + ); + } + + class C + { + void M + ( + [In] + List b + ); + } + + class C + { + void M + ( + [In] + [In, In] + List b + ); + } + """; + + var expected = """ + class C + { + void M + ( + [In] + bool b + ); + } + + class C + { + void M + ( + [In] + List b + ); + } + + class C + { + void M + ( + [In] + [In, In] + List b + ); + } + """; + await AssertFormatAsync(expected, code); } -}"; - var expected = @"using System.Linq; -class C -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/776513")] + public async Task Bugfix_776513_CheckBraceIfNotMissingBeforeApplyingOperationForBracedBlocks() { - var temp = from x in ""abc"" - let z = x.ToString() - select z into w - select w; + var code = """ + var alwaysTriggerList = new[] + Dim triggerOnlyWithLettersList = + """; + + var expected = """ + var alwaysTriggerList = new[] + Dim triggerOnlyWithLettersList = + """; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact] - public async Task QueryContinuation2() - { - var code = @"using System.Linq; -class C -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/769342")] + public async Task ShouldFormatDocCommentWithIndentSameAsTabSizeWithUseTabTrue() { - var temp = from x in ""abc"" select x into + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + + await AssertFormatAsync(""" + namespace ConsoleApplication1 + { + /// + /// fka;jsgdflkhsjflgkhdsl; + /// + class Program + { + } + } + """, """ + namespace ConsoleApplication1 + { + /// + /// fka;jsgdflkhsjflgkhdsl; + /// + class Program + { + } + } + """, changedOptionSet: optionSet); } -}"; - var expected = @"using System.Linq; -class C -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/797278")] + public async Task TestSpacingOptionAroundControlFlow() { - var temp = from x in ""abc"" - select x into - } -}"; - await AssertFormatAsync(expected, code); - } + const string code = """ + + class Program + { + public void goo() + { + int i; + for(i=0; i<10; i++) + {} + + foreach(i in new[] {1,2,3}) + {} + + if (i==10) + {} + + while(i==10) + {} + + switch(i) + { + default: break; + } + + do {} while (true); + + try + { } + catch (System.Exception) + { } + catch (System.Exception e) when (true) + { } + + using(somevar) + { } + + lock(somevar) + { } + + fixed(char* p = str) + { } + } + } + """; + const string expected = """ + + class Program + { + public void goo() + { + int i; + for ( i = 0; i < 10; i++ ) + { } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542305")] - public async Task AttributeFormatting1() + foreach ( i in new[] { 1, 2, 3 } ) + { } + + if ( i == 10 ) + { } + + while ( i == 10 ) + { } + + switch ( i ) + { + default: break; + } + + do { } while ( true ); + + try + { } + catch ( System.Exception ) + { } + catch ( System.Exception e ) when ( true ) + { } + + using ( somevar ) + { } + + lock ( somevar ) + { } + + fixed ( char* p = str ) + { } + } + } + """; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { - var code = @"class Program -{ - void AddClass(string name,[OptionalAttribute] object position,[OptionalAttribute] object bases) - { - } -}"; + { SpaceBetweenParentheses, SpaceBetweenParentheses.DefaultValue.WithFlagValue( SpacePlacementWithinParentheses.ControlFlowStatements, true) }, + }; - var expected = @"class Program -{ - void AddClass(string name, [OptionalAttribute] object position, [OptionalAttribute] object bases) - { + await AssertFormatAsync(expected, code, changedOptionSet: optionSet); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542304")] - public async Task CloseBracesInArgumentList() - { - var code = @"class Program -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37031")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/176345")] + public async Task TestSpacingOptionAfterControlFlowKeyword() { - var relativeIndentationGetter = new Lazy(() => - { - var indentationDelta = operation.IndentationDeltaOrPosition * this.OptionSet.IndentationSize; - var baseIndentation = this.tokenStream.GetCurrentColumn(operation.BaseToken); + var code = """ + + class Program + { + public void goo() + { + int i; + for (i=0; i<10; i++) + {} + + foreach (i in new[] {1,2,3}) + {} + + if (i==10) + {} + + while (i==10) + {} + + switch (i) + { + default: break; + } + + do {} while (true); - return baseIndentation + indentationDelta; - } , isThreadSafe: true); + try + { } + catch (System.Exception e) when (true) + { } + + using (somevar) + { } + + lock (somevar) + { } + + fixed (somevar) + { } + } + } + """; + var expected = """ + + class Program + { + public void goo() + { + int i; + for(i = 0; i < 10; i++) + { } + + foreach(i in new[] { 1, 2, 3 }) + { } + + if(i == 10) + { } + + while(i == 10) + { } + + switch(i) + { + default: break; + } + + do { } while(true); + + try + { } + catch(System.Exception e) when(true) + { } + + using(somevar) + { } + + lock(somevar) + { } + + fixed(somevar) + { } + } + } + """; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.SpaceAfterControlFlowStatementKeyword, false } }; + await AssertFormatAsync(expected, code, changedOptionSet: optionSet); } -}"; - var expected = @"class Program -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/766212")] + public async Task TestOptionForSpacingAroundCommas() { - var relativeIndentationGetter = new Lazy(() => - { - var indentationDelta = operation.IndentationDeltaOrPosition * this.OptionSet.IndentationSize; - var baseIndentation = this.tokenStream.GetCurrentColumn(operation.BaseToken); + var code = """ + + class Program + { + public void Main() + { + var a = new[] {1,2,3}; + var digits = new List {1,2,3,4}; + } + } + """; + var expectedDefault = """ + + class Program + { + public void Main() + { + var a = new[] { 1, 2, 3 }; + var digits = new List { 1, 2, 3, 4 }; + } + } + """; + await AssertFormatAsync(expectedDefault, code); + + var expectedAfterCommaDisabled = """ + + class Program + { + public void Main() + { + var a = new[] { 1,2,3 }; + var digits = new List { 1,2,3,4 }; + } + } + """; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.SpaceAfterComma, false } }; + await AssertFormatAsync(expectedAfterCommaDisabled, code, changedOptionSet: optionSet); + + var expectedBeforeCommaEnabled = """ - return baseIndentation + indentationDelta; - }, isThreadSafe: true); + class Program + { + public void Main() + { + var a = new[] { 1 ,2 ,3 }; + var digits = new List { 1 ,2 ,3 ,4 }; + } + } + """; + optionSet.Add(CSharpFormattingOptions2.SpaceBeforeComma, true); + await AssertFormatAsync(expectedBeforeCommaEnabled, code, changedOptionSet: optionSet); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542538")] - public async Task MissingTokens() - { - var code = @"using System; -delegate void myDelegate(int name = 1); -class innerClass -{ - public innerClass() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772308")] + public async Task Bugfix_772308_SeparateSuppressionForEachCaseLabelEvenIfEmpty() { - myDelegate x = (int y=1) => { return; }; - } -}"; + var code = """ + + class C + { + int M() + { + switch (1) + { + case 1: return 1; + case 2: return 2; + case 3: + case 4: return 4; + default: + } + } + } + + """; + + var expected = """ + + class C + { + int M() + { + switch (1) + { + case 1: return 1; + case 2: return 2; + case 3: + case 4: return 4; + default: + } + } + } - var expected = @"using System; -delegate void myDelegate(int name = 1); -class innerClass -{ - public innerClass() - { - myDelegate x = (int y = 1) => { return; }; + """; + await AssertFormatAsync(expected, code); } -}"; - - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542199")] - public async Task ColumnOfVeryFirstToken() - { - var code = @" W )b"; - - var expected = @"W )b"; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/844913")] + public async Task QueryExpressionInExpression() + { + var code = """ - await AssertFormatAsync(expected, code); - } + class C + { + public void CreateSettingsFile(string path, string comment) { + var xml = new XDocument( + new XDeclaration(1.0, utf8, yes), + new XComment(comment), + new XElement(UserSettings, + new XElement(ToolsOptions, + from t in KnownSettings.DefaultCategories + group t by t.Item1 into cat + select new XElement(ToolsOptionsCategory, + new XAttribute(name, cat.Key), + cat.Select(sc => new XElement(ToolsOptionsSubCategory, new XAttribute(name, sc.Item2))) + ) + ) + ) + ); + UpdateSettingsXml(xml); + xml.Save(path); + SettingsPath = path; + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542718")] - public async Task EmptySuppressionSpan() - { - var code = @"enum E - { - a,, - }"; + """; - var expected = @"enum E -{ - a,, -}"; + var expected = """ - await AssertFormatAsync(expected, code); - } + class C + { + public void CreateSettingsFile(string path, string comment) + { + var xml = new XDocument( + new XDeclaration(1.0, utf8, yes), + new XComment(comment), + new XElement(UserSettings, + new XElement(ToolsOptions, + from t in KnownSettings.DefaultCategories + group t by t.Item1 into cat + select new XElement(ToolsOptionsCategory, + new XAttribute(name, cat.Key), + cat.Select(sc => new XElement(ToolsOptionsSubCategory, new XAttribute(name, sc.Item2))) + ) + ) + ) + ); + UpdateSettingsXml(xml); + xml.Save(path); + SettingsPath = path; + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542790")] - public async Task LabelInSwitch() - { - var code = @"class test -{ - public static void Main() - { - string target = ""t1""; - switch (target) - { - case ""t1"": - label1: - goto label1; - case ""t2"": - label2: - goto label2; - } + """; + await AssertFormatAsync(expected, code); } -}"; - var expected = @"class test -{ - public static void Main() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/843479")] + public async Task EmbeddedStatementElse() { - string target = ""t1""; - switch (target) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - case ""t1"": - label1: - goto label1; - case ""t2"": - label2: - goto label2; - } - } -}"; + { CSharpFormattingOptions2.NewLineForElse, false } + }; - await AssertFormatAsync(expected, code); - } + var code = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543112")] - public void FormatArbitaryNode() - { - var expected = @"public int Prop -{ - get - { - return c; - } + class C + { + void Method() + { + if (true) + Console.WriteLine(); else + Console.WriteLine(); + } + } - set - { - c = value; - } -}"; + """; - var property = SyntaxFactory.PropertyDeclaration( - attributeLists: [], - [PublicKeyword], - SyntaxFactory.ParseTypeName("int"), - null, - SyntaxFactory.Identifier("Prop"), - SyntaxFactory.AccessorList([ - SyntaxFactory.AccessorDeclaration( - SyntaxKind.GetAccessorDeclaration, - SyntaxFactory.Block(SyntaxFactory.ParseStatement("return c;"))), - SyntaxFactory.AccessorDeclaration( - SyntaxKind.SetAccessorDeclaration, - SyntaxFactory.Block(SyntaxFactory.ParseStatement("c = value;")))])); + var expected = """ - Assert.NotNull(property); - using var workspace = new AdhocWorkspace(); - var newProperty = Formatter.Format(property, workspace.Services.SolutionServices, CSharpSyntaxFormattingOptions.Default, CancellationToken.None); + class C + { + void Method() + { + if (true) + Console.WriteLine(); + else + Console.WriteLine(); + } + } - Assert.Equal(expected, newProperty.ToFullString()); - } + """; + await AssertFormatAsync(expected, code, changingOptions); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543140")] - public async Task OmittedTypeArgument() - { - var code = @"using System; -using System.Collections.Generic; -using System.Linq; - -class Program -{ - static void Main(string[] args) + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772311")] + public async Task LineCommentAtTheEndOfLine() { - Console.WriteLine(typeof(Dictionary<, >).IsGenericTypeDefinition); - } -}"; + var code = """ - var expected = @"using System; -using System.Collections.Generic; -using System.Linq; + using System; -class Program -{ - static void Main(string[] args) - { - Console.WriteLine(typeof(Dictionary<,>).IsGenericTypeDefinition); - } -}"; + class Program + { + static void Main(string[] args) + { + Console.WriteLine(); // this is a comment + // that I would like to keep - await AssertFormatAsync(expected, code); - } + // properly indented + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543131")] - public async Task TryAfterLabel() - { - var code = @"using System; -class Program -{ - static object lockObj = new object(); - static int Main() - { - int sum = 0; - lock (lockObj) - try - { sum = 0; } - catch (Exception ex) - { Console.WriteLine(ex); } - return sum; - } -}"; + """; - var expected = @"using System; -class Program -{ - static object lockObj = new object(); - static int Main() - { - int sum = 0; - lock (lockObj) - try - { sum = 0; } - catch (Exception ex) - { Console.WriteLine(ex); } - return sum; - } -}"; + var expected = """ - await AssertFormatAsync(expected, code); - } + using System; - [Fact] - public async Task QueryContinuation1() - { - var code = @"using System.Linq; + class Program + { + static void Main(string[] args) + { + Console.WriteLine(); // this is a comment + // that I would like to keep -class Program -{ - static void Main(string[] args) - { - var q = from arg in args - group arg by arg.Length into final - where final - .Select(c => c) - .Distinct() - .Count() > 0 - select final; - } -}"; + // properly indented + } + } - var expected = @"using System.Linq; + """; + await AssertFormatAsync(expected, code); + } -class Program -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38224")] + public async Task BlockCommentAtTheEndOfLine1() { - var q = from arg in args - group arg by arg.Length into final - where final - .Select(c => c) - .Distinct() - .Count() > 0 - select final; - } -}"; + var code = """ - await AssertFormatAsync(expected, code); - } + using System; - [Fact] - public async Task TestCSharpFormattingSpacingOptions() - { - var text = -@" -interface f1 -{ } + class Program + { + static void Main(string[] args) + { + Console.WriteLine(); /* this is a comment */ + // that I would like to keep -interface f2 : f1 { } + // properly indented + } + } -struct d2 : f1 { } + """; -class goo : System . Object -{ - public int bar = 1* 2; - public void goobar ( ) - { - goobar ( ); - } - public int toofoobar( int i , int j ) - { - int s = ( int ) ( 34 ); - if ( i < 0 ) - { - } - return toofoobar( i,j ); - } - public string parfoobar(string [ ] str) - { - for(int i = 0 ; i < 28 ; i++) { } - return str[ 5 ]; - } -}"; - var expectedFormattedText = -@" -interface f1 -{ } + var expected = """ -interface f2 : f1 { } + using System; -struct d2 : f1 { } + class Program + { + static void Main(string[] args) + { + Console.WriteLine(); /* this is a comment */ + // that I would like to keep -class goo : System.Object -{ - public int bar = 1 * 2; - public void goobar() - { - goobar(); - } - public int toofoobar(int i, int j) - { - int s = (int)(34); - if (i < 0) - { - } - return toofoobar(i, j); + // properly indented + } + } + + """; + await AssertFormatAsync(expected, code); } - public string parfoobar(string[] str) + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38224")] + public async Task BlockCommentAtTheEndOfLine2() { - for (int i = 0; i < 28; i++) { } - return str[5]; - } -}"; + var code = """ - await AssertFormatAsync(expectedFormattedText, text); - } + using System; - [Fact] - public async Task SpacingFixInTokenBasedForIfAndSwitchCase() - { - var code = @"class Class5{ -void bar() -{ -if(x == 1) -x = 2; else x = 3; -switch (x) { -case 1: break; case 2: break; default: break;} -} -}"; - var expectedCode = @"class Class5 -{ - void bar() - { - if (x == 1) - x = 2; - else x = 3; - switch (x) - { - case 1: break; - case 2: break; - default: break; - } - } -}"; - await AssertFormatAsync(expectedCode, code); - } + class Program + { + static void Main(string[] args) + { + Console.WriteLine(); // this is a comment + /* that I would like to keep */ - [Fact] - public async Task SpacingInDeconstruction() - { - var code = @"class Class5{ -void bar() -{ -var(x,y)=(1,2); -} -}"; - var expectedCode = @"class Class5 -{ - void bar() - { - var (x, y) = (1, 2); - } -}"; + // properly indented + } + } - await AssertFormatAsync(expectedCode, code); - } + """; - [Fact] - public async Task SpacingInNullableTuple() - { - var code = @"class Class5 -{ - void bar() - { - (int, string) ? x = (1, ""hello""); - } -}"; - var expectedCode = @"class Class5 -{ - void bar() - { - (int, string)? x = (1, ""hello""); - } -}"; + var expected = """ - await AssertFormatAsync(expectedCode, code); - } + using System; - [Fact] - public async Task SpacingInTupleArrayCreation() - { - var code = @"class C -{ - void bar() - { - (string a, string b)[] ab = new(string a, string b) [1]; - } -}"; - var expectedCode = @"class C -{ - void bar() - { - (string a, string b)[] ab = new (string a, string b)[1]; - } -}"; + class Program + { + static void Main(string[] args) + { + Console.WriteLine(); // this is a comment + /* that I would like to keep */ - await AssertFormatAsync(expectedCode, code); - } + // properly indented + } + } - [Fact] - public async Task SpacingInTupleArrayCreation2() - { - var code = @"class C -{ - void bar() - { - (string a, string b)[] ab = new( + """; + await AssertFormatAsync(expected, code); } -}"; - var expectedCode = @"class C -{ - void bar() + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38224")] + public async Task BlockCommentAtBeginningOfLine() { - (string a, string b)[] ab = new( - } -}"; + var code = """ - await AssertFormatAsync(expectedCode, code); - } + using System; - [Fact] - public async Task SpacingInImplicitObjectCreation() - { - var code = @"class C -{ - void bar() - { - C a = new (); + class Program + { + static void Main( + int x, // Some comment + /*A*/ int y) + { + } + } + + """; + await AssertFormatAsync(code, code); } -}"; - var expectedCode = @"class C -{ - void bar() + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772311")] + public async Task TestTab() { - C a = new(); - } -}"; + var code = """ - await AssertFormatAsync(expectedCode, code); - } + using System; - [Fact] - public async Task FormatRecursivePattern_Positional() - { - var code = @"class C -{ - void M() { _ = this is ( 1 , 2 ) ; } -}"; - var expectedCode = @"class C -{ - void M() { _ = this is (1, 2); } -}"; + class Program + { + /// + /// This function is the callback used to execute a command when a menu item is clicked. + /// See the Initialize method to see how the menu item is associated to this function using + /// the OleMenuCommandService service and the MenuCommand class. + /// + private void MenuItemCallback(object sender, EventArgs e) { + // Show a Message Box to prove we were here + IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell)); + Guid clsid = Guid.Empty; + int result; + Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox( + 0, + ref clsid, + Rebracer, + string.Format(CultureInfo.CurrentCulture, Inside {0}.MenuItemCallback(), this.ToString()), + string.Empty, + 0, + OLEMSGBUTTON.OLEMSGBUTTON_OK, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, + OLEMSGICON.OLEMSGICON_INFO, + 0, // false + out result)); + } + } - await AssertFormatAsync(expectedCode, code); - } + """; - [Fact] - public async Task FormatRecursivePattern_Positional_Singleline() - { - var code = @"class C -{ - void M() { -_ = this is ( 1 , 2 ) ; } -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is (1, 2); - } -}"; + var expected = """ - await AssertFormatAsync(expectedCode, code); - } + using System; - [Fact] - public async Task FormatRecursivePattern_Positional_Multiline() - { - var code = @"class C -{ - void M() { -_ = this is ( 1 , -2 , -3 ) ; } -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is (1, - 2, - 3); - } -}"; - await AssertFormatAsync(expectedCode, code); - } + class Program + { + /// + /// This function is the callback used to execute a command when a menu item is clicked. + /// See the Initialize method to see how the menu item is associated to this function using + /// the OleMenuCommandService service and the MenuCommand class. + /// + private void MenuItemCallback(object sender, EventArgs e) + { + // Show a Message Box to prove we were here + IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell)); + Guid clsid = Guid.Empty; + int result; + Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox( + 0, + ref clsid, + Rebracer, + string.Format(CultureInfo.CurrentCulture, Inside { 0}.MenuItemCallback(), this.ToString()), + string.Empty, + 0, + OLEMSGBUTTON.OLEMSGBUTTON_OK, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, + OLEMSGICON.OLEMSGICON_INFO, + 0, // false + out result)); + } + } - [Fact] - public async Task FormatRecursivePattern_Positional_Multiline2() - { - var code = @"class C -{ - void M() { -_ = this is ( 1 , -2 , -3 ) ; } -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is (1, - 2, - 3); - } -}"; - await AssertFormatAsync(expectedCode, code); - } + """; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; - [Fact] - public async Task FormatRecursivePattern_Positional_Multiline3() - { - var code = @"class C -{ - void M() { -_ = this is -( 1 , -2 , -3 ) ; } -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is - (1, - 2, - 3); + await AssertFormatAsync(expected, code, changedOptionSet: optionSet); + await AssertFormatAsync(expected, expected, changedOptionSet: optionSet); } -}"; - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task FormatRecursivePattern_Positional_Multiline4() - { - var code = @"class C -{ - void M() { -_ = this is -( 1 , -2 , 3 ) ; } -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task LeaveBlockSingleLine_False() { - _ = this is - (1, - 2, 3); - } -}"; - await AssertFormatAsync(expectedCode, code); - } + var code = """ - [Fact] - public async Task FormatRecursivePattern_Properties_Singleline() - { - var code = @"class C -{ - void M() { _ = this is C{ P1 : 1 } ; } -}"; - var expectedCode = @"class C -{ - void M() { _ = this is C { P1: 1 }; } -}"; + namespace N { class C { int x; } } + """; - await AssertFormatAsync(expectedCode, code); - } + var expected = """ - [Fact] - public async Task FormatRecursivePattern_Properties_Multiline() - { - var code = @"class C -{ - void M() { -_ = this is -{ -P1 : 1 , -P2 : 2 -} ; -} -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is - { - P1: 1, - P2: 2 - }; - } -}"; + namespace N + { + class C + { + int x; + } + } + """; - await AssertFormatAsync(expectedCode, code); - } + var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.WrappingPreserveSingleLine, false } }; + await AssertFormatAsync(expected, code, changedOptionSet: options); + } - [Fact] - public async Task FormatRecursivePattern_Properties_Multiline2() - { - var code = @"class C -{ - void M() { -_ = this is { -P1 : 1 , -P2 : 2 -} ; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task LeaveBlockSingleLine_False2() { - _ = this is - { - P1: 1, - P2: 2 - }; - } -}"; + var code = """ - await AssertFormatAsync(expectedCode, code); - } + class C { void goo() { } } + """; - [Fact] - public async Task FormatRecursivePattern_Properties_Multiline3() - { - var code = @"class C -{ - void M() { -_ = this is { -P1 : 1 , -P2 : 2, P3: 3 -} ; -} -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is - { - P1: 1, - P2: 2, P3: 3 - }; - } -}"; + var expected = """ + + class C + { + void goo() + { + } + } + """; - await AssertFormatAsync(expectedCode, code); - } + var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.WrappingPreserveSingleLine, false } }; + await AssertFormatAsync(expected, code, changedOptionSet: options); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27268")] - public async Task FormatRecursivePattern_NoSpaceBetweenTypeAndPositionalSubpattern() - { - var code = @"class C -{ - void M() { -_ = this is C( 1 , 2 ){} ; } -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task LeaveStatementMethodDeclarationSameLine_False() { - _ = this is C(1, 2) { }; - } -}"; - // no space separates the type and the positional pattern - await AssertFormatAsync(expectedCode, code); - } + var code = """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27268")] - public async Task FormatRecursivePattern_PreferSpaceBetweenTypeAndPositionalSubpattern() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class Program { - { CSharpFormattingOptions2.SpaceAfterMethodCallName, true } - }; - var code = @"class C -{ - void M() { -_ = this is C( 1 , 2 ){} ; } -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is C (1, 2) { }; - } -}"; - await AssertFormatAsync(expectedCode, code, changedOptionSet: changingOptions); - } + void goo() + { + int x = 0; int y = 0; + } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27268")] - public async Task FormatRecursivePattern_PreferSpaceInsidePositionalSubpatternParentheses() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + var expected = """ + + class Program { - { CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, true } - }; - var code = @"class C -{ - void M() { -_ = this is C( 1 , 2 ){} ; -_ = this is C( ){} ; } -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is C( 1, 2 ) { }; - _ = this is C() { }; + void goo() + { + int x = 0; + int y = 0; + } + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - await AssertFormatAsync(expectedCode, code, changedOptionSet: changingOptions); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27268")] - public async Task FormatRecursivePattern_PreferSpaceInsideEmptyPositionalSubpatternParentheses() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses, true } - }; - var code = @"class C -{ - void M() { -_ = this is C( 1 , 2 ){} ; -_ = this is C( ){} ; } -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0000() { - _ = this is C(1, 2) { }; - _ = this is C( ) { }; - } -}"; - await AssertFormatAsync(expectedCode, code, changedOptionSet: changingOptions); - } + var code = """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/34683")] - public async Task FormatRecursivePattern_InBinaryOperation() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class Program { - { CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, true } - }; - var code = @"class C -{ - void M() - { - return - typeWithAnnotations is { } && true; - } -}"; - var expectedCode = code; - await AssertFormatAsync(expectedCode, code, changedOptionSet: changingOptions); - } + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; - [Fact] - public async Task FormatPropertyPattern_MultilineAndEmpty() - { - var code = @"class C -{ - void M() { -_ = this is + var expected = """ + + class Program { - }; -} -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is + int[] x; + int[,] y; + int[,,] z = new int[1,2,3]; + var a = new[] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, false }, }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - await AssertFormatAsync(expectedCode, code); - } - - [Fact] - public async Task FormatSwitchExpression_IndentArms() - { - var code = @"class C -{ - void M() { -_ = this switch -{ -{ P1: 1} => true, -(0, 1) => true, -_ => false -}; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0001() { - _ = this switch + var code = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; + + var expected = """ + + class Program + { + int[] x; + int[,] y; + int[,,] z = new int[1, 2, 3]; + var a = new[] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - { P1: 1 } => true, - (0, 1) => true, - _ => false + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, true }, }; - + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task FormatPropertyPattern_FollowedByInvocation() - { - var code = @"class C -{ - void M() { -_ = this is { } -M(); -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0010() { - _ = this is { } - M(); - } -}"; - // although 'M' will be parsed into the pattern on line above, we should not wrap the pattern - await AssertFormatAsync(expectedCode, code); - } + var code = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; + + var expected = """ + + class Program + { + int[] x; + int[,] y; + int[,,] z = new int[1 ,2 ,3]; + var a = new[] { 0 }; + } + """; - [Fact] - public async Task FormatPositionalPattern_FollowedByInvocation() + var options = new OptionsCollection(LanguageNames.CSharp) { - var code = @"class C -{ - void M() { -_ = this is (1, 2) { } -M(); -} -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this is (1, 2) { } - M(); + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, false }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - // although 'M' will be parsed into the pattern on line above, we should not wrap the pattern - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task FormatPositionalPattern_FollowedByScope() - { - var code = @"class C -{ - void M() { -_ = this is (1, 2) -{ - M(); -} -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0011() { - _ = this is (1, 2) + var code = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; + + var expected = """ + + class Program + { + int[] x; + int[,] y; + int[,,] z = new int[1 , 2 , 3]; + var a = new[] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - M(); + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, true }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -} -}"; - // You should not invoke Format on incomplete code and expect nice results - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task FormatSwitchExpression_MultilineAndNoArms() - { - var code = @"class C -{ - void M() { -_ = this switch -{ - }; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0100() { - _ = this switch + var code = """ + + class Program + { + int[ ] x; + int[, ] y; + int[, , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; + + var expected = """ + + class Program + { + int[] x; + int[,] y; + int[,,] z = new int[ 1,2,3 ]; + var a = new[] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, false }, }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - await AssertFormatAsync(expectedCode, code); - } - - [Fact] - public async Task FormatSwitchExpression_ExpressionAnchoredToArm() - { - var code = @"class C -{ - void M() { -_ = this switch -{ -{ P1: 1} -=> true, -(0, 1) - => true, -_ - => false -}; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0101() { - _ = this switch - { - { P1: 1 } - => true, - (0, 1) - => true, - _ - => false - }; + var code = """ - } -}"; - await AssertFormatAsync(expectedCode, code); - } + class Program + { + int[ ] x; + int[, ] y; + int[, , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; - [Fact] - public async Task FormatSwitchExpression_NoSpaceBeforeColonInArm() - { - var code = @"class C -{ - void M() { -_ = this switch -{ -{ P1: 1} -=> true, -(0, 1) - => true, -_ - => false -}; + var expected = """ -} -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this switch + class Program + { + int[] x; + int[,] y; + int[,,] z = new int[ 1, 2, 3 ]; + var a = new[] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - { P1: 1 } - => true, - (0, 1) - => true, - _ - => false + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, true }, }; - + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - await AssertFormatAsync(expectedCode, code); - } - - [Fact] - public async Task FormatSwitchExpression_ArmCommaWantsNewline() - { - var code = @"class C -{ - void M() { -_ = this switch -{ -{ P1: 1} => true, -(0, 1) => true, _ => false -}; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0110() { - _ = this switch - { - { P1: 1 } => true, - (0, 1) => true, - _ => false - }; + var code = """ - } -}"; - await AssertFormatAsync(expectedCode, code); - } + class Program + { + int[ ] x; + int[, ] y; + int[, , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; - [Fact] - public async Task FormatSwitchExpression_ArmCommaPreservesLines() - { - var code = @"class C -{ - void M() { -_ = this switch -{ -{ P1: 1} => true, + var expected = """ -(0, 1) => true, _ => false -}; + class Program + { + int[] x; + int[,] y; + int[,,] z = new int[ 1 ,2 ,3 ]; + var a = new[] { 0 }; + } + """; -} -}"; - var expectedCode = @"class C -{ - void M() - { - _ = this switch + var options = new OptionsCollection(LanguageNames.CSharp) { - { P1: 1 } => true, - - (0, 1) => true, - _ => false + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, false }, }; - + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - await AssertFormatAsync(expectedCode, code); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33839")] - public async Task FormatSwitchExpression_ExpressionBody() - { - var code = @" -public class Test -{ - public object Method(int i) - => i switch -{ -1 => 'a', -2 => 'b', -_ => null, -}; -}"; - var expectedCode = @" -public class Test -{ - public object Method(int i) - => i switch - { - 1 => 'a', - 2 => 'b', - _ => null, - }; -}"; + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0111() + { + var code = """ - await AssertFormatAsync(expectedCode, code); - } + class Program + { + int[ ] x; + int[, ] y; + int[, , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/72196")] - [InlineData("[]")] - [InlineData("[a]")] - [InlineData("[a, b]")] - [InlineData("[..]")] - [InlineData("[var a, .., var b]")] - [InlineData("[{ } a, null]")] - [InlineData("[a, []]")] - public async Task FormatSwitchExpression_ListPatternAligned(string listPattern) - { - var code = $$""" - class C - { - void M() - { - _ = Array.Empty() switch - { - {{listPattern}} => 0, - _ => 1, - }; - } - } - """; - var expectedCode = $$""" - class C - { - void M() - { - _ = Array.Empty() switch - { - {{listPattern}} => 0, - _ => 1, - }; - } - } - """; - await AssertFormatAsync(expectedCode, code); - } + var expected = """ - [Fact] - public async Task FormatSwitchWithPropertyPattern() - { - var code = @"class C -{ - void M() - { - switch (this) + class Program + { + int[] x; + int[,] y; + int[,,] z = new int[ 1 , 2 , 3 ]; + var a = new[] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - case { P1: 1, P2: { P3: 3, P4: 4 } }: - break; - } + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, true }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - var expectedCode = @"class C -{ - void M() + + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1000() { - switch (this) + var code = """ + + class Program + { + int[] x; + int[ ,] y; + int[ , ,] z = new int[1,2,3]; + var a = new[] { 0 }; + } + """; + + var expected = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - case { P1: 1, P2: { P3: 3, P4: 4 } }: - break; - } + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, false }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task FormatSwitchWithPropertyPattern_Singleline() - { - var code = @"class C -{ - void M() + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1001() { - switch (this) + var code = """ + + class Program + { + int[] x; + int[ ,] y; + int[ , ,] z = new int[1,2,3]; + var a = new[] { 0 }; + } + """; + + var expected = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1, 2, 3]; + var a = new[ ] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - case { P1: 1, P2: { P3: 3, P4: 4 } }: break; - } + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, true }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - var expectedCode = @"class C -{ - void M() + + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1010() { - switch (this) - { - case { P1: 1, P2: { P3: 3, P4: 4 } }: break; - } - } -}"; + var code = """ - await AssertFormatAsync(expectedCode, code); - } + class Program + { + int[] x; + int[ ,] y; + int[ , ,] z = new int[1,2,3]; + var a = new[] { 0 }; + } + """; + + var expected = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1 ,2 ,3]; + var a = new[ ] { 0 }; + } + """; - [Fact] - public async Task FormatSwitchWithPropertyPattern_Singleline2() - { - var code = @"class C -{ - void M() - { - switch (this) + var options = new OptionsCollection(LanguageNames.CSharp) { - case { P1: 1, P2: { P3: 3, P4: 4 } }: System.Console.Write(1); - break; - } + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, false }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - var expectedCode = @"class C -{ - void M() + + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1011() { - switch (this) - { - case { P1: 1, P2: { P3: 3, P4: 4 } }: - System.Console.Write(1); - break; - } - } -}"; - await AssertFormatAsync(expectedCode, code); - } + var code = """ - [Fact] - public async Task SpacingInTupleExtension() - { - var code = @"static class Class5 -{ - static void Extension(this(int, string) self) { } -}"; - var expectedCode = @"static class Class5 -{ - static void Extension(this (int, string) self) { } -}"; + class Program + { + int[] x; + int[ ,] y; + int[ , ,] z = new int[1,2,3]; + var a = new[] { 0 }; + } + """; - await AssertFormatAsync(expectedCode, code); - } + var expected = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1 , 2 , 3]; + var a = new[ ] { 0 }; + } + """; - [Fact] - public async Task SpacingInNestedDeconstruction() + var options = new OptionsCollection(LanguageNames.CSharp) { - var code = @"class Class5{ -void bar() -{ -( int x1 , var( x2,x3 ) )=(1,(2,3)); -} -}"; - var expectedCode = @"class Class5 -{ - void bar() - { - (int x1, var (x2, x3)) = (1, (2, 3)); + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, true }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - await AssertFormatAsync(expectedCode, code); - } + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1100() + { + var code = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; - [Fact] - public async Task SpacingInSuppressNullableWarningExpression() + var expected = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[ 1,2,3 ]; + var a = new[ ] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - var code = -@"class C -{ - static object F() - { - object? o[] = null; - object? x = null; - object? y = null; - return x ! ?? (y) ! ?? o[0] !; + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, false }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - var expectedCode = -@"class C -{ - static object F() + + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1101() { - object? o[] = null; - object? x = null; - object? y = null; - return x! ?? (y)! ?? o[0]!; - } -}"; + var code = """ - await AssertFormatAsync(expectedCode, code); - } + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; + + var expected = """ + + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[ 1, 2, 3 ]; + var a = new[ ] { 0 }; + } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545335")] - public async Task PreprocessorOnSameLine() + var options = new OptionsCollection(LanguageNames.CSharp) { - var code = @"class C -{ -}#line default + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, true }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); + } -#line hidden"; + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1110() + { + var code = """ - var expected = @"class C -{ -}#line default + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; -#line hidden"; + var expected = """ - await AssertFormatAsync(expected, code); - } + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[ 1 ,2 ,3 ]; + var a = new[ ] { 0 }; + } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545626")] - public async Task ArraysInAttributes() + var options = new OptionsCollection(LanguageNames.CSharp) { - var code = @"[A(X = new int[] { 1 })] -public class A : Attribute -{ - public int[] X; -}"; + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, false }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); + } - var expected = @"[A(X = new int[] { 1 })] -public class A : Attribute -{ - public int[] X; -}"; + [Fact] + public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1111() + { + var code = """ - await AssertFormatAsync(expected, code); - } + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[1,2,3]; + var a = new[ ] { 0 }; + } + """; + + var expected = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530580")] - public async Task NoNewLineAfterBraceInExpression() + class Program + { + int[ ] x; + int[ , ] y; + int[ , , ] z = new int[ 1 , 2 , 3 ]; + var a = new[ ] { 0 }; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - var code = @"public class A -{ - void Method() - { - var po = cancellationToken.CanBeCanceled ? - new ParallelOptions() { CancellationToken = cancellationToken } : - defaultParallelOptions; + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, true }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - var expected = @"public class A -{ - void Method() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14128")] + public async Task SpaceBeforeCommasInLocalFunctionParameters() { - var po = cancellationToken.CanBeCanceled ? - new ParallelOptions() { CancellationToken = cancellationToken } : - defaultParallelOptions; - } -}"; + var code = """ - await AssertFormatAsync(expected, code); - } + class Program + { + void Goo() + { + void LocalFunction(int i, string s) + { + } + } + } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530580")] - public async Task NoIndentForNestedUsingWithoutBraces() - { - var code = @"class C -{ -void M() -{ -using (null) -using (null) -{ -} -} -} -"; + var expected = """ - var expected = @"class C -{ - void M() - { - using (null) - using (null) + class Program + { + void Goo() + { + void LocalFunction(int i , string s) + { + } + } + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { - } + { SpaceBeforeComma, true }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -} -"; - - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530580")] - public async Task NoIndentForNestedUsingWithoutBraces2() - { - var code = @"class C -{ - void M() + [Fact] + public async Task ArrayDeclarationShouldFollowEmptySquareBrackets() { - using (null) - using (null) - using (null) + const string code = """ + + class Program { + var t = new Goo(new[ ] { "a", "b" }); } - } -} -"; + """; - var expected = @"class C -{ - void M() - { - using (null) - using (null) - using (null) - { - } - } -} -"; + const string expected = """ - await AssertFormatAsync(expected, code); - } + class Program + { + var t = new Goo(new[] { "a", "b" }); + } + """; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530580")] - public async Task NoIndentForNestedUsingWithoutBraces3() - { - var code = @"class C -{ - void M() - { - using (null) - using (null) - using (null) + var options = new OptionsCollection(LanguageNames.CSharp) { - } + { CSharpFormattingOptions2.SpaceWithinSquareBrackets, true }, + { CSharpFormattingOptions2.SpaceBetweenEmptySquareBrackets, false } + }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -} -"; - var expected = @"class C -{ - void M() + [Fact] + public async Task SquareBracesBefore_True() { - using (null) - using (null) - using (null) - { - } + var code = """ + + class Program + { + int[] x; + } + """; + + var expected = """ + + class Program + { + int [] x; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.SpaceBeforeOpenSquareBracket, true } }; + await AssertFormatAsync(expected, code, changedOptionSet: options); } -} -"; - await AssertFormatAsync(expected, code); - } + [Fact] + public async Task SquareBracesAndValue_True() + { + var code = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546678")] - public async Task UnicodeWhitespace() - { - var code = "\u001A"; + class Program + { + int[3] x; + } + """; - await AssertFormatAsync("", code); - } + var expected = """ - [Fact, WorkItem(17431, "DevDiv_Projects/Roslyn")] - public async Task NoElasticRuleOnRegularFile() - { - var code = @"class Consumer -{ - public int P + class Program + { + int[ 3 ] x; + } + """; + + var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.SpaceWithinSquareBrackets, true } }; + await AssertFormatAsync(expected, code, changedOptionSet: options); + } + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/917351")] + public async Task TestLockStatement() { + var code = """ + + class Program + { + public void Method() + { + lock (expression) + { + // goo + } } -}"; + } + """; - var expected = @"class Consumer -{ - public int P - { - } -}"; + var expected = """ - await AssertFormatAsync(expected, code); - } + class Program + { + public void Method() + { + lock (expression) { + // goo + } + } + } + """; - [Fact, WorkItem(584599, "DevDiv_Projects/Roslyn")] - public async Task CaseSection() - { - var code = @"class C -{ - void Method() - { - switch(i) + var options = new OptionsCollection(LanguageNames.CSharp) { - // test1 - case 1: - // test2 - case 2: - // test3 - int i2 = 10; - // test 4 - case 4: -// test 5 - } + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, false) } + }; + + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - var expected = @"class C -{ - void Method() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/962416")] + public async Task TestCheckedAndUncheckedStatement() { - switch (i) - { - // test1 - case 1: - // test2 - case 2: - // test3 - int i2 = 10; - // test 4 - case 4: - // test 5 - } - } -}"; + var code = """ - await AssertFormatAsync(expected, code); - } + class Program + { + public void Method() + { + checked + { + // goo + } + unchecked + { + } + } + } + """; - [Fact, WorkItem(553654, "DevDiv_Projects/Roslyn")] - public async Task Bugfix_553654_LabelStatementIndenting() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + var expected = """ + + class Program { - { CSharpFormattingOptions2.LabelPositioning, LabelPositionOptions.LeftMost } - }; + public void Method() + { + checked { + // goo + } + unchecked { + } + } + } + """; - var code = @"class Program -{ - void F() - { - foreach (var x in new int[] { }) + var options = new OptionsCollection(LanguageNames.CSharp) { - goo: - int a = 1; - } + { NewLineBeforeOpenBrace , NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, false) } + }; + + await AssertFormatAsync(expected, code, changedOptionSet: options); } -}"; - var expected = @"class Program -{ - void F() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/953535")] + public async Task ConditionalMemberAccess() { - foreach (var x in new int[] { }) - { -goo: - int a = 1; - } + var code = """ + + using System; + class A + { + public A a; + } + + class Program + { + static void Main(string[] args) + { + A a = null; + A ?.a = null; + System.Console.WriteLine(args ?[0]); + System.Console.WriteLine(args ?.Length); + } + } + """; + + var expected = """ + + using System; + class A + { + public A a; + } + + class Program + { + static void Main(string[] args) + { + A a = null; + A?.a = null; + System.Console.WriteLine(args?[0]); + System.Console.WriteLine(args?.Length); + } + } + """; + var parseOptions = new CSharpParseOptions(); + await AssertFormatAsync(expected, code, parseOptions: parseOptions); } -}"; - await AssertFormatAsync(expected, code, changingOptions); - } - [Fact, WorkItem(707064, "DevDiv_Projects/Roslyn")] - public async Task Bugfix_707064_SpaceAfterSecondSemiColonInFor() - { - var code = @"class Program -{ - void F() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/924172")] + public async Task IgnoreSpacesInDeclarationStatementEnabled() { - for (int i = 0; i < 5;) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - } + { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, true } + }; + var code = """ + + class Program + { + static void Main(string[] args) + { + int s; + } + } + """; + + var expected = """ + + class Program + { + static void Main(string[] args) + { + int s; + } + } + """; + await AssertFormatAsync(expected, code, changedOptionSet: changingOptions); } -}"; - var expected = @"class Program -{ - void F() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/899492")] + public async Task CommentIsLeadingTriviaOfStatementNotLabel() { - for (int i = 0; i < 5;) - { - } + var code = """ + + class C + { + void M() + { + label: + // comment + M(); + M(); + } + } + """; + + var expected = """ + + class C + { + void M() + { + label: + // comment + M(); + M(); + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772313")] - public async Task Bugfix_772313_ReturnKeywordBeforeQueryClauseDoesNotTriggerNewLineOnFormat() - { - var code = @"class C -{ - int M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991547")] + public async Task DoNotWrappingTryCatchFinallyIfOnSingleLine() { - return from c in "" - select c; + var code = """ + + class C + { + void M() + { + try { } + catch { } + finally { } + } + } + """; + + var expected = """ + + class C + { + void M() + { + try { } + catch { } + finally { } + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - var expected = @"class C -{ - int M() + [Fact] + public async Task InterpolatedStrings1() { - return from c in "" - select c; - } -}"; - await AssertFormatAsync(expected, code); - } + var code = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772304")] - public async Task Bugfix_772313_PreserveMethodParameterIndentWhenAttributePresent() - { - var code = @"class C -{ - void M - ( - [In] - bool b - ); -} + class C + { + void M() + { + var a = "World"; + var b = $"Hello, {a}"; + } + } + """; -class C -{ - void M - ( - [In] - List b - ); -} + var expected = """ -class C -{ - void M - ( - [In] - [In, In] - List b - ); -}"; - - var expected = @"class C -{ - void M - ( - [In] - bool b - ); -} + class C + { + void M() + { + var a = "World"; + var b = $"Hello, {a}"; + } + } + """; -class C -{ - void M - ( - [In] - List b - ); -} + await AssertFormatAsync(expected, code); + } -class C -{ - void M - ( - [In] - [In, In] - List b - ); -}"; - await AssertFormatAsync(expected, code); - } + [Fact] + public async Task InterpolatedStrings2() + { + var code = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/776513")] - public async Task Bugfix_776513_CheckBraceIfNotMissingBeforeApplyingOperationForBracedBlocks() - { - var code = @"var alwaysTriggerList = new[] - Dim triggerOnlyWithLettersList ="; + class C + { + void M() + { + var a = "Hello"; + var b = "World"; + var c = $"{a}, {b}"; + } + } + """; - var expected = @"var alwaysTriggerList = new[] - Dim triggerOnlyWithLettersList ="; - await AssertFormatAsync(expected, code); - } + var expected = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/769342")] - public async Task ShouldFormatDocCommentWithIndentSameAsTabSizeWithUseTabTrue() - { - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + class C + { + void M() + { + var a = "Hello"; + var b = "World"; + var c = $"{a}, {b}"; + } + } + """; - await AssertFormatAsync(@"namespace ConsoleApplication1 -{ - /// - /// fka;jsgdflkhsjflgkhdsl; - /// - class Program - { - } -}", @"namespace ConsoleApplication1 -{ - /// - /// fka;jsgdflkhsjflgkhdsl; - /// - class Program - { + await AssertFormatAsync(expected, code); } -}", changedOptionSet: optionSet); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/797278")] - public async Task TestSpacingOptionAroundControlFlow() - { - const string code = @" -class Program -{ - public void goo() + [Fact] + public async Task InterpolatedStrings3() { - int i; - for(i=0; i<10; i++) - {} + var code = """ - foreach(i in new[] {1,2,3}) - {} + class C + { + void M() + { + var a = "World"; + var b = $"Hello, { a }"; + } + } + """; - if (i==10) - {} + var expected = """ - while(i==10) - {} + class C + { + void M() + { + var a = "World"; + var b = $"Hello, {a}"; + } + } + """; - switch(i) - { - default: break; - } + await AssertFormatAsync(expected, code); + } - do {} while (true); + [Fact] + public async Task InterpolatedRawStrings3() + { + var code = """" - try - { } - catch (System.Exception) - { } - catch (System.Exception e) when (true) - { } + class C + { + void M() + { + var a = "World"; + var b = $"""Hello, { a }"""; + } + } + """"; - using(somevar) - { } + var expected = """" - lock(somevar) - { } + class C + { + void M() + { + var a = "World"; + var b = $"""Hello, {a}"""; + } + } + """"; - fixed(char* p = str) - { } + await AssertFormatAsync(expected, code); } -}"; - const string expected = @" -class Program -{ - public void goo() - { - int i; - for ( i = 0; i < 10; i++ ) - { } - foreach ( i in new[] { 1, 2, 3 } ) - { } + [Fact] + public async Task InterpolatedStrings4() + { + var code = """ - if ( i == 10 ) - { } + class C + { + void M() + { + var a = "Hello"; + var b = "World"; + var c = $"{ a }, { b }"; + } + } + """; - while ( i == 10 ) - { } + var expected = """ - switch ( i ) - { - default: break; - } + class C + { + void M() + { + var a = "Hello"; + var b = "World"; + var c = $"{a}, {b}"; + } + } + """; - do { } while ( true ); + await AssertFormatAsync(expected, code); + } - try - { } - catch ( System.Exception ) - { } - catch ( System.Exception e ) when ( true ) - { } + [Fact] + public async Task InterpolatedStrings5() + { + var code = """ - using ( somevar ) - { } + class C + { + void M() + { + var a = "World"; + var b = $@"Hello, {a}"; + } + } + """; - lock ( somevar ) - { } + var expected = """ - fixed ( char* p = str ) - { } - } -}"; - var optionSet = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBetweenParentheses, SpaceBetweenParentheses.DefaultValue.WithFlagValue( SpacePlacementWithinParentheses.ControlFlowStatements, true) }, - }; + void M() + { + var a = "World"; + var b = $@"Hello, {a}"; + } + } + """; - await AssertFormatAsync(expected, code, changedOptionSet: optionSet); - } + await AssertFormatAsync(expected, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37031")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/176345")] - public async Task TestSpacingOptionAfterControlFlowKeyword() - { - var code = @" -class Program -{ - public void goo() + [Fact] + public async Task InterpolatedStrings6() { - int i; - for (i=0; i<10; i++) - {} + var code = """ - foreach (i in new[] {1,2,3}) - {} + class C + { + void M() + { + var a = "Hello"; + var b = "World"; + var c = $@"{a}, {b}"; + } + } + """; - if (i==10) - {} + var expected = """ - while (i==10) - {} + class C + { + void M() + { + var a = "Hello"; + var b = "World"; + var c = $@"{a}, {b}"; + } + } + """; - switch (i) - { - default: break; - } + await AssertFormatAsync(expected, code); + } - do {} while (true); + [Fact] + public async Task InterpolatedStrings7() + { + var code = """ - try - { } - catch (System.Exception e) when (true) - { } + class C + { + void M() + { + var a = "World"; + var b = $@"Hello, { a }"; + } + } + """; - using (somevar) - { } + var expected = """ - lock (somevar) - { } + class C + { + void M() + { + var a = "World"; + var b = $@"Hello, {a}"; + } + } + """; - fixed (somevar) - { } + await AssertFormatAsync(expected, code); } -}"; - var expected = @" -class Program -{ - public void goo() + + [Fact] + public async Task InterpolatedStrings8() { - int i; - for(i = 0; i < 10; i++) - { } + var code = """ - foreach(i in new[] { 1, 2, 3 }) - { } + class C + { + void M() + { + var a = "Hello"; + var b = "World"; + var c = $@"{ a }, { b }"; + } + } + """; - if(i == 10) - { } + var expected = """ - while(i == 10) - { } + class C + { + void M() + { + var a = "Hello"; + var b = "World"; + var c = $@"{a}, {b}"; + } + } + """; - switch(i) - { - default: break; - } + await AssertFormatAsync(expected, code); + } - do { } while(true); + [Fact] + public async Task InterpolatedStrings9() + { + var code = """ - try - { } - catch(System.Exception e) when(true) - { } + class C + { + void M() + { + var a = "Hello"; + var c = $"{ a }, World"; + } + } + """; - using(somevar) - { } + var expected = """ - lock(somevar) - { } + class C + { + void M() + { + var a = "Hello"; + var c = $"{a}, World"; + } + } + """; - fixed(somevar) - { } + await AssertFormatAsync(expected, code); } -}"; - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.SpaceAfterControlFlowStatementKeyword, false } }; - await AssertFormatAsync(expected, code, changedOptionSet: optionSet); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/766212")] - public async Task TestOptionForSpacingAroundCommas() - { - var code = @" -class Program -{ - public void Main() - { - var a = new[] {1,2,3}; - var digits = new List {1,2,3,4}; - } -}"; - var expectedDefault = @" -class Program -{ - public void Main() + [Fact] + public async Task InterpolatedStrings10() { - var a = new[] { 1, 2, 3 }; - var digits = new List { 1, 2, 3, 4 }; - } -}"; - await AssertFormatAsync(expectedDefault, code); + var code = """ - var expectedAfterCommaDisabled = @" -class Program -{ - public void Main() - { - var a = new[] { 1,2,3 }; - var digits = new List { 1,2,3,4 }; + class C + { + void M() + { + var s = $"{42 , -4 :x}"; + } + } + """; + + var expected = """ + + class C + { + void M() + { + var s = $"{42,-4:x}"; + } + } + """; + + await AssertFormatAsync(expected, code); } -}"; - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.SpaceAfterComma, false } }; - await AssertFormatAsync(expectedAfterCommaDisabled, code, changedOptionSet: optionSet); - var expectedBeforeCommaEnabled = @" -class Program -{ - public void Main() + [Fact] + public async Task InterpolatedRawStrings10() { - var a = new[] { 1 ,2 ,3 }; - var digits = new List { 1 ,2 ,3 ,4 }; + var code = """" + + class C + { + void M() + { + var s = $"""{42 , -4 :x}"""; + } + } + """"; + + var expected = """" + + class C + { + void M() + { + var s = $"""{42,-4:x}"""; + } + } + """"; + + await AssertFormatAsync(expected, code); } -}"; - optionSet.Add(CSharpFormattingOptions2.SpaceBeforeComma, true); - await AssertFormatAsync(expectedBeforeCommaEnabled, code, changedOptionSet: optionSet); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772308")] - public async Task Bugfix_772308_SeparateSuppressionForEachCaseLabelEvenIfEmpty() - { - var code = @" -class C -{ - int M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59811")] + public async Task InterpolatedStrings11() { - switch (1) - { - case 1: return 1; - case 2: return 2; - case 3: - case 4: return 4; - default: - } + var code = """ + + class C + { + void M() + { + var hostAddress = "host"; + var nasTypeId = "nas"; + var version = "1.2"; + var c = $"{ hostAddress?? ""}/{nasTypeId }/{version??""}"; + } + } + """; + + var expected = """ + + class C + { + void M() + { + var hostAddress = "host"; + var nasTypeId = "nas"; + var version = "1.2"; + var c = $"{hostAddress ?? ""}/{nasTypeId}/{version ?? ""}"; + } + } + """; + + await AssertFormatAsync(expected, code); } -} -"; - var expected = @" -class C -{ - int M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59811")] + public async Task InterpolatedStrings12() { - switch (1) - { - case 1: return 1; - case 2: return 2; - case 3: - case 4: return 4; - default: - } - } -} -"; - await AssertFormatAsync(expected, code); - } + var code = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/844913")] - public async Task QueryExpressionInExpression() - { - var code = @" -class C -{ - public void CreateSettingsFile(string path, string comment) { - var xml = new XDocument( - new XDeclaration(1.0, utf8, yes), - new XComment(comment), - new XElement(UserSettings, - new XElement(ToolsOptions, - from t in KnownSettings.DefaultCategories - group t by t.Item1 into cat - select new XElement(ToolsOptionsCategory, - new XAttribute(name, cat.Key), - cat.Select(sc => new XElement(ToolsOptionsSubCategory, new XAttribute(name, sc.Item2))) - ) - ) - ) - ); - UpdateSettingsXml(xml); - xml.Save(path); - SettingsPath = path; - } - } -"; + class C + { + void M() + { + var a = 1.2M; + var c = $"{ a : 000.00 }"; + } + } + """; - var expected = @" -class C -{ - public void CreateSettingsFile(string path, string comment) - { - var xml = new XDocument( - new XDeclaration(1.0, utf8, yes), - new XComment(comment), - new XElement(UserSettings, - new XElement(ToolsOptions, - from t in KnownSettings.DefaultCategories - group t by t.Item1 into cat - select new XElement(ToolsOptionsCategory, - new XAttribute(name, cat.Key), - cat.Select(sc => new XElement(ToolsOptionsSubCategory, new XAttribute(name, sc.Item2))) - ) - ) - ) - ); - UpdateSettingsXml(xml); - xml.Save(path); - SettingsPath = path; - } -} -"; - await AssertFormatAsync(expected, code); - } + var expected = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/843479")] - public async Task EmbeddedStatementElse() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class C { - { CSharpFormattingOptions2.NewLineForElse, false } - }; + void M() + { + var a = 1.2M; + var c = $"{a: 000.00 }"; + } + } + """; - var code = @" -class C -{ - void Method() - { - if (true) - Console.WriteLine(); else - Console.WriteLine(); + await AssertFormatAsync(expected, code); } -} -"; - var expected = @" -class C -{ - void Method() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59811")] + public async Task InterpolatedStrings13() { - if (true) - Console.WriteLine(); - else - Console.WriteLine(); - } -} -"; - await AssertFormatAsync(expected, code, changingOptions); - } + var code = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772311")] - public async Task LineCommentAtTheEndOfLine() - { - var code = @" -using System; + class C + { + void M() + { + var a = 1.2M; + var c = $"{ (a > 2?"a":"b"}"; + } + } + """; -class Program -{ - static void Main(string[] args) - { - Console.WriteLine(); // this is a comment - // that I would like to keep + var expected = """ - // properly indented - } -} -"; + class C + { + void M() + { + var a = 1.2M; + var c = $"{(a > 2 ? "a" : "b"}"; + } + } + """; - var expected = @" -using System; + await AssertFormatAsync(expected, code); + } -class Program -{ - static void Main(string[] args) + [Fact] + public async Task InterpolatedStrings14() { - Console.WriteLine(); // this is a comment - // that I would like to keep + var code = """ + + class C + { + void M() + { + var s = $"{ 42 , -4 :x}"; + } + } + """; + + var expected = """ + + class C + { + void M() + { + var s = $"{42,-4:x}"; + } + } + """; - // properly indented + await AssertFormatAsync(expected, code); } -} -"; - await AssertFormatAsync(expected, code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38224")] - public async Task BlockCommentAtTheEndOfLine1() - { - var code = @" -using System; -class Program -{ - static void Main(string[] args) + [Fact] + public async Task InterpolatedStrings15() { - Console.WriteLine(); /* this is a comment */ - // that I would like to keep + var code = """ - // properly indented - } -} -"; + class C + { + void M() + { + var s = $"{ 42 , -4 }"; + } + } + """; - var expected = @" -using System; + var expected = """ -class Program -{ - static void Main(string[] args) - { - Console.WriteLine(); /* this is a comment */ - // that I would like to keep + class C + { + void M() + { + var s = $"{42,-4}"; + } + } + """; - // properly indented + await AssertFormatAsync(expected, code); } -} -"; - await AssertFormatAsync(expected, code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38224")] - public async Task BlockCommentAtTheEndOfLine2() - { - var code = @" -using System; -class Program -{ - static void Main(string[] args) + [Fact] + public async Task InterpolatedStrings16() { - Console.WriteLine(); // this is a comment - /* that I would like to keep */ + var code = """ - // properly indented - } -} -"; + class C + { + void M() + { + var s = $"{ 42 , -4 : x }"; + } + } + """; - var expected = @" -using System; + var expected = """ -class Program -{ - static void Main(string[] args) - { - Console.WriteLine(); // this is a comment - /* that I would like to keep */ + class C + { + void M() + { + var s = $"{42,-4: x }"; + } + } + """; - // properly indented + await AssertFormatAsync(expected, code); } -} -"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38224")] - public async Task BlockCommentAtBeginningOfLine() - { - var code = @" -using System; - -class Program -{ - static void Main( - int x, // Some comment - /*A*/ int y) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1151")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1041787")] + public async Task ReconstructWhitespaceStringUsingTabs_SingleLineComment() { - } -} -"; - await AssertFormatAsync(code, code); - } + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + await AssertFormatAsync(""" + using System; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772311")] - public async Task TestTab() - { - var code = @" -using System; + class Program + { + static void Main(string[] args) + { + Console.WriteLine(""); // GooBar + } + } + """, """ + using System; -class Program -{ - /// - /// This function is the callback used to execute a command when a menu item is clicked. - /// See the Initialize method to see how the menu item is associated to this function using - /// the OleMenuCommandService service and the MenuCommand class. - /// - private void MenuItemCallback(object sender, EventArgs e) { - // Show a Message Box to prove we were here - IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell)); - Guid clsid = Guid.Empty; - int result; - Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox( - 0, - ref clsid, - Rebracer, - string.Format(CultureInfo.CurrentCulture, Inside {0}.MenuItemCallback(), this.ToString()), - string.Empty, - 0, - OLEMSGBUTTON.OLEMSGBUTTON_OK, - OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, - OLEMSGICON.OLEMSGICON_INFO, - 0, // false - out result)); - } + class Program + { + static void Main(string[] args) + { + Console.WriteLine(""); // GooBar + } + } + """, optionSet); } -"; - - var expected = @" -using System; -class Program -{ - /// - /// This function is the callback used to execute a command when a menu item is clicked. - /// See the Initialize method to see how the menu item is associated to this function using - /// the OleMenuCommandService service and the MenuCommand class. - /// - private void MenuItemCallback(object sender, EventArgs e) - { - // Show a Message Box to prove we were here - IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell)); - Guid clsid = Guid.Empty; - int result; - Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox( - 0, - ref clsid, - Rebracer, - string.Format(CultureInfo.CurrentCulture, Inside { 0}.MenuItemCallback(), this.ToString()), - string.Empty, - 0, - OLEMSGBUTTON.OLEMSGBUTTON_OK, - OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST, - OLEMSGICON.OLEMSGICON_INFO, - 0, // false - out result)); - } -} -"; - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1151")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/961559")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1041787")] + public async Task ReconstructWhitespaceStringUsingTabs_MultiLineComment() + { + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + await AssertFormatAsync(""" + using System; - await AssertFormatAsync(expected, code, changedOptionSet: optionSet); - await AssertFormatAsync(expected, expected, changedOptionSet: optionSet); - } + class Program + { + static void Main(string[] args) + { + Console.WriteLine(""); /* GooBar */ + } + } + """, """ + using System; - [Fact] - public async Task LeaveBlockSingleLine_False() - { - var code = @" -namespace N { class C { int x; } }"; + class Program + { + static void Main(string[] args) + { + Console.WriteLine(""); /* GooBar */ + } + } + """, optionSet); + } - var expected = @" -namespace N -{ - class C + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1100920")] + public async Task NoLineOperationAroundInterpolationSyntax() { - int x; + await AssertFormatAsync(""" + class Program + { + static string F(int a, int b, int c) + { + return $"{a} (index: 0x{b}, size: {c}): " + } + } + """, """ + class Program + { + static string F(int a, int b, int c) + { + return $"{a} (index: 0x{ b}, size: { c}): " + } + } + """); } -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.WrappingPreserveSingleLine, false } }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } - - [Fact] - public async Task LeaveBlockSingleLine_False2() - { - var code = @" -class C { void goo() { } }"; - var expected = @" -class C -{ - void goo() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62")] + public async Task SpaceAfterWhenInExceptionFilter() { - } -}"; + const string expected = """ + class C + { + void M() + { + try + { + if (x) + { + G(); + } + } + catch (Exception e) when (H(e)) + { - var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.WrappingPreserveSingleLine, false } }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + } + } + } + """; - [Fact] - public async Task LeaveStatementMethodDeclarationSameLine_False() - { - var code = @" -class Program -{ - void goo() - { - int x = 0; int y = 0; + const string code = """ + class C + { + void M() + { + try + { + if(x){ + G(); + } + } + catch(Exception e) when (H(e)) + { + + } + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - var expected = @" -class Program -{ - void goo() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1089196")] + [WorkItem("https://github.com/dotnet/roslyn/issues/285")] + public async Task FormatHashInBadDirectiveToZeroColumnAnywhereInsideIfDef() { - int x = 0; - int y = 0; - } -}"; + const string code = """ + class MyClass + { + static void Main(string[] args) + { + #if false - var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + # - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0000() - { - var code = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[] x; - int[,] y; - int[,,] z = new int[1,2,3]; - var a = new[] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, false }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + #endif + } + } + """; - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0001() - { - var code = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[] x; - int[,] y; - int[,,] z = new int[1, 2, 3]; - var a = new[] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + const string expected = """ + class MyClass + { + static void Main(string[] args) + { + #if false - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0010() - { - var code = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[] x; - int[,] y; - int[,,] z = new int[1 ,2 ,3]; - var a = new[] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, false }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + # - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0011() - { - var code = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[] x; - int[,] y; - int[,,] z = new int[1 , 2 , 3]; - var a = new[] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + #endif + } + } + """; + await AssertFormatAsync(expected, code); + } - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0100() - { - var code = @" -class Program -{ - int[ ] x; - int[, ] y; - int[, , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[] x; - int[,] y; - int[,,] z = new int[ 1,2,3 ]; - var a = new[] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, false }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1089196")] + [WorkItem("https://github.com/dotnet/roslyn/issues/285")] + public async Task FormatHashElseToZeroColumnAnywhereInsideIfDef() + { + const string code = """ + class MyClass + { + static void Main(string[] args) + { + #if false - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0101() - { - var code = @" -class Program -{ - int[ ] x; - int[, ] y; - int[, , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[] x; - int[,] y; - int[,,] z = new int[ 1, 2, 3 ]; - var a = new[] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + #else + Appropriate indentation should be here though # + #endif + } + } + """; - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0110() - { - var code = @" -class Program -{ - int[ ] x; - int[, ] y; - int[, , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[] x; - int[,] y; - int[,,] z = new int[ 1 ,2 ,3 ]; - var a = new[] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, false }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + const string expected = """ + class MyClass + { + static void Main(string[] args) + { + #if false - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_0111() - { - var code = @" -class Program -{ - int[ ] x; - int[, ] y; - int[, , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[] x; - int[,] y; - int[,,] z = new int[ 1 , 2 , 3 ]; - var a = new[] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + #else + Appropriate indentation should be here though # + #endif + } + } + """; + await AssertFormatAsync(expected, code); + } - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1000() - { - var code = @" -class Program -{ - int[] x; - int[ ,] y; - int[ , ,] z = new int[1,2,3]; - var a = new[] { 0 }; -}"; - - var expected = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, false }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1089196")] + [WorkItem("https://github.com/dotnet/roslyn/issues/285")] + public async Task FormatHashsToZeroColumnAnywhereInsideIfDef() + { + const string code = """ + class MyClass + { + static void Main(string[] args) + { + #if false - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1001() - { - var code = @" -class Program -{ - int[] x; - int[ ,] y; - int[ , ,] z = new int[1,2,3]; - var a = new[] { 0 }; -}"; - - var expected = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1, 2, 3]; - var a = new[ ] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + #else + # - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1010() - { - var code = @" -class Program -{ - int[] x; - int[ ,] y; - int[ , ,] z = new int[1,2,3]; - var a = new[] { 0 }; -}"; - - var expected = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1 ,2 ,3]; - var a = new[ ] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, false }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + #endif + } + } + """; - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1011() - { - var code = @" -class Program -{ - int[] x; - int[ ,] y; - int[ , ,] z = new int[1,2,3]; - var a = new[] { 0 }; -}"; - - var expected = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1 , 2 , 3]; - var a = new[ ] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + const string expected = """ + class MyClass + { + static void Main(string[] args) + { + #if false - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1100() - { - var code = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[ 1,2,3 ]; - var a = new[ ] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, false }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + #else + # - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1101() - { - var code = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[ 1, 2, 3 ]; - var a = new[ ] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + #endif + } + } + """; + await AssertFormatAsync(expected, code); + } - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1110() - { - var code = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[ 1 ,2 ,3 ]; - var a = new[ ] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, false }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1118")] + public void DoNotAssumeCertainNodeAreAlwaysParented() + { + var block = SyntaxFactory.Block(); + Formatter.Format(block, new AdhocWorkspace().Services.SolutionServices, CSharpSyntaxFormattingOptions.Default, CancellationToken.None); + } - [Fact] - public async Task SpaceWithinEmptyBracketPrecedencesSpaceBeforeOrAfterComma_1111() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/776")] + public async Task SpacingRulesAroundMethodCallAndParenthesisAppliedInAttributeNonDefault() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - var code = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[1,2,3]; - var a = new[ ] { 0 }; -}"; - - var expected = @" -class Program -{ - int[ ] x; - int[ , ] y; - int[ , , ] z = new int[ 1 , 2 , 3 ]; - var a = new[ ] { 0 }; -}"; - - var options = new OptionsCollection(LanguageNames.CSharp) - { - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + { CSharpFormattingOptions2.SpaceAfterMethodCallName, true }, + { CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses, true }, + { CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, true } + }; + await AssertFormatAsync(""" + [Obsolete ( "Test" ), Obsolete ( )] + class Program + { + static void Main(string[] args) + { + } + } + """, """ + [Obsolete("Test"), Obsolete()] + class Program + { + static void Main(string[] args) + { + } + } + """, changingOptions); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14128")] - public async Task SpaceBeforeCommasInLocalFunctionParameters() - { - var code = @" -class Program -{ - void Goo() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/776")] + public async Task SpacingRulesAroundMethodCallAndParenthesisAppliedInAttribute() { - void LocalFunction(int i, string s) - { - } + var code = """ + [Obsolete("Test"), Obsolete()] + class Program + { + static void Main(string[] args) + { + } + } + """; + await AssertFormatAsync(code, code); } -}"; - var expected = @" -class Program -{ - void Goo() + [Fact] + public async Task SpacingInMethodCallArguments_True() { - void LocalFunction(int i , string s) - { - } - } -}"; + const string code = """ - var options = new OptionsCollection(LanguageNames.CSharp) + [Bar(A=1,B=2)] + class Program { - { SpaceBeforeComma, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + public void goo() + { + var a = typeof(A); + var b = M(a); + var c = default(A); + var d = sizeof(A); + M(); + } + } + """; + const string expected = """ - [Fact] - public async Task ArrayDeclarationShouldFollowEmptySquareBrackets() + [Bar ( A = 1, B = 2 )] + class Program + { + public void goo() + { + var a = typeof ( A ); + var b = M ( a ); + var c = default ( A ); + var d = sizeof ( A ); + M ( ); + } + } + """; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { - const string code = @" -class Program -{ - var t = new Goo(new[ ] { ""a"", ""b"" }); -}"; + { CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, true }, + { CSharpFormattingOptions2.SpaceAfterMethodCallName, true }, + { CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses, true }, + }; + await AssertFormatAsync(expected, code, changedOptionSet: optionSet); + } - const string expected = @" -class Program -{ - var t = new Goo(new[] { ""a"", ""b"" }); -}"; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1298")] + public async Task DoNotforceAccessorsToNewLineWithPropertyInitializers() + { + var code = """ + using System.Collections.Generic; - var options = new OptionsCollection(LanguageNames.CSharp) + class Program { - { CSharpFormattingOptions2.SpaceWithinSquareBrackets, true }, - { CSharpFormattingOptions2.SpaceBetweenEmptySquareBrackets, false } - }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } - - [Fact] - public async Task SquareBracesBefore_True() - { - var code = @" -class Program -{ - int[] x; -}"; - - var expected = @" -class Program -{ - int [] x; -}"; + public List ValidationExcludeFilters { get; } + = new List(); + } - var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.SpaceBeforeOpenSquareBracket, true } }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + public class ExcludeValidation + { + } + """; - [Fact] - public async Task SquareBracesAndValue_True() - { - var code = @" -class Program -{ - int[3] x; -}"; + var expected = """ + using System.Collections.Generic; - var expected = @" -class Program -{ - int[ 3 ] x; -}"; + class Program + { + public List ValidationExcludeFilters { get; } + = new List(); + } - var options = new OptionsCollection(LanguageNames.CSharp) { { CSharpFormattingOptions2.SpaceWithinSquareBrackets, true } }; - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + public class ExcludeValidation + { + } + """; + await AssertFormatAsync(expected, code); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/917351")] - public async Task TestLockStatement() - { - var code = @" -class Program -{ - public void Method() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1339")] + public async Task DoNotFormatAutoPropertyInitializerIfNotDifferentLine() { - lock (expression) + var code = """ + class Program { - // goo -} + public int d { get; } + = 3; + static void Main(string[] args) + { + } + } + """; + await AssertFormatAsync(code, code); } -}"; - var expected = @" -class Program -{ - public void Method() + [Fact] + public async Task SpacingForForStatementInfiniteLoop() { - lock (expression) { - // goo - } - } -}"; + var code = """ - var options = new OptionsCollection(LanguageNames.CSharp) + class Program { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, false) } - }; - - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + void Main() + { + for ( ;;) + { + } + } + } + """; + var expected = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/962416")] - public async Task TestCheckedAndUncheckedStatement() - { - var code = @" -class Program -{ - public void Method() - { - checked + class Program { - // goo -} - unchecked + void Main() + { + for (; ; ) { + } + } } + """; + await AssertFormatAsync(expected, code); } -}"; - var expected = @" -class Program -{ - public void Method() + [Fact] + public async Task SpacingForForStatementInfiniteLoopWithNoSpaces() { - checked { - // goo - } - unchecked { - } - } -}"; + var code = """ - var options = new OptionsCollection(LanguageNames.CSharp) + class Program { - { NewLineBeforeOpenBrace , NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, false) } - }; - - await AssertFormatAsync(expected, code, changedOptionSet: options); - } + void Main() + { + for ( ; ; ) + { + } + } + } + """; + var expected = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/953535")] - public async Task ConditionalMemberAccess() + class Program + { + void Main() + { + for (;;) + { + } + } + } + """; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { - var code = @" -using System; -class A -{ - public A a; -} + { CSharpFormattingOptions2.SpaceAfterSemicolonsInForStatement, false }, + }; -class Program -{ - static void Main(string[] args) - { - A a = null; - A ?.a = null; - System.Console.WriteLine(args ?[0]); - System.Console.WriteLine(args ?.Length); + await AssertFormatAsync(expected, code, changedOptionSet: optionSet); } -}"; - - var expected = @" -using System; -class A -{ - public A a; -} -class Program -{ - static void Main(string[] args) + [Fact] + public async Task SpacingForForStatementInfiniteLoopWithSpacesBefore() { - A a = null; - A?.a = null; - System.Console.WriteLine(args?[0]); - System.Console.WriteLine(args?.Length); - } -}"; - var parseOptions = new CSharpParseOptions(); - await AssertFormatAsync(expected, code, parseOptions: parseOptions); - } + var code = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/924172")] - public async Task IgnoreSpacesInDeclarationStatementEnabled() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class Program { - { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, true } - }; - var code = @" -class Program -{ - static void Main(string[] args) - { - int s; + void Main() + { + for (;; ) + { + } + } + } + """; + var expected = """ + + class Program + { + void Main() + { + for ( ; ;) + { + } + } + } + """; + var optionSet = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.SpaceBeforeSemicolonsInForStatement, true }, + { CSharpFormattingOptions2.SpaceAfterSemicolonsInForStatement, false }, + }; + + await AssertFormatAsync(expected, code, changedOptionSet: optionSet); } -}"; - var expected = @" -class Program -{ - static void Main(string[] args) + [Fact] + public async Task SpacingForForStatementInfiniteLoopWithSpacesBeforeAndAfter() { - int s; - } -}"; - await AssertFormatAsync(expected, code, changedOptionSet: changingOptions); - } + var code = """ + + class Program + { + void Main() + { + for (;;) + { + } + } + } + """; + var expected = """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/899492")] - public async Task CommentIsLeadingTriviaOfStatementNotLabel() + class Program + { + void Main() + { + for ( ; ; ) + { + } + } + } + """; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { - var code = @" -class C -{ - void M() - { - label: - // comment - M(); - M(); + { CSharpFormattingOptions2.SpaceBeforeSemicolonsInForStatement, true }, + }; + + await AssertFormatAsync(expected, code, changedOptionSet: optionSet); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4240")] + [WorkItem("https://github.com/dotnet/roslyn/issues/4421")] + public async Task VerifySpacingAfterMethodDeclarationName_Default() { - label: - // comment - M(); - M(); + var code = """ + class Program + { + public static Program operator + (Program p1, Program p2) { return null; } + public static implicit operator string (Program p) { return null; } + public static void M () { } + public void F () { } + } + """; + var expected = """ + class Program + { + public static Program operator +(Program p1, Program p2) { return null; } + public static implicit operator string(Program p) { return null; } + public static void M() { } + public void F() { } + } + """; + await AssertFormatAsync(expected, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991547")] - public async Task DoNotWrappingTryCatchFinallyIfOnSingleLine() - { - var code = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4421")] + [WorkItem("https://github.com/dotnet/roslyn/issues/4240")] + public async Task VerifySpacingAfterMethodDeclarationName_NonDefault() { - try { } - catch { } - finally { } + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.SpacingAfterMethodDeclarationName, true } + }; + var code = """ + class Program + { + public static Program operator + (Program p1, Program p2) { return null; } + public static implicit operator string (Program p) { return null; } + public static void M () { } + public void F () { } + } + """; + var expected = """ + class Program + { + public static Program operator + (Program p1, Program p2) { return null; } + public static implicit operator string (Program p) { return null; } + public static void M () { } + public void F () { } + } + """; + await AssertFormatAsync(expected, code, changedOptionSet: changingOptions); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/939")] + public async Task DoNotFormatInsideArrayInitializers() { - try { } - catch { } - finally { } + var code = """ + class Program + { + static void Main(string[] args) + { + int[] sss = new[] { + //Comment1 + 2, + 5, 324534, 345345, + //Comment2 + //This comment should not line up with the previous comment + 234234 + //Comment3 + , 234, + 234234 + /* + This is a multiline comment + */ + //Comment4 + }; + } + } + """; + await AssertFormatAsync(code, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact] - public async Task InterpolatedStrings1() - { - var code = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4280")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1184285")] + public async Task FormatDictionaryInitializers() { - var a = ""World""; - var b = $""Hello, {a}""; + var code = """ + class Program + { + void Main() + { + var sample = new Dictionary {["x"] = "d" ,["z"] = "XX" }; + } + } + """; + var expected = """ + class Program + { + void Main() + { + var sample = new Dictionary { ["x"] = "d", ["z"] = "XX" }; + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3256")] + public async Task SwitchSectionHonorsNewLineForBracesinControlBlockOption_Default() { - var a = ""World""; - var b = $""Hello, {a}""; + var code = """ + class Program + { + public void goo() + { + int f = 1; + switch (f) { + case 1: { + // DO nothing + break; + } + } + } + } + """; + var expected = """ + class Program + { + public void goo() + { + int f = 1; + switch (f) + { + case 1: + { + // DO nothing + break; + } + } + } + } + """; + await AssertFormatAsync(expected, code); } -}"; - - await AssertFormatAsync(expected, code); - } - [Fact] - public async Task InterpolatedStrings2() - { - var code = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3256")] + public async Task SwitchSectionHonorsNewLineForBracesinControlBlockOption_NonDefault() { - var a = ""Hello""; - var b = ""World""; - var c = $""{a}, {b}""; + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, false) } + }; + var code = """ + class Program + { + public void goo() + { + int f = 1; + switch (f) + { + case 1: + { + // DO nothing + break; + } + } + } + } + """; + + var expected = """ + class Program + { + public void goo() + { + int f = 1; + switch (f) { + case 1: { + // DO nothing + break; + } + } + } + } + """; + await AssertFormatAsync(expected, code, changedOptionSet: changingOptions); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4014")] + public async Task FormattingCodeWithMissingTokensShouldRespectFormatTabsOption1() { - var a = ""Hello""; - var b = ""World""; - var c = $""{a}, {b}""; - } -}"; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; - await AssertFormatAsync(expected, code); - } + await AssertFormatAsync(""" + class Program + { + static void Main() + { + return // Note the missing semicolon + } // The tab here should stay a tab + } + """, """ + class Program + { + static void Main() + { + return // Note the missing semicolon + } // The tab here should stay a tab + } + """, changedOptionSet: optionSet); + } - [Fact] - public async Task InterpolatedStrings3() - { - var code = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4014")] + public async Task FormattingCodeWithMissingTokensShouldRespectFormatTabsOption2() { - var a = ""World""; - var b = $""Hello, { a }""; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + + await AssertFormatAsync(""" + struct Goo + { + private readonly string bar; + + public Goo(readonly string bar) + { + } + } + """, """ + struct Goo + { + private readonly string bar; + + public Goo(readonly string bar) + { + } + } + """, changedOptionSet: optionSet); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4014")] + public async Task FormattingCodeWithBrokenLocalDeclarationShouldRespectFormatTabsOption() { - var a = ""World""; - var b = $""Hello, {a}""; - } -}"; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; - await AssertFormatAsync(expected, code); - } + await AssertFormatAsync(""" + class AClass + { + void AMethod(Object anArgument) + { + if (anArgument == null) + { + throw new ArgumentNullException(nameof(anArgument)); + } + anArgument + + DoSomething(); + } + + void DoSomething() + { + } + } + """, """ + class AClass + { + void AMethod(Object anArgument) + { + if (anArgument == null) + { + throw new ArgumentNullException(nameof(anArgument)); + }anArgument + + DoSomething(); + } + + void DoSomething() + { + } + } + """, changedOptionSet: optionSet); + } - [Fact] - public async Task InterpolatedRawStrings3() - { - var code = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4014")] + public async Task FormattingCodeWithBrokenInterpolatedStringShouldRespectFormatTabsOption() { - var a = ""World""; - var b = $""""""Hello, { a }""""""; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + + await AssertFormatAsync(""" + class AClass + { + void Main() + { + Test($"\"_{\""); + Console.WriteLine(args); + } + } + """, """ + class AClass + { + void Main() + { + Test($"\"_{\""); + Console.WriteLine(args); + } + } + """, changedOptionSet: optionSet); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/84")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/849870")] + public async Task NewLinesForBracesInPropertiesTest() { - var a = ""World""; - var b = $""""""Hello, {a}""""""; - } -}"; + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.Properties, false) }, + }; + await AssertFormatAsync(""" + class Class2 + { + int Goo { + get + { + return 1; + } + } - await AssertFormatAsync(expected, code); - } + int MethodGoo() + { + return 42; + } + } + """, """ + class Class2 + { + int Goo + { + get + { + return 1; + } + } - [Fact] - public async Task InterpolatedStrings4() - { - var code = @" -class C -{ - void M() - { - var a = ""Hello""; - var b = ""World""; - var c = $""{ a }, { b }""; + int MethodGoo() + { + return 42; + } + } + """, changingOptions); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/849870")] + [WorkItem("https://github.com/dotnet/roslyn/issues/84")] + public async Task NewLinesForBracesInAccessorsTest() { - var a = ""Hello""; - var b = ""World""; - var c = $""{a}, {b}""; - } -}"; + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.Accessors, false) }, + }; + await AssertFormatAsync(""" + class Class2 + { + int Goo + { + get { + return 1; + } + } - await AssertFormatAsync(expected, code); - } + int MethodGoo() + { + return 42; + } + } + """, """ + class Class2 + { + int Goo + { + get + { + return 1; + } + } - [Fact] - public async Task InterpolatedStrings5() - { - var code = @" -class C -{ - void M() - { - var a = ""World""; - var b = $@""Hello, {a}""; + int MethodGoo() + { + return 42; + } + } + """, changingOptions); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/849870")] + [WorkItem("https://github.com/dotnet/roslyn/issues/84")] + public async Task NewLinesForBracesInPropertiesAndAccessorsTest() { - var a = ""World""; - var b = $@""Hello, {a}""; - } -}"; + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue + .WithFlagValue(NewLineBeforeOpenBracePlacement.Properties, false) + .WithFlagValue(NewLineBeforeOpenBracePlacement.Accessors, false)}, + }; + await AssertFormatAsync(""" + class Class2 + { + int Goo { + get { + return 1; + } + } - await AssertFormatAsync(expected, code); - } + int MethodGoo() + { + return 42; + } + } + """, """ + class Class2 + { + int Goo + { + get + { + return 1; + } + } - [Fact] - public async Task InterpolatedStrings6() - { - var code = @" -class C -{ - void M() - { - var a = ""Hello""; - var b = ""World""; - var c = $@""{a}, {b}""; + int MethodGoo() + { + return 42; + } + } + """, changingOptions); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem(111079, "devdiv.visualstudio.com")] + public async Task TestThrowInIfOnSingleLine() { - var a = ""Hello""; - var b = ""World""; - var c = $@""{a}, {b}""; - } -}"; + var code = """ - await AssertFormatAsync(expected, code); - } + class C + { + void M() + { + if (true) throw new Exception( + "message"); + } + } - [Fact] - public async Task InterpolatedStrings7() - { - var code = @" -class C -{ - void M() - { - var a = ""World""; - var b = $@""Hello, { a }""; + """; + + await AssertFormatAsync(code, code); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://connect.microsoft.com/VisualStudio/feedback/details/1711675/autoformatting-issues")] + public async Task SingleLinePropertiesPreservedWithLeaveStatementsAndMembersOnSingleLineFalse() { - var a = ""World""; - var b = $@""Hello, {a}""; - } -}"; + var changedOptionSet = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.WrappingPreserveSingleLine, true }, + { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false}, + }; - await AssertFormatAsync(expected, code); - } + await AssertFormatAsync(""" - [Fact] - public async Task InterpolatedStrings8() - { - var code = @" -class C -{ - void M() - { - var a = ""Hello""; - var b = ""World""; - var c = $@""{ a }, { b }""; + class C + { + string Name { get; set; } + } + """, """ + + class C + { + string Name { get ; set ; } + } + """, changedOptionSet: changedOptionSet); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4720")] + public async Task KeepAccessorWithAttributeOnSingleLine() { - var a = ""Hello""; - var b = ""World""; - var c = $@""{a}, {b}""; - } -}"; + await AssertFormatAsync(""" - await AssertFormatAsync(expected, code); - } + class Program + { + public Int32 PaymentMethodID + { + [System.Diagnostics.DebuggerStepThrough] + get { return 10; } + } + } + """, """ - [Fact] - public async Task InterpolatedStrings9() - { - var code = @" -class C -{ - void M() - { - var a = ""Hello""; - var c = $""{ a }, World""; + class Program + { + public Int32 PaymentMethodID + { + [System.Diagnostics.DebuggerStepThrough] + get { return 10; } + } + } + """); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6905")] + public async Task KeepConstructorBodyInSameLineAsBaseConstructorInitializer() { - var a = ""Hello""; - var c = $""{a}, World""; - } -}"; + var code = """ - await AssertFormatAsync(expected, code); - } + class C + { + public C(int s) + : base() { } + public C() + { + } + } + """; + await AssertFormatAsync(code, code); + } - [Fact] - public async Task InterpolatedStrings10() - { - var code = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6905")] + public async Task KeepConstructorBodyInSameLineAsThisConstructorInitializer() { - var s = $""{42 , -4 :x}""; + var code = """ + + class C + { + public C(int s) + : this() { } + public C() + { + } + } + """; + await AssertFormatAsync(code, code); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6905")] + public async Task KeepConstructorBodyInSameLineAsThisConstructorInitializerAdjustSpace() { - var s = $""{42,-4:x}""; - } -}"; + await AssertFormatAsync(""" - await AssertFormatAsync(expected, code); - } + class C + { + public C(int s) + : this() { } + public C() + { + } + } + """, """ - [Fact] - public async Task InterpolatedRawStrings10() - { - var code = @" -class C -{ - void M() - { - var s = $""""""{42 , -4 :x}""""""; + class C + { + public C(int s) + : this() { } + public C() + { + } + } + """); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4720")] + public async Task OneSpaceBetweenAccessorsAndAttributes() { - var s = $""""""{42,-4:x}""""""; - } -}"; + await AssertFormatAsync(""" - await AssertFormatAsync(expected, code); - } + class Program + { + public int SomeProperty { [SomeAttribute] get; [SomeAttribute] private set; } + } + """, """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59811")] - public async Task InterpolatedStrings11() - { - var code = @" -class C -{ - void M() - { - var hostAddress = ""host""; - var nasTypeId = ""nas""; - var version = ""1.2""; - var c = $""{ hostAddress?? """"}/{nasTypeId }/{version??""""}""; + class Program + { + public int SomeProperty { [SomeAttribute] get; [SomeAttribute] private set; } + } + """); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7900")] + public async Task FormatEmbeddedStatementInsideLockStatement() { - var hostAddress = ""host""; - var nasTypeId = ""nas""; - var version = ""1.2""; - var c = $""{hostAddress ?? """"}/{nasTypeId}/{version ?? """"}""; - } -}"; + await AssertFormatAsync(""" - await AssertFormatAsync(expected, code); - } + class C + { + private object _l = new object(); + public void M() + { + lock (_l) Console.WriteLine("d"); + } + } + """, """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59811")] - public async Task InterpolatedStrings12() - { - var code = @" -class C -{ - void M() - { - var a = 1.2M; - var c = $""{ a : 000.00 }""; + class C + { + private object _l = new object(); + public void M() + { + lock (_l) Console.WriteLine("d"); + } + } + """); } -}"; - var expected = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7900")] + public async Task FormatEmbeddedStatementInsideLockStatementDifferentLine() { - var a = 1.2M; - var c = $""{a: 000.00 }""; - } -}"; + await AssertFormatAsync(""" - await AssertFormatAsync(expected, code); - } + class C + { + private object _l = new object(); + public void M() + { + lock (_l) + Console.WriteLine("d"); + } + } + """, """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59811")] - public async Task InterpolatedStrings13() - { - var code = @" -class C -{ - void M() - { - var a = 1.2M; - var c = $""{ (a > 2?""a"":""b""}""; + class C + { + private object _l = new object(); + public void M() + { + lock (_l) + Console.WriteLine("d"); + } + } + """); } -}"; - var expected = @" -class C -{ - void M() + [Fact] + public async Task PropertyDeclarationSimple() { - var a = 1.2M; - var c = $""{(a > 2 ? ""a"" : ""b""}""; + var expected = @"if (o is Point p)"; + await AssertFormatBodyAsync(expected, expected); + await AssertFormatBodyAsync(expected, @"if (o is Point p)"); + await AssertFormatBodyAsync(expected, @"if (o is Point p )"); } -}"; - await AssertFormatAsync(expected, code); - } - - [Fact] - public async Task InterpolatedStrings14() - { - var code = @" -class C -{ - void M() + [Fact] + public async Task PropertyDeclarationTypeOnNewLine() { - var s = $""{ 42 , -4 :x}""; - } -}"; + var expected = """ - var expected = @" -class C -{ - void M() - { - var s = $""{42,-4:x}""; - } -}"; + var y = o is + Point p; + """; + await AssertFormatBodyAsync(expected, expected); + await AssertFormatBodyAsync(expected, """ - await AssertFormatAsync(expected, code); - } + var y = o is + Point p; + """); - [Fact] - public async Task InterpolatedStrings15() - { - var code = @" -class C -{ - void M() - { - var s = $""{ 42 , -4 }""; - } -}"; + await AssertFormatBodyAsync(expected, """ - var expected = @" -class C -{ - void M() - { - var s = $""{42,-4}""; - } -}"; + var y = o is + Point p ; + """); - await AssertFormatAsync(expected, code); - } + await AssertFormatBodyAsync(expected, """ - [Fact] - public async Task InterpolatedStrings16() - { - var code = @" -class C -{ - void M() - { - var s = $""{ 42 , -4 : x }""; + var y = o is + Point p ; + """); } -}"; - var expected = @" -class C -{ - void M() + [Fact] + public async Task CasePatternDeclarationSimple() { - var s = $""{42,-4: x }""; - } -}"; - - await AssertFormatAsync(expected, code); - } + var expected = """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1151")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1041787")] - public async Task ReconstructWhitespaceStringUsingTabs_SingleLineComment() - { - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; - await AssertFormatAsync(@"using System; - -class Program -{ - static void Main(string[] args) - { - Console.WriteLine(""""); // GooBar - } -}", @"using System; + switch (o) + { + case Point p: + } + """; -class Program -{ - static void Main(string[] args) - { - Console.WriteLine(""""); // GooBar - } -}", optionSet); - } + await AssertFormatBodyAsync(expected, expected); + await AssertFormatBodyAsync(expected, """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1151")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/961559")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1041787")] - public async Task ReconstructWhitespaceStringUsingTabs_MultiLineComment() - { - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; - await AssertFormatAsync(@"using System; + switch (o) + { + case Point p : + } + """); -class Program -{ - static void Main(string[] args) - { - Console.WriteLine(""""); /* GooBar */ - } -}", @"using System; + await AssertFormatBodyAsync(expected, """ -class Program -{ - static void Main(string[] args) - { - Console.WriteLine(""""); /* GooBar */ + switch (o) + { + case Point p : + } + """); } -}", optionSet); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1100920")] - public async Task NoLineOperationAroundInterpolationSyntax() - { - await AssertFormatAsync(@"class Program -{ - static string F(int a, int b, int c) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23703")] + public async Task FormatNullableArray() { - return $""{a} (index: 0x{b}, size: {c}): "" - } -}", @"class Program -{ - static string F(int a, int b, int c) - { - return $""{a} (index: 0x{ b}, size: { c}): "" + var code = """ + + class C + { + object[]? F = null; + } + """; + await AssertFormatAsync(code, code); } -}"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62")] - public async Task SpaceAfterWhenInExceptionFilter() - { - const string expected = @"class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23703")] + public async Task FormatConditionalWithArrayAccess() { - try - { - if (x) + var code = """ + + class C { - G(); + void M() + { + _ = array[1] ? 2 : 3; + } } - } - catch (Exception e) when (H(e)) - { - - } + """; + await AssertFormatAsync(code, code); } -}"; - const string code = @"class C -{ - void M() + private Task AssertFormatBodyAsync(string expected, string input) { - try + static string transform(string s) { - if(x){ - G(); + var lines = s.Split([Environment.NewLine], StringSplitOptions.None); + for (var i = 0; i < lines.Length; i++) + { + if (!string.IsNullOrEmpty(lines[i])) + { + lines[i] = new string(' ', count: 8) + lines[i]; + } } - } - catch(Exception e) when (H(e)) - { + return string.Join(Environment.NewLine, lines); } + + var pattern = """ + + class C + {{ + void M() + {{ + {0} + }} + }} + """; + + expected = string.Format(pattern, transform(expected)); + input = string.Format(pattern, transform(input)); + return AssertFormatAsync(expected, input); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1089196")] - [WorkItem("https://github.com/dotnet/roslyn/issues/285")] - public async Task FormatHashInBadDirectiveToZeroColumnAnywhereInsideIfDef() - { - const string code = @"class MyClass -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6628")] + public async Task FormatElseBlockBracesOnDifferentLineToNewLines() { -#if false + await AssertFormatAsync(""" - # + class C + { + public void M() + { + if (true) + { + } + else + { + } + } + } + """, """ -#endif + class C + { + public void M() + { + if (true) + { + } + else { + } + } + } + """); } -}"; - const string expected = @"class MyClass -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6628")] + public async Task FormatOnElseBlockBracesOnSameLineRemainsInSameLine_1() { -#if false + var code = """ -# - -#endif + class C + { + public void M() + { + if (true) + { + } + else { } + } + } + """; + await AssertFormatAsync(code, code); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1089196")] - [WorkItem("https://github.com/dotnet/roslyn/issues/285")] - public async Task FormatHashElseToZeroColumnAnywhereInsideIfDef() - { - const string code = @"class MyClass -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11572")] + public async Task FormatAttributeOnSameLineAsField() { -#if false + await AssertFormatAsync( + """ - #else - Appropriate indentation should be here though # -#endif + class C + { + [Attr] int i; + } + """, + """ + + class C { + [Attr] int i; + } + """); } -}"; - const string expected = @"class MyClass -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21789")] + public async Task FormatMultipleAttributeOnSameLineAsField1() { -#if false + await AssertFormatAsync( + """ + + class C + { + [Attr1] + [Attr2] + [Attr3][Attr4] int i; + } + """, + """ -#else - Appropriate indentation should be here though # -#endif + class C { + [Attr1] + [Attr2] + [Attr3][Attr4] int i; + } + """); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1089196")] - [WorkItem("https://github.com/dotnet/roslyn/issues/285")] - public async Task FormatHashsToZeroColumnAnywhereInsideIfDef() - { - const string code = @"class MyClass -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21789")] + public async Task FormatMultipleAttributesOnSameLineAsField2() { -#if false + await AssertFormatAsync( + """ - #else - # + class C + { + [Attr1] + [Attr2] + [Attr3][Attr4] int i; + } + """, + """ -#endif + class C { + [Attr1][Attr2] + [Attr3][Attr4] int i; + } + """); } -}"; - const string expected = @"class MyClass -{ - static void Main(string[] args) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21789")] + public async Task FormatMultipleAttributeOnSameLineAndFieldOnNewLine() { -#if false + await AssertFormatAsync( + """ -#else -# + class C + { + [Attr1] + [Attr2] + int i; + } + """, + """ -#endif + class C { + [Attr1][Attr2] + int i; + } + """); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1118")] - public void DoNotAssumeCertainNodeAreAlwaysParented() - { - var block = SyntaxFactory.Block(); - Formatter.Format(block, new AdhocWorkspace().Services.SolutionServices, CSharpSyntaxFormattingOptions.Default, CancellationToken.None); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6628")] + public async Task FormatOnElseBlockBracesOnSameLineRemainsInSameLine_2() + { + var code = """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/776")] - public async Task SpacingRulesAroundMethodCallAndParenthesisAppliedInAttributeNonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class C { - { CSharpFormattingOptions2.SpaceAfterMethodCallName, true }, - { CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses, true }, - { CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, true } - }; - await AssertFormatAsync(@"[Obsolete ( ""Test"" ), Obsolete ( )] -class Program -{ - static void Main(string[] args) - { - } -}", @"[Obsolete(""Test""), Obsolete()] -class Program -{ - static void Main(string[] args) - { + public void M() + { + if (true) + { + } + else + { } + } + } + """; + await AssertFormatAsync(code, code); } -}", changingOptions); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/776")] - public async Task SpacingRulesAroundMethodCallAndParenthesisAppliedInAttribute() - { - var code = @"[Obsolete(""Test""), Obsolete()] -class Program -{ - static void Main(string[] args) - { - } -}"; - await AssertFormatAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25098")] + public void FormatSingleStructDeclaration() + => Formatter.Format(SyntaxFactory.StructDeclaration("S"), DefaultWorkspace.Services.SolutionServices, CSharpSyntaxFormattingOptions.Default, CancellationToken.None); - [Fact] - public async Task SpacingInMethodCallArguments_True() - { - const string code = @" -[Bar(A=1,B=2)] -class Program -{ - public void goo() - { - var a = typeof(A); - var b = M(a); - var c = default(A); - var d = sizeof(A); - M(); - } -}"; - const string expected = @" -[Bar ( A = 1, B = 2 )] -class Program -{ - public void goo() + [Fact] + public async Task FormatIndexExpression() { - var a = typeof ( A ); - var b = M ( a ); - var c = default ( A ); - var d = sizeof ( A ); - M ( ); - } -}"; - var optionSet = new OptionsCollection(LanguageNames.CSharp) + await AssertFormatAsync(""" + + class C { - { CSharpFormattingOptions2.SpaceWithinMethodCallParentheses, true }, - { CSharpFormattingOptions2.SpaceAfterMethodCallName, true }, - { CSharpFormattingOptions2.SpaceBetweenEmptyMethodCallParentheses, true }, - }; - await AssertFormatAsync(expected, code, changedOptionSet: optionSet); - } + void M() + { + object x = ^1; + object y = ^1 + } + } + """, """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1298")] - public async Task DoNotforceAccessorsToNewLineWithPropertyInitializers() - { - var code = @"using System.Collections.Generic; + class C + { + void M() + { + object x = ^1; + object y = ^1 + } + } + """); + } -class Program -{ - public List ValidationExcludeFilters { get; } - = new List(); -} + [Fact] + public async Task FormatRangeExpression_NoOperands() + { + await AssertFormatAsync(""" -public class ExcludeValidation -{ -}"; + class C + { + void M() + { + object x = ..; + object y = .. + } + } + """, """ - var expected = @"using System.Collections.Generic; + class C + { + void M() + { + object x = ..; + object y = .. + } + } + """); + } -class Program -{ - public List ValidationExcludeFilters { get; } - = new List(); -} + [Fact] + public async Task FormatRangeExpression_RightOperand() + { + await AssertFormatAsync(""" -public class ExcludeValidation -{ -}"; - await AssertFormatAsync(expected, code); - } + class C + { + void M() + { + object x = ..1; + object y = ..1 + } + } + """, """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1339")] - public async Task DoNotFormatAutoPropertyInitializerIfNotDifferentLine() - { - var code = @"class Program -{ - public int d { get; } - = 3; - static void Main(string[] args) - { + class C + { + void M() + { + object x = ..1; + object y = ..1 + } + } + """); } -}"; - await AssertFormatAsync(code, code); - } - [Fact] - public async Task SpacingForForStatementInfiniteLoop() - { - var code = @" -class Program -{ - void Main() - { - for ( ;;) - { - } - } -}"; - var expected = @" -class Program -{ - void Main() + [Fact] + public async Task FormatRangeExpression_LeftOperand() { - for (; ; ) - { - } - } -}"; - await AssertFormatAsync(expected, code); - } + await AssertFormatAsync(""" - [Fact] - public async Task SpacingForForStatementInfiniteLoopWithNoSpaces() - { - var code = @" -class Program -{ - void Main() - { - for ( ; ; ) - { - } - } -}"; - var expected = @" -class Program -{ - void Main() - { - for (;;) - { - } - } -}"; - var optionSet = new OptionsCollection(LanguageNames.CSharp) + class C { - { CSharpFormattingOptions2.SpaceAfterSemicolonsInForStatement, false }, - }; - - await AssertFormatAsync(expected, code, changedOptionSet: optionSet); - } + void M() + { + object x = 1..; + object y = 1.. + } + } + """, """ - [Fact] - public async Task SpacingForForStatementInfiniteLoopWithSpacesBefore() - { - var code = @" -class Program -{ - void Main() - { - for (;; ) - { - } + class C + { + void M() + { + object x = 1..; + object y = 1.. + } + } + """); } -}"; - var expected = @" -class Program -{ - void Main() + + [Fact] + public async Task FormatRangeExpression_BothOperands() { - for ( ; ;) - { - } - } -}"; - var optionSet = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.SpaceBeforeSemicolonsInForStatement, true }, - { CSharpFormattingOptions2.SpaceAfterSemicolonsInForStatement, false }, - }; + await AssertFormatAsync(""" - await AssertFormatAsync(expected, code, changedOptionSet: optionSet); - } + class C + { + void M() + { + object x = 1..2; + object y = 1..2 + } + } + """, """ - [Fact] - public async Task SpacingForForStatementInfiniteLoopWithSpacesBeforeAndAfter() - { - var code = @" -class Program -{ - void Main() - { - for (;;) - { - } + class C + { + void M() + { + object x = 1..2; + object y = 1..2 + } + } + """); } -}"; - var expected = @" -class Program -{ - void Main() + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32113")] + public async Task FormatCommaAfterCloseBrace_CommaRemainIntheSameLine() { - for ( ; ; ) - { - } - } -}"; - var optionSet = new OptionsCollection(LanguageNames.CSharp) + await AssertFormatAsync( + """ + + public class Test { - { CSharpFormattingOptions2.SpaceBeforeSemicolonsInForStatement, true }, - }; + public void Foo() + { + (Action, Action, Action) tuple = ( + () => { Console.WriteLine(2.997e8); }, + () => { Console.WriteLine(6.67e-11); }, + () => { Console.WriteLine(1.602e-19); } + ); + } + } + """, + """ - await AssertFormatAsync(expected, code, changedOptionSet: optionSet); - } + public class Test + { + public void Foo() + { + (Action, Action, Action) tuple = ( + () => { Console.WriteLine(2.997e8); }, + () => { Console.WriteLine(6.67e-11); }, + () => { Console.WriteLine(1.602e-19); } + ); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4240")] - [WorkItem("https://github.com/dotnet/roslyn/issues/4421")] - public async Task VerifySpacingAfterMethodDeclarationName_Default() - { - var code = @"class Program -{ - public static Program operator + (Program p1, Program p2) { return null; } - public static implicit operator string (Program p) { return null; } - public static void M () { } - public void F () { } -}"; - var expected = @"class Program -{ - public static Program operator +(Program p1, Program p2) { return null; } - public static implicit operator string(Program p) { return null; } - public static void M() { } - public void F() { } -}"; - await AssertFormatAsync(expected, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32113")] + public async Task FormatCommaAfterCloseBrace_SpaceSurroundWillBeRemoved() + { + await AssertFormatAsync( + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4421")] - [WorkItem("https://github.com/dotnet/roslyn/issues/4240")] - public async Task VerifySpacingAfterMethodDeclarationName_NonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + public class Test { - { CSharpFormattingOptions2.SpacingAfterMethodDeclarationName, true } - }; - var code = @"class Program -{ - public static Program operator + (Program p1, Program p2) { return null; } - public static implicit operator string (Program p) { return null; } - public static void M () { } - public void F () { } -}"; - var expected = @"class Program -{ - public static Program operator + (Program p1, Program p2) { return null; } - public static implicit operator string (Program p) { return null; } - public static void M () { } - public void F () { } -}"; - await AssertFormatAsync(expected, code, changedOptionSet: changingOptions); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/939")] - public async Task DoNotFormatInsideArrayInitializers() - { - var code = @"class Program -{ - static void Main(string[] args) - { - int[] sss = new[] { - //Comment1 - 2, - 5, 324534, 345345, - //Comment2 - //This comment should not line up with the previous comment - 234234 - //Comment3 - , 234, - 234234 - /* - This is a multiline comment - */ - //Comment4 - }; - } -}"; - await AssertFormatAsync(code, code); - } + public void Foo() + { + (Action, Action, Action) tuple = ( + () => { Console.WriteLine(2.997e8); }, + () => { Console.WriteLine(6.67e-11); }, + () => { Console.WriteLine(1.602e-19); } + ); + } + } + """, + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4280")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1184285")] - public async Task FormatDictionaryInitializers() - { - var code = @"class Program -{ - void Main() - { - var sample = new Dictionary {[""x""] = ""d"" ,[""z""] = ""XX"" }; + public class Test + { + public void Foo() + { + (Action, Action, Action) tuple = ( + () => { Console.WriteLine(2.997e8); } , + () => { Console.WriteLine(6.67e-11); } , + () => { Console.WriteLine(1.602e-19); } + ); + } + } + """); } -}"; - var expected = @"class Program -{ - void Main() + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31571")] + [WorkItem("https://github.com/dotnet/roslyn/issues/33910")] + [CombinatorialData] + public async Task ConversionOperator_CorrectlySpaceArgumentList( + [CombinatorialValues("implicit", "explicit")] string operatorType, + [CombinatorialValues("string", "string[]", "System.Action", "int?", "int*", "(int, int)")] string targetType, + bool spacingAfterMethodDeclarationName) { - var sample = new Dictionary { [""x""] = ""d"", [""z""] = ""XX"" }; + var expectedSpacing = spacingAfterMethodDeclarationName ? " " : ""; + var initialSpacing = spacingAfterMethodDeclarationName ? "" : " "; + var changedOptionSet = new OptionsCollection(LanguageNames.CSharp) { { SpacingAfterMethodDeclarationName, spacingAfterMethodDeclarationName } }; + await AssertFormatAsync( + $$""" + + public unsafe class Test + { + public static {{operatorType}} operator {{targetType}}{{expectedSpacing}}() => throw null; + } + """, + $$""" + + public unsafe class Test + { + public static {{operatorType}} operator {{targetType}}{{initialSpacing}}() => throw null; + } + """, + changedOptionSet: changedOptionSet); } -}"; - await AssertFormatAsync(expected, code); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3256")] - public async Task SwitchSectionHonorsNewLineForBracesinControlBlockOption_Default() - { - var code = @"class Program -{ - public void goo() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31868")] + public async Task SpaceAroundDeclaration() { - int f = 1; - switch (f) { - case 1: { - // DO nothing - break; + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, true } + }; + await AssertFormatAsync( + """ + + class Program + { + public void FixMyType() + { + var myint = 0; } - } + } + """, + """ + + class Program + { + public void FixMyType() + { + var myint = 0; + } + } + """, changedOptionSet: changingOptions); } -}"; - var expected = @"class Program -{ - public void goo() + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31868")] + public async Task SpaceAroundDeclarationAndPreserveSingleLine() { - int f = 1; - switch (f) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - case 1: + { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, true }, + { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } + }; + await AssertFormatAsync( + """ + + class Program + { + public void FixMyType() { - // DO nothing - break; + var myint = 0; } - } - } -}"; - await AssertFormatAsync(expected, code); - } + } + """, + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3256")] - public async Task SwitchSectionHonorsNewLineForBracesinControlBlockOption_NonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class Program { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, false) } - }; - var code = @"class Program -{ - public void goo() - { - int f = 1; - switch (f) - { - case 1: + public void FixMyType() { - // DO nothing - break; + var myint = 0; } - } + } + """, changedOptionSet: changingOptions); } -}"; - var expected = @"class Program -{ - public void goo() + [Fact] + public async Task ClassConstraint() { - int f = 1; - switch (f) { - case 1: { - // DO nothing - break; - } - } - } -}"; - await AssertFormatAsync(expected, code, changedOptionSet: changingOptions); - } + await AssertFormatAsync( + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4014")] - public async Task FormattingCodeWithMissingTokensShouldRespectFormatTabsOption1() - { - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + class Program + where T : class? + { + } + """, + """ - await AssertFormatAsync(@"class Program -{ - static void Main() - { - return // Note the missing semicolon - } // The tab here should stay a tab -}", @"class Program -{ - static void Main() - { - return // Note the missing semicolon - } // The tab here should stay a tab -}", changedOptionSet: optionSet); - } + class Program + where T : class ? + { + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4014")] - public async Task FormattingCodeWithMissingTokensShouldRespectFormatTabsOption2() - { - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + [Fact] + public async Task SingleLinePropertyPattern1() + { + await AssertFormatAsync( + """ - await AssertFormatAsync(@"struct Goo -{ - private readonly string bar; + using System.Collections.Generic; + class Program + { + public void FixMyType() + { + _ = new List() is + { + Count: { }, + }; + } + } + """, + """ - public Goo(readonly string bar) - { - } -}", @"struct Goo -{ - private readonly string bar; + using System.Collections.Generic; + class Program + { + public void FixMyType() + { + _ = new List() is + { + Count:{}, + }; + } + } + """); + } - public Goo(readonly string bar) - { - } -}", changedOptionSet: optionSet); - } + [Fact] + public async Task SingleLinePropertyPattern2() + { + await AssertFormatAsync( + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4014")] - public async Task FormattingCodeWithBrokenLocalDeclarationShouldRespectFormatTabsOption() - { - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + using System.Collections.Generic; + class Program + { + public void FixMyType(object o) + { + _ = o is List { Count: { } }; + } + } + """, + """ - await AssertFormatAsync(@"class AClass -{ - void AMethod(Object anArgument) - { - if (anArgument == null) - { - throw new ArgumentNullException(nameof(anArgument)); - } - anArgument - - DoSomething(); - } - - void DoSomething() - { - } -}", @"class AClass -{ - void AMethod(Object anArgument) - { - if (anArgument == null) - { - throw new ArgumentNullException(nameof(anArgument)); - }anArgument - - DoSomething(); - } - - void DoSomething() - { - } -}", changedOptionSet: optionSet); - } + using System.Collections.Generic; + class Program + { + public void FixMyType(object o) + { + _ = o is List{Count:{}}; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4014")] - public async Task FormattingCodeWithBrokenInterpolatedStringShouldRespectFormatTabsOption() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37030")] + public async Task SpaceAroundEnumMemberDeclarationIgnored() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, true } + }; + await AssertFormatAsync( + """ - await AssertFormatAsync(@"class AClass -{ - void Main() - { - Test($""\""_{\""""); - Console.WriteLine(args); - } -}", @"class AClass -{ - void Main() - { - Test($""\""_{\""""); - Console.WriteLine(args); - } -}", changedOptionSet: optionSet); - } + enum TestEnum + { + Short = 1, + LongItemName = 2 + } + """, + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/84")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/849870")] - public async Task NewLinesForBracesInPropertiesTest() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + enum TestEnum { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.Properties, false) }, - }; - await AssertFormatAsync(@"class Class2 -{ - int Goo { - get - { - return 1; - } + Short = 1, + LongItemName = 2 + } + """, changedOptionSet: changingOptions); } - int MethodGoo() - { - return 42; - } -}", @"class Class2 -{ - int Goo + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37030")] + public async Task SpaceAroundEnumMemberDeclarationSingle() { - get + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - return 1; - } - } + { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, false } + }; + await AssertFormatAsync( + """ - int MethodGoo() - { - return 42; - } -}", changingOptions); - } + enum TestEnum + { + Short = 1, + LongItemName = 2 + } + """, + """ - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/849870")] - [WorkItem("https://github.com/dotnet/roslyn/issues/84")] - public async Task NewLinesForBracesInAccessorsTest() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + enum TestEnum { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.Accessors, false) }, - }; - await AssertFormatAsync(@"class Class2 -{ - int Goo - { - get { - return 1; - } + Short = 1, + LongItemName = 2 + } + """, changedOptionSet: changingOptions); } - int MethodGoo() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38895")] + public async Task FormattingNbsp() { - return 42; + await AssertFormatAsync( + """ + + class C + { + List list = new List + { + new C() + }; + } + """, + """ + + class C + { + List list = new List + { +             new C() + }; + } + """.Replace(" ", "\u00A0")); } -}", @"class Class2 -{ - int Goo + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47438")] + public async Task IndentationForMultilineWith() { - get - { - return 1; - } + var code = """ + record C(int X) + { + C M() + { + return this with + { + X = 1 + }; + } + } + """; + var expectedCode = """ + record C(int X) + { + C M() + { + return this with + { + X = 1 + }; + } + } + """; + + await AssertFormatAsync(expectedCode, code); } - int MethodGoo() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47438")] + public async Task IndentationForMultilineWith_ArrowBody() { - return 42; + var code = """ + record C(int X) + { + C M() + => this with + { + X = 1 + }; + } + """; + var expectedCode = """ + record C(int X) + { + C M() + => this with + { + X = 1 + }; + } + """; + + await AssertFormatAsync(expectedCode, code); } -}", changingOptions); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/849870")] - [WorkItem("https://github.com/dotnet/roslyn/issues/84")] - public async Task NewLinesForBracesInPropertiesAndAccessorsTest() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47438")] + public async Task IndentationForMultilineWith_ArrowBody_WithTrailingComma() + { + var code = """ + record C(int X) + { + C M() + => this with { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue - .WithFlagValue(NewLineBeforeOpenBracePlacement.Properties, false) - .WithFlagValue(NewLineBeforeOpenBracePlacement.Accessors, false)}, + X = 1, }; - await AssertFormatAsync(@"class Class2 -{ - int Goo { - get { - return 1; - } + } + """; + var expectedCode = """ + record C(int X) + { + C M() + => this with + { + X = 1, + }; + } + """; + + await AssertFormatAsync(expectedCode, code); } - int MethodGoo() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41022")] + public async Task SpacingAfterAttribute() { - return 42; + var code = """ + class C + { + void M([My]string?[]?[] x) + { + } + } + """; + var expectedCode = """ + class C + { + void M([My] string?[]?[] x) + { + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -}", @"class Class2 -{ - int Goo + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41022")] + public async Task SpacingAfterAttribute_Multiple() { - get - { - return 1; - } + var code = """ + class C + { + void M([My][My] int x) + { + } + } + """; + var expectedCode = """ + class C + { + void M([My][My] int x) + { + } + } + """; + + await AssertFormatAsync(expectedCode, code); } - int MethodGoo() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41022")] + public async Task SpacingAfterAttribute_Multiple2() { - return 42; + var code = """ + class C + { + void M([My] [My] int x) + { + } + } + """; + var expectedCode = """ + class C + { + void M([My][My] int x) + { + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -}", changingOptions); - } - [Fact, WorkItem(111079, "devdiv.visualstudio.com")] - public async Task TestThrowInIfOnSingleLine() - { - var code = @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41022")] + public async Task SpacingAfterAttribute_MultipleOnDeclaration() { - if (true) throw new Exception( - ""message""); + var code = """ + class C + { + [My] [My] void M() + { + } + } + """; + var expectedCode = """ + class C + { + [My] + [My] + void M() + { + } + } + """; + + await AssertFormatAsync(expectedCode, code); } -} -"; - await AssertFormatAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47442")] + public async Task IndentImplicitObjectCreationInitializer() + { + var code = """ - [Fact, WorkItem("https://connect.microsoft.com/VisualStudio/feedback/details/1711675/autoformatting-issues")] - public async Task SingleLinePropertiesPreservedWithLeaveStatementsAndMembersOnSingleLineFalse() - { - var changedOptionSet = new OptionsCollection(LanguageNames.CSharp) + class C { - { CSharpFormattingOptions2.WrappingPreserveSingleLine, true }, - { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false}, - }; + public string Name { get; set; } + public static C Create1(string name) + => new C() + { + Name = name + }; + public static C Create2(string name) + => new() + { + Name = name + }; + } + """; + var expectedCode = """ - await AssertFormatAsync(@" -class C -{ - string Name { get; set; } -}", @" -class C -{ - string Name { get ; set ; } -}", changedOptionSet: changedOptionSet); - } + class C + { + public string Name { get; set; } + public static C Create1(string name) + => new C() + { + Name = name + }; + public static C Create2(string name) + => new() + { + Name = name + }; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4720")] - public async Task KeepAccessorWithAttributeOnSingleLine() - { - await AssertFormatAsync(@" -class Program -{ - public Int32 PaymentMethodID - { - [System.Diagnostics.DebuggerStepThrough] - get { return 10; } - } -}", @" -class Program -{ - public Int32 PaymentMethodID - { - [System.Diagnostics.DebuggerStepThrough] - get { return 10; } + await AssertFormatAsync(expectedCode, code); } -}"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6905")] - public async Task KeepConstructorBodyInSameLineAsBaseConstructorInitializer() - { - var code = @" -class C -{ - public C(int s) - : base() { } - public C() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36913")] + public async Task NewLinesForBraces_SwitchExpression_Default() { - } -}"; - await AssertFormatAsync(code, code); - } + await AssertFormatAsync( + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6905")] - public async Task KeepConstructorBodyInSameLineAsThisConstructorInitializer() - { - var code = @" -class C -{ - public C(int s) - : this() { } - public C() - { + class A + { + void br() + { + var msg = 1 switch + { + _ => null + }; + } + } + """, + """ + + class A + { + void br() + { + var msg = 1 switch { + _ => null + }; + } + } + """); } -}"; - await AssertFormatAsync(code, code); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6905")] - public async Task KeepConstructorBodyInSameLineAsThisConstructorInitializerAdjustSpace() - { - await AssertFormatAsync(@" -class C -{ - public C(int s) - : this() { } - public C() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36913")] + public async Task NewLinesForBraces_SwitchExpression_NonDefault() { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) + { + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, + }; + await AssertFormatAsync( + """ + + class A + { + void br() + { + var msg = 1 switch { + _ => null + }; + } + } + """, + """ + + class A + { + void br() + { + var msg = 1 switch + { + _ => null + }; + } + } + """, changedOptionSet: changingOptions); } -}", @" -class C -{ - public C(int s) - : this() { } - public C() + + [Fact, WorkItem("https://github.com/dotnet/roslyn/discussions/49725")] + public async Task NewLinesForBraces_RecordWithInitializer_Default() { + await AssertFormatAsync( + """ + + record R(int X); + class C + { + void Goo(R r) + { + var r2 = r with + { + X = 0 + }; + } + } + """, + """ + + record R(int X); + class C + { + void Goo(R r) + { + var r2 = r with { + X = 0 + }; + } + } + """); } -}"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4720")] - public async Task OneSpaceBetweenAccessorsAndAttributes() + [Fact, WorkItem("https://github.com/dotnet/roslyn/discussions/49725")] + public async Task NewLinesForBraces_RecordWithInitializer_NonDefault() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - await AssertFormatAsync(@" -class Program -{ - public int SomeProperty { [SomeAttribute] get; [SomeAttribute] private set; } -}", @" -class Program -{ - public int SomeProperty { [SomeAttribute] get; [SomeAttribute] private set; } -}"); - } + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, + }; + await AssertFormatAsync( + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7900")] - public async Task FormatEmbeddedStatementInsideLockStatement() - { - await AssertFormatAsync(@" -class C -{ - private object _l = new object(); - public void M() + record R(int X); + class C + { + void Goo(R r) + { + var r2 = r with { + X = 0 + }; + } + } + """, + """ + + record R(int X); + class C + { + void Goo(R r) + { + var r2 = r with + { + X = 0 + }; + } + } + """, changedOptionSet: changingOptions); + } + + [Fact] + public async Task NoSpacesInPropertyPatterns() { - lock (_l) Console.WriteLine(""d""); + var code = """ + class C + { + int IntProperty { get; set; } + void M() + { + _ = this is { IntProperty : 2 }; + } + } + """; + var expectedCode = """ + class C + { + int IntProperty { get; set; } + void M() + { + _ = this is { IntProperty: 2 }; + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", @" -class C -{ - private object _l = new object(); - public void M() + + [Fact] + public async Task NoSpacesInExtendedPropertyPatterns() { - lock (_l) Console.WriteLine(""d""); + var code = """ + class C + { + C CProperty { get; set; } + int IntProperty { get; set; } + void M() + { + _ = this is { CProperty . IntProperty : 2 }; + } + } + """; + var expectedCode = """ + class C + { + C CProperty { get; set; } + int IntProperty { get; set; } + void M() + { + _ = this is { CProperty.IntProperty: 2 }; + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7900")] - public async Task FormatEmbeddedStatementInsideLockStatementDifferentLine() - { - await AssertFormatAsync(@" -class C -{ - private object _l = new object(); - public void M() - { - lock (_l) - Console.WriteLine(""d""); - } -}", @" -class C -{ - private object _l = new object(); - public void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52413")] + public async Task NewLinesForBraces_PropertyPatternClauses_Default() { - lock (_l) - Console.WriteLine(""d""); - } -}"); - } + await AssertFormatAsync( + """ - [Fact] - public async Task PropertyDeclarationSimple() - { - var expected = @"if (o is Point p)"; - await AssertFormatBodyAsync(expected, expected); - await AssertFormatBodyAsync(expected, @"if (o is Point p)"); - await AssertFormatBodyAsync(expected, @"if (o is Point p )"); - } + class A + { + public string Name { get; } - [Fact] - public async Task PropertyDeclarationTypeOnNewLine() - { - var expected = @" -var y = o is -Point p;"; - await AssertFormatBodyAsync(expected, expected); - await AssertFormatBodyAsync(expected, @" -var y = o is -Point p; "); - - await AssertFormatBodyAsync(expected, @" -var y = o is -Point p ;"); - - await AssertFormatBodyAsync(expected, @" -var y = o is -Point p ;"); - } + public bool IsFoo(A a) + { + return a is + { + Name: "foo", + }; + } + } + """, + """ + + class A + { + public string Name { get; } + + public bool IsFoo(A a) + { + return a is { + Name: "foo", + }; + } + } + """); + } - [Fact] - public async Task CasePatternDeclarationSimple() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52413")] + public async Task NewLinesForBraces_PropertyPatternClauses_NonDefault() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - var expected = @" -switch (o) -{ - case Point p: -}"; + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, + }; + await AssertFormatAsync( + """ - await AssertFormatBodyAsync(expected, expected); - await AssertFormatBodyAsync(expected, @" -switch (o) -{ - case Point p : -}"); + class A + { + public string Name { get; } - await AssertFormatBodyAsync(expected, @" -switch (o) -{ - case Point p : -}"); - } + public bool IsFoo(A a) + { + return a is { + Name: "foo", + }; + } + } + """, + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23703")] - public async Task FormatNullableArray() - { - var code = @" -class C -{ - object[]? F = null; -}"; - await AssertFormatAsync(code, code); - } + class A + { + public string Name { get; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23703")] - public async Task FormatConditionalWithArrayAccess() - { - var code = @" -class C -{ - void M() - { - _ = array[1] ? 2 : 3; + public bool IsFoo(A a) + { + return a is + { + Name: "foo", + }; + } + } + """, changedOptionSet: changingOptions); } -}"; - await AssertFormatAsync(code, code); - } - private Task AssertFormatBodyAsync(string expected, string input) + [Fact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WorkItem(57854, "https://github.com/dotnet/roslyn/issues/57854")] + public async Task NewLinesForBraces_PropertyPatternClauses_NonDefaultInSwitchExpression() + { + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - static string transform(string s) + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, + }; + await AssertFormatAsync( + """ + + class A { - var lines = s.Split([Environment.NewLine], StringSplitOptions.None); - for (var i = 0; i < lines.Length; i++) + public string Name { get; } + + public bool IsFoo(A a) { - if (!string.IsNullOrEmpty(lines[i])) - { - lines[i] = new string(' ', count: 8) + lines[i]; - } + return a switch { + { Name: "foo" } => true, + _ => false, + }; } - - return string.Join(Environment.NewLine, lines); } + """, + """ - var pattern = @" -class C -{{ - void M() - {{ -{0} - }} -}}"; - - expected = string.Format(pattern, transform(expected)); - input = string.Format(pattern, transform(input)); - return AssertFormatAsync(expected, input); - } + class A + { + public string Name { get; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6628")] - public async Task FormatElseBlockBracesOnDifferentLineToNewLines() - { - await AssertFormatAsync(@" -class C -{ - public void M() - { - if (true) - { - } - else - { - } + public bool IsFoo(A a) + { + return a switch + { + { Name: "foo" } => true, + _ => false, + }; + } + } + """, changedOptionSet: changingOptions); } -}", @" -class C -{ - public void M() + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/52413")] + public async Task NewLinesForBraces_PropertyPatternClauses_SingleLine(bool option) { - if (true) + var changingOptions = new OptionsCollection(LanguageNames.CSharp) { - } - else { - } + { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, option) }, + }; + var code = """ + + class A + { + public string Name { get; } + + public bool IsFoo(A a) + { + return a is { Name: "foo" }; + } + } + """; + await AssertFormatAsync(code, code, changedOptionSet: changingOptions); } -}"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6628")] - public async Task FormatOnElseBlockBracesOnSameLineRemainsInSameLine_1() - { - var code = @" -class C -{ - public void M() + [Fact] + public async Task RecordClass() { - if (true) - { - } - else { } - } -}"; - await AssertFormatAsync(code, code); - } + await AssertFormatAsync( + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11572")] - public async Task FormatAttributeOnSameLineAsField() - { - await AssertFormatAsync( -@" -class C -{ - [Attr] int i; -}", -@" -class C { - [Attr] int i; -}"); - } + record class R(int X); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21789")] - public async Task FormatMultipleAttributeOnSameLineAsField1() - { - await AssertFormatAsync( -@" -class C -{ - [Attr1] - [Attr2] - [Attr3][Attr4] int i; -}", -@" -class C { - [Attr1] - [Attr2] - [Attr3][Attr4] int i; -}"); - } + """, + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21789")] - public async Task FormatMultipleAttributesOnSameLineAsField2() - { - await AssertFormatAsync( -@" -class C -{ - [Attr1] - [Attr2] - [Attr3][Attr4] int i; -}", -@" -class C { - [Attr1][Attr2] - [Attr3][Attr4] int i; -}"); - } + record class R(int X); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21789")] - public async Task FormatMultipleAttributeOnSameLineAndFieldOnNewLine() - { - await AssertFormatAsync( -@" -class C -{ - [Attr1] - [Attr2] - int i; -}", -@" -class C { - [Attr1][Attr2] - int i; -}"); - } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/6628")] - public async Task FormatOnElseBlockBracesOnSameLineRemainsInSameLine_2() - { - var code = @" -class C -{ - public void M() + [Fact] + public async Task Class() { - if (true) - { - } - else - { } - } -}"; - await AssertFormatAsync(code, code); - } + await AssertFormatAsync( + """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25098")] - public void FormatSingleStructDeclaration() - => Formatter.Format(SyntaxFactory.StructDeclaration("S"), DefaultWorkspace.Services.SolutionServices, CSharpSyntaxFormattingOptions.Default, CancellationToken.None); + class R(int X); - [Fact] - public async Task FormatIndexExpression() - { - await AssertFormatAsync(@" -class C -{ - void M() - { - object x = ^1; - object y = ^1 - } -}", @" -class C -{ - void M() - { - object x = ^1; - object y = ^1 - } -}"); - } + """, + """ - [Fact] - public async Task FormatRangeExpression_NoOperands() - { - await AssertFormatAsync(@" -class C -{ - void M() - { - object x = ..; - object y = .. - } -}", @" -class C -{ - void M() - { - object x = ..; - object y = .. - } -}"); - } + class R(int X) ; - [Fact] - public async Task FormatRangeExpression_RightOperand() - { - await AssertFormatAsync(@" -class C -{ - void M() - { - object x = ..1; - object y = ..1 - } -}", @" -class C -{ - void M() - { - object x = ..1; - object y = ..1 + """); } -}"); - } - [Fact] - public async Task FormatRangeExpression_LeftOperand() - { - await AssertFormatAsync(@" -class C -{ - void M() - { - object x = 1..; - object y = 1.. - } -}", @" -class C -{ - void M() + [Fact] + public async Task Interface() { - object x = 1..; - object y = 1.. - } -}"); - } + await AssertFormatAsync( + """ - [Fact] - public async Task FormatRangeExpression_BothOperands() - { - await AssertFormatAsync(@" -class C -{ - void M() - { - object x = 1..2; - object y = 1..2 - } -}", @" -class C -{ - void M() - { - object x = 1..2; - object y = 1..2 - } -}"); - } + interface R(int X); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32113")] - public async Task FormatCommaAfterCloseBrace_CommaRemainIntheSameLine() - { - await AssertFormatAsync( - @" -public class Test -{ - public void Foo() - { - (Action, Action, Action) tuple = ( - () => { Console.WriteLine(2.997e8); }, - () => { Console.WriteLine(6.67e-11); }, - () => { Console.WriteLine(1.602e-19); } - ); - } -}", - @" -public class Test -{ - public void Foo() - { - (Action, Action, Action) tuple = ( - () => { Console.WriteLine(2.997e8); }, - () => { Console.WriteLine(6.67e-11); }, - () => { Console.WriteLine(1.602e-19); } - ); + """, + """ + + interface R(int X) ; + + """); } -}"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32113")] - public async Task FormatCommaAfterCloseBrace_SpaceSurroundWillBeRemoved() - { - await AssertFormatAsync( - @" -public class Test -{ - public void Foo() + [Fact] + public async Task RecordStruct() { - (Action, Action, Action) tuple = ( - () => { Console.WriteLine(2.997e8); }, - () => { Console.WriteLine(6.67e-11); }, - () => { Console.WriteLine(1.602e-19); } - ); + await AssertFormatAsync( + """ + + record struct R(int X); + + """, + """ + + record struct R(int X); + + """); } -}", - @" -public class Test -{ - public void Foo() + + [Fact] + public async Task Struct() { - (Action, Action, Action) tuple = ( - () => { Console.WriteLine(2.997e8); } , - () => { Console.WriteLine(6.67e-11); } , - () => { Console.WriteLine(1.602e-19); } - ); - } -}"); - } + await AssertFormatAsync( + """ - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31571")] - [WorkItem("https://github.com/dotnet/roslyn/issues/33910")] - [CombinatorialData] - public async Task ConversionOperator_CorrectlySpaceArgumentList( - [CombinatorialValues("implicit", "explicit")] string operatorType, - [CombinatorialValues("string", "string[]", "System.Action", "int?", "int*", "(int, int)")] string targetType, - bool spacingAfterMethodDeclarationName) - { - var expectedSpacing = spacingAfterMethodDeclarationName ? " " : ""; - var initialSpacing = spacingAfterMethodDeclarationName ? "" : " "; - var changedOptionSet = new OptionsCollection(LanguageNames.CSharp) { { SpacingAfterMethodDeclarationName, spacingAfterMethodDeclarationName } }; - await AssertFormatAsync( - $@" -public unsafe class Test -{{ - public static {operatorType} operator {targetType}{expectedSpacing}() => throw null; -}}", - $@" -public unsafe class Test -{{ - public static {operatorType} operator {targetType}{initialSpacing}() => throw null; -}}", - changedOptionSet: changedOptionSet); - } + struct R(int X); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31868")] - public async Task SpaceAroundDeclaration() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, true } - }; - await AssertFormatAsync( - @" -class Program -{ - public void FixMyType() - { - var myint = 0; + """, + """ + + struct R(int X) ; + + """); } -}", - @" -class Program -{ - public void FixMyType() + + [Fact] + public async Task FormatListPattern() { - var myint = 0; - } -}", changedOptionSet: changingOptions); - } + var code = """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31868")] - public async Task SpaceAroundDeclarationAndPreserveSingleLine() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class C { - { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, true }, - { CSharpFormattingOptions2.WrappingKeepStatementsOnSingleLine, false } - }; - await AssertFormatAsync( - @" -class Program -{ - public void FixMyType() - { - var myint = 0; - } -}", - @" -class Program -{ - public void FixMyType() - { - var myint = 0; - } -}", changedOptionSet: changingOptions); - } + void M() { + _ = this is[1,2,>=3]; + } + } + """; + await AssertFormatAsync(code: code, expected: """ - [Fact] - public async Task ClassConstraint() - { - await AssertFormatAsync( - @" -class Program - where T : class? -{ -}", - @" -class Program - where T : class ? -{ -}"); - } + class C + { + void M() + { + _ = this is [1, 2, >= 3]; + } + } + """); - [Fact] - public async Task SingleLinePropertyPattern1() - { - await AssertFormatAsync( - @" -using System.Collections.Generic; -class Program -{ - public void FixMyType() - { - _ = new List() is - { - Count: { }, - }; - } -}", - @" -using System.Collections.Generic; -class Program -{ - public void FixMyType() - { - _ = new List() is + var options = new OptionsCollection(LanguageNames.CSharp) { - Count:{}, + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, false }, }; - } -}"); - } - [Fact] - public async Task SingleLinePropertyPattern2() - { - await AssertFormatAsync( - @" -using System.Collections.Generic; -class Program -{ - public void FixMyType(object o) - { - _ = o is List { Count: { } }; - } -}", - @" -using System.Collections.Generic; -class Program -{ - public void FixMyType(object o) - { - _ = o is List{Count:{}}; - } -}"); - } + await AssertFormatAsync(code: code, changedOptionSet: options, expected: """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37030")] - public async Task SpaceAroundEnumMemberDeclarationIgnored() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class C { - { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, true } - }; - await AssertFormatAsync( - @" -enum TestEnum -{ - Short = 1, - LongItemName = 2 -}", - @" -enum TestEnum -{ - Short = 1, - LongItemName = 2 -}", changedOptionSet: changingOptions); - } + void M() + { + _ = this is [1,2,>= 3]; + } + } + """); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37030")] - public async Task SpaceAroundEnumMemberDeclarationSingle() + options = new OptionsCollection(LanguageNames.CSharp) { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.SpacesIgnoreAroundVariableDeclaration, false } - }; - await AssertFormatAsync( - @" -enum TestEnum -{ - Short = 1, - LongItemName = 2 -}", - @" -enum TestEnum -{ - Short = 1, - LongItemName = 2 -}", changedOptionSet: changingOptions); - } + { SpaceBeforeOpenSquareBracket, false }, // ignored + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, true }, + }; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38895")] - public async Task FormattingNbsp() - { - await AssertFormatAsync( - @" -class C -{ - List list = new List - { -new C() - }; -}", - @" -class C -{ - List list = new List - { -            new C() - }; -}".Replace(" ", "\u00A0")); - } + await AssertFormatAsync(code: code, changedOptionSet: options, expected: """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47438")] - public async Task IndentationForMultilineWith() - { - var code = @"record C(int X) -{ - C M() - { - return this with -{ -X = 1 -}; + class C + { + void M() + { + _ = this is [ 1 , 2 , >= 3 ]; + } + } + """); } -}"; - var expectedCode = @"record C(int X) -{ - C M() + + [Fact] + public async Task FormatListPattern_Parentheses() { - return this with - { - X = 1 - }; - } -}"; + var code = """ + + class C + { + void M((int[], int[]) a) { + _ = a is([1,2,>=3],[1,2]); + } + } + """; + await AssertFormatAsync(code: code, expected: """ - await AssertFormatAsync(expectedCode, code); - } + class C + { + void M((int[], int[]) a) + { + _ = a is ([1, 2, >= 3], [1, 2]); + } + } + """); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47438")] - public async Task IndentationForMultilineWith_ArrowBody() - { - var code = @"record C(int X) -{ - C M() - => this with -{ -X = 1 -}; -}"; - var expectedCode = @"record C(int X) -{ - C M() - => this with + var options = new OptionsCollection(LanguageNames.CSharp) { - X = 1 + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, false }, }; -}"; - await AssertFormatAsync(expectedCode, code); - } + await AssertFormatAsync(code: code, changedOptionSet: options, expected: """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47438")] - public async Task IndentationForMultilineWith_ArrowBody_WithTrailingComma() - { - var code = @"record C(int X) -{ - C M() - => this with -{ -X = 1, -}; -}"; - var expectedCode = @"record C(int X) -{ - C M() - => this with + class C + { + void M((int[], int[]) a) + { + _ = a is ([1,2,>= 3],[1,2]); + } + } + """); + + options = new OptionsCollection(LanguageNames.CSharp) { - X = 1, + { SpaceBeforeOpenSquareBracket, false }, // ignored + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, true }, }; -}"; - await AssertFormatAsync(expectedCode, code); - } + await AssertFormatAsync(code: code, changedOptionSet: options, expected: """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41022")] - public async Task SpacingAfterAttribute() - { - var code = @"class C -{ - void M([My]string?[]?[] x) - { + class C + { + void M((int[ ], int[ ]) a) + { + _ = a is ([ 1 , 2 , >= 3 ], [ 1 , 2 ]); + } + } + """); } -}"; - var expectedCode = @"class C -{ - void M([My] string?[]?[] x) + + [Fact] + public async Task FormatListPattern_TrailingComma() { - } -}"; + var code = """ - await AssertFormatAsync(expectedCode, code); - } + class C + { + void M() { + _ = this is[1,2,>=3,]; + } + } + """; + await AssertFormatAsync(code: code, expected: """ + + class C + { + void M() + { + _ = this is [1, 2, >= 3,]; + } + } + """); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41022")] - public async Task SpacingAfterAttribute_Multiple() + var options = new OptionsCollection(LanguageNames.CSharp) { - var code = @"class C -{ - void M([My][My] int x) - { - } -}"; - var expectedCode = @"class C -{ - void M([My][My] int x) - { - } -}"; + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, false }, + }; - await AssertFormatAsync(expectedCode, code); - } + await AssertFormatAsync(code: code, changedOptionSet: options, expected: """ + + class C + { + void M() + { + _ = this is [1,2,>= 3,]; + } + } + """); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41022")] - public async Task SpacingAfterAttribute_Multiple2() + options = new OptionsCollection(LanguageNames.CSharp) { - var code = @"class C -{ - void M([My] [My] int x) - { - } -}"; - var expectedCode = @"class C -{ - void M([My][My] int x) - { - } -}"; + { SpaceBeforeOpenSquareBracket, false }, // ignored + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, true }, + }; - await AssertFormatAsync(expectedCode, code); - } + await AssertFormatAsync(code: code, changedOptionSet: options, expected: """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41022")] - public async Task SpacingAfterAttribute_MultipleOnDeclaration() - { - var code = @"class C -{ - [My] [My] void M() - { + class C + { + void M() + { + _ = this is [ 1 , 2 , >= 3 , ]; + } + } + """); } -}"; - var expectedCode = @"class C -{ - [My] - [My] - void M() + + [Fact] + public async Task FormatListPattern_WithNewline() { - } -}"; + var code = """ - await AssertFormatAsync(expectedCode, code); - } + class C + { + void M() { + _ = this is + [1,2,>=3 + ]; + } + } + """; + await AssertFormatAsync(code: code, expected: """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47442")] - public async Task IndentImplicitObjectCreationInitializer() - { - var code = @" -class C -{ - public string Name { get; set; } - public static C Create1(string name) - => new C() - { - Name = name - }; - public static C Create2(string name) - => new() - { - Name = name - }; -}"; - var expectedCode = @" -class C -{ - public string Name { get; set; } - public static C Create1(string name) - => new C() - { - Name = name - }; - public static C Create2(string name) - => new() + class C + { + void M() + { + _ = this is + [1, 2, >= 3 + ]; + } + } + """); + + var options = new OptionsCollection(LanguageNames.CSharp) { - Name = name + { SpaceBetweenEmptySquareBrackets, false }, + { SpaceWithinSquareBrackets, false }, + { SpaceBeforeComma, false }, + { SpaceAfterComma, false }, }; -}"; - await AssertFormatAsync(expectedCode, code); - } + await AssertFormatAsync(code: code, changedOptionSet: options, expected: """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36913")] - public async Task NewLinesForBraces_SwitchExpression_Default() - { - await AssertFormatAsync( - @" -class A -{ - void br() - { - var msg = 1 switch + class C + { + void M() + { + _ = this is + [1,2,>= 3 + ]; + } + } + """); + + options = new OptionsCollection(LanguageNames.CSharp) { - _ => null + { SpaceBeforeOpenSquareBracket, false }, // ignored + { SpaceBetweenEmptySquareBrackets, true }, + { SpaceWithinSquareBrackets, true }, + { SpaceBeforeComma, true }, + { SpaceAfterComma, true }, }; - } -}", - @" -class A -{ - void br() - { - var msg = 1 switch { - _ => null - }; - } -}"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36913")] - public async Task NewLinesForBraces_SwitchExpression_NonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + await AssertFormatAsync(code: code, changedOptionSet: options, expected: """ + + class C { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, - }; - await AssertFormatAsync( - @" -class A -{ - void br() - { - var msg = 1 switch { - _ => null - }; + void M() + { + _ = this is + [ 1 , 2 , >= 3 + ]; + } + } + """); } -}", - @" -class A -{ - void br() + + [Fact] + public async Task FormatSlicePattern() { - var msg = 1 switch - { - _ => null - }; + var code = """ + class C + { + void M() { + _ = this is[ 0,.. var rest ]; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is [0, .. var rest]; + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", changedOptionSet: changingOptions); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/discussions/49725")] - public async Task NewLinesForBraces_RecordWithInitializer_Default() - { - await AssertFormatAsync( - @" -record R(int X); -class C -{ - void Goo(R r) + [Fact] + public async Task FormatSlicePattern_NoSpace() { - var r2 = r with - { - X = 0 - }; + var code = """ + class C + { + void M() { + _ = this is[ 0,..var rest ]; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is [0, .. var rest]; + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", - @" -record R(int X); -class C -{ - void Goo(R r) + + [Fact] + public async Task FormatSlicePatternWithAnd() { - var r2 = r with { - X = 0 - }; + var code = """ + class C + { + void M() { + _ = this is[ 0,.. {Count: >0} and var rest ]; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is [0, .. { Count: > 0 } and var rest]; + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/discussions/49725")] - public async Task NewLinesForBraces_RecordWithInitializer_NonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, - }; - await AssertFormatAsync( - @" -record R(int X); -class C -{ - void Goo(R r) + [Fact] + public async Task FormatLengthAndListPattern() { - var r2 = r with { - X = 0 - }; + var code = """ + class C + { + void M() { + _ = this is{Count:>0 and var x}and[ 1,2,3 ]; + } + } + """; + var expectedCode = """ + class C + { + void M() + { + _ = this is { Count: > 0 and var x } and [1, 2, 3]; + } + } + """; + await AssertFormatAsync(expectedCode, code); } -}", - @" -record R(int X); -class C -{ - void Goo(R r) + + [Fact] + public async Task LambdaReturnType_01() { - var r2 = r with - { - X = 0 - }; + await AssertFormatAsync( + """ + class Program + { + Delegate D = void () => { }; + } + """, + """ + class Program + { + Delegate D = void () => { }; + } + """); } -}", changedOptionSet: changingOptions); - } - [Fact] - public async Task NoSpacesInPropertyPatterns() - { - var code = @"class C -{ - int IntProperty { get; set; } - void M() + [Fact] + public async Task LambdaReturnType_02() { - _ = this is { IntProperty : 2 }; + await AssertFormatAsync( + """ + class Program + { + Delegate D = A.B () => { }; + } + """, + """ + class Program + { + Delegate D = A.B()=>{ }; + } + """); } -}"; - var expectedCode = @"class C -{ - int IntProperty { get; set; } - void M() + + [Fact] + public async Task LambdaReturnType_03() { - _ = this is { IntProperty: 2 }; + await AssertFormatAsync( + """ + class Program + { + Delegate D = A (x) => x; + } + """, + """ + class Program + { + Delegate D = A < B > ( x ) => x; + } + """); } -}"; - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task NoSpacesInExtendedPropertyPatterns() - { - var code = @"class C -{ - C CProperty { get; set; } - int IntProperty { get; set; } - void M() + [Fact] + public async Task LambdaReturnType_04() { - _ = this is { CProperty . IntProperty : 2 }; + await AssertFormatAsync( + """ + class Program + { + object F = Func((A, B) ((A, B) t) => t); + } + """, + """ + class Program + { + object F = Func((A,B)((A,B)t)=>t); + } + """); } -}"; - var expectedCode = @"class C -{ - C CProperty { get; set; } - int IntProperty { get; set; } - void M() + + [Fact] + public async Task LineSpanDirective() { - _ = this is { CProperty.IntProperty: 2 }; + var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; + await AssertFormatAsync( + """ + class Program + { + static void Main() + { + #line (1, 1) - (1, 100) 5 "a.razor" + } + } + """, + """ + class Program + { + static void Main() + { + #line (1,1)-(1,100) 5 "a.razor" + } + } + """, changedOptionSet: optionSet); } -}"; - await AssertFormatAsync(expectedCode, code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52413")] - public async Task NewLinesForBraces_PropertyPatternClauses_Default() - { - await AssertFormatAsync( - @" -class A -{ - public string Name { get; } - public bool IsFoo(A a) + [Fact] + public async Task FileScopedNamespace() { - return a is - { - Name: ""foo"", - }; + await AssertFormatAsync( + expected: """ + + namespace NS; + + class C { } + + """, + code: """ + + namespace NS; + + class C { } + + """); } -}", - @" -class A -{ - public string Name { get; } - public bool IsFoo(A a) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] + public async Task NewInImplicitObjectCreation() { - return a is { - Name: ""foo"", - }; - } -}"); - } + await AssertFormatAsync( + expected: """ - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52413")] - public async Task NewLinesForBraces_PropertyPatternClauses_NonDefault() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class C { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, - }; - await AssertFormatAsync( - @" -class A -{ - public string Name { get; } + void M() + { + string v = new(); + } + } - public bool IsFoo(A a) - { - return a is { - Name: ""foo"", - }; + """, + code: """ + + class C + { + void M() { + string v = new (); + } + } + + """); } -}", - @" -class A -{ - public string Name { get; } - public bool IsFoo(A a) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] + public async Task NewInTupleArrayCreation() { - return a is - { - Name: ""foo"", - }; - } -}", changedOptionSet: changingOptions); - } + await AssertFormatAsync( + expected: """ - [Fact, Trait(Traits.Feature, Traits.Features.Formatting)] - [WorkItem(57854, "https://github.com/dotnet/roslyn/issues/57854")] - public async Task NewLinesForBraces_PropertyPatternClauses_NonDefaultInSwitchExpression() - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class C { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) }, - }; - await AssertFormatAsync( - @" -class A -{ - public string Name { get; } + void M() + { + var v = new (int, int)[]; + } + } - public bool IsFoo(A a) - { - return a switch { - { Name: ""foo"" } => true, - _ => false, - }; + """, + code: """ + + class C + { + void M() { + var v = new (int, int) [ ]; + } + } + + """); } -}", - @" -class A -{ - public string Name { get; } - public bool IsFoo(A a) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] + public async Task NewInArrayCreation() { - return a switch - { - { Name: ""foo"" } => true, - _ => false, - }; - } -}", changedOptionSet: changingOptions); - } + await AssertFormatAsync( + expected: """ - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/52413")] - public async Task NewLinesForBraces_PropertyPatternClauses_SingleLine(bool option) - { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) + class C { - { NewLineBeforeOpenBrace, NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, option) }, - }; - var code = @" -class A -{ - public string Name { get; } + void M() + { + var v = new int[1]; + } + } + + """, + code: """ + + class C + { + void M() { + var v = new int [ 1 ]; + } + } - public bool IsFoo(A a) - { - return a is { Name: ""foo"" }; + """); } -}"; - await AssertFormatAsync(code, code, changedOptionSet: changingOptions); - } - [Fact] - public async Task RecordClass() - { - await AssertFormatAsync( - @" -record class R(int X); -", - @" -record class R(int X); -"); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] + public async Task NewInImplicitArrayCreation() + { + await AssertFormatAsync( + expected: """ - [Fact] - public async Task Class() - { - await AssertFormatAsync( - @" -class R(int X); -", - @" -class R(int X) ; -"); - } + class C + { + void M() + { + var v = new[] { 1, 2, 3 }; + } + } - [Fact] - public async Task Interface() - { - await AssertFormatAsync( - @" -interface R(int X); -", - @" -interface R(int X) ; -"); - } + """, + code: """ - [Fact] - public async Task RecordStruct() - { - await AssertFormatAsync( - @" -record struct R(int X); -", - @" -record struct R(int X); -"); - } + class C + { + void M() { + var v = new [ ] { 1, 2, 3 }; + } + } - [Fact] - public async Task Struct() - { - await AssertFormatAsync( - @" -struct R(int X); -", - @" -struct R(int X) ; -"); - } + """); + } - [Fact] - public async Task FormatListPattern() - { - var code = @" -class C -{ - void M() { -_ = this is[1,2,>=3]; -} -}"; - await AssertFormatAsync(code: code, expected: @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] + public async Task NewInConstructorConstraint() { - _ = this is [1, 2, >= 3]; - } -}"); + await AssertFormatAsync( + expected: """ - var options = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, false }, - }; + void M() where T : new() + { + } + } - await AssertFormatAsync(code: code, changedOptionSet: options, expected: @" -class C -{ - void M() - { - _ = this is [1,2,>= 3]; - } -}"); + """, + code: """ - options = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBeforeOpenSquareBracket, false }, // ignored - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, true }, - }; + void M() where T : new ( ) { + } + } - await AssertFormatAsync(code: code, changedOptionSet: options, expected: @" -class C -{ - void M() - { - _ = this is [ 1 , 2 , >= 3 ]; + """); } -}"); - } - [Fact] - public async Task FormatListPattern_Parentheses() - { - var code = @" -class C -{ - void M((int[], int[]) a) { -_ = a is([1,2,>=3],[1,2]); -} -}"; - await AssertFormatAsync(code: code, expected: @" -class C -{ - void M((int[], int[]) a) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] + public async Task NewMethodOverloadWithTupleReturnType() { - _ = a is ([1, 2, >= 3], [1, 2]); - } -}"); + await AssertFormatAsync( + expected: """ - var options = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, false }, - }; + new (int, int) M() { } + } - await AssertFormatAsync(code: code, changedOptionSet: options, expected: @" -class C -{ - void M((int[], int[]) a) - { - _ = a is ([1,2,>= 3],[1,2]); - } -}"); + """, + code: """ - options = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBeforeOpenSquareBracket, false }, // ignored - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, true }, - }; + new (int, int) M() { } + } - await AssertFormatAsync(code: code, changedOptionSet: options, expected: @" -class C -{ - void M((int[ ], int[ ]) a) - { - _ = a is ([ 1 , 2 , >= 3 ], [ 1 , 2 ]); + """); } -}"); - } - [Fact] - public async Task FormatListPattern_TrailingComma() - { - var code = @" -class C -{ - void M() { -_ = this is[1,2,>=3,]; -} -}"; - await AssertFormatAsync(code: code, expected: @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] + public async Task NewPropertyWithTupleReturnType() { - _ = this is [1, 2, >= 3,]; - } -}"); + await AssertFormatAsync( + expected: """ - var options = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, false }, - }; + new (int, int) Property { get; set; } + } - await AssertFormatAsync(code: code, changedOptionSet: options, expected: @" -class C -{ - void M() - { - _ = this is [1,2,>= 3,]; - } -}"); + """, + code: """ - options = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBeforeOpenSquareBracket, false }, // ignored - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, true }, - }; + new (int, int) Property { get; set; } + } - await AssertFormatAsync(code: code, changedOptionSet: options, expected: @" -class C -{ - void M() - { - _ = this is [ 1 , 2 , >= 3 , ]; + """); } -}"); - } - [Fact] - public async Task FormatListPattern_WithNewline() - { - var code = @" -class C -{ - void M() { -_ = this is -[1,2,>=3 -]; -} -}"; - await AssertFormatAsync(code: code, expected: @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] + public async Task NewIndexerWithTupleReturnType() { - _ = this is - [1, 2, >= 3 - ]; - } -}"); + await AssertFormatAsync( + expected: """ - var options = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBetweenEmptySquareBrackets, false }, - { SpaceWithinSquareBrackets, false }, - { SpaceBeforeComma, false }, - { SpaceAfterComma, false }, - }; + new (int, int) this[int i] { get => throw null; } + } - await AssertFormatAsync(code: code, changedOptionSet: options, expected: @" -class C -{ - void M() - { - _ = this is - [1,2,>= 3 - ]; - } -}"); + """, + code: """ - options = new OptionsCollection(LanguageNames.CSharp) + class C { - { SpaceBeforeOpenSquareBracket, false }, // ignored - { SpaceBetweenEmptySquareBrackets, true }, - { SpaceWithinSquareBrackets, true }, - { SpaceBeforeComma, true }, - { SpaceAfterComma, true }, - }; + new (int, int) this[int i] { get => throw null; } + } - await AssertFormatAsync(code: code, changedOptionSet: options, expected: @" -class C -{ - void M() - { - _ = this is - [ 1 , 2 , >= 3 - ]; + """); } -}"); - } - [Fact] - public async Task FormatSlicePattern() - { - var code = @"class C -{ - void M() { -_ = this is[ 0,.. var rest ]; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] + public async Task FormatAttributeOnLambda() { - _ = this is [0, .. var rest]; + await AssertFormatAsync( + expected: """ + + var f = [Attribute] () => { }; + + """, + code: """ + + var f = [Attribute] () => { }; + + """); } -}"; - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task FormatSlicePattern_NoSpace() - { - var code = @"class C -{ - void M() { -_ = this is[ 0,..var rest ]; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] + public async Task FormatAttributeOnLambda_TwoAttributes() { - _ = this is [0, .. var rest]; + await AssertFormatAsync( + expected: """ + + var f = [Attribute][Attribute2] () => { }; + + """, + code: """ + + var f = [Attribute] [Attribute2] () => { }; + + """); } -}"; - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task FormatSlicePatternWithAnd() - { - var code = @"class C -{ - void M() { -_ = this is[ 0,.. {Count: >0} and var rest ]; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] + public async Task FormatAttributeOnMethod_TwoAttributes() { - _ = this is [0, .. { Count: > 0 } and var rest]; + await AssertFormatAsync( + expected: """ + + [Attribute][Attribute2] + void M() + { } + + """, + code: """ + + [Attribute] [Attribute2] + void M() + { } + + """); } -}"; - await AssertFormatAsync(expectedCode, code); - } - [Fact] - public async Task FormatLengthAndListPattern() - { - var code = @"class C -{ - void M() { -_ = this is{Count:>0 and var x}and[ 1,2,3 ]; -} -}"; - var expectedCode = @"class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] + public async Task FormatAttributeOnTypeParameter_TwoAttributes() { - _ = this is { Count: > 0 and var x } and [1, 2, 3]; - } -}"; - await AssertFormatAsync(expectedCode, code); - } + await AssertFormatAsync( + expected: """ - [Fact] - public async Task LambdaReturnType_01() - { - await AssertFormatAsync( -@"class Program -{ - Delegate D = void () => { }; -}", -@"class Program -{ - Delegate D = void () => { }; -}"); - } + class C<[Attribute][Attribute2] T> { } - [Fact] - public async Task LambdaReturnType_02() - { - await AssertFormatAsync( -@"class Program -{ - Delegate D = A.B () => { }; -}", -@"class Program -{ - Delegate D = A.B()=>{ }; -}"); - } + """, + code: """ - [Fact] - public async Task LambdaReturnType_03() - { - await AssertFormatAsync( -@"class Program -{ - Delegate D = A (x) => x; -}", -@"class Program -{ - Delegate D = A < B > ( x ) => x; -}"); - } + class C< [Attribute] [Attribute2] T > { } - [Fact] - public async Task LambdaReturnType_04() - { - await AssertFormatAsync( -@"class Program -{ - object F = Func((A, B) ((A, B) t) => t); -}", -@"class Program -{ - object F = Func((A,B)((A,B)t)=>t); -}"); - } + """); + } - [Fact] - public async Task LineSpanDirective() - { - var optionSet = new OptionsCollection(LanguageNames.CSharp) { { FormattingOptions2.UseTabs, true } }; - await AssertFormatAsync( -@"class Program -{ - static void Main() - { -#line (1, 1) - (1, 100) 5 ""a.razor"" - } -}", -@"class Program -{ - static void Main() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] + public async Task FormatAttributeOnTypeParameter_TwoAttributes_Method() { -#line (1,1)-(1,100) 5 ""a.razor"" - } -}", changedOptionSet: optionSet); - } + await AssertFormatAsync( + expected: """ - [Fact] - public async Task FileScopedNamespace() - { - await AssertFormatAsync( - expected: @" -namespace NS; + class C + { + void M<[Attribute][Attribute2] T>() { } + } -class C { } -", - code: @" -namespace NS; + """, + code: """ - class C { } -"); - } + class C + { + void M< [Attribute] [Attribute2] T > ( ) { } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] - public async Task NewInImplicitObjectCreation() - { - await AssertFormatAsync( - expected: @" -class C -{ - void M() - { - string v = new(); + """); } -} -", - code: @" -class C -{ - void M() { - string v = new (); - } -} -"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] - public async Task NewInTupleArrayCreation() - { - await AssertFormatAsync( - expected: @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] + public async Task FormatAttributeOnParameter_TwoAttributes() { - var v = new (int, int)[]; - } -} -", - code: @" -class C -{ - void M() { - var v = new (int, int) [ ]; + await AssertFormatAsync( + expected: """ + + class C + { + void M([Attribute][Attribute2] T t) { } + } + + """, + code: """ + + class C + { + void M( [Attribute] [Attribute2] T t ) { } + } + + """); } -} -"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] - public async Task NewInArrayCreation() - { - await AssertFormatAsync( - expected: @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] + public async Task FormatAttributeOnLambdaWithExplicitType() { - var v = new int[1]; - } -} -", - code: @" -class C -{ - void M() { - var v = new int [ 1 ]; + await AssertFormatAsync( + expected: """ + + var f = [Attribute] int () => 1; + + """, + code: """ + + var f = [Attribute] int () => 1; + + """); } -} -"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] - public async Task NewInImplicitArrayCreation() - { - await AssertFormatAsync( - expected: @" -class C -{ - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] + public async Task FormatAttributeOnLambdaInInvocation() { - var v = new[] { 1, 2, 3 }; - } -} -", - code: @" -class C -{ - void M() { - var v = new [ ] { 1, 2, 3 }; + await AssertFormatAsync( + expected: """ + + f([Attribute] () => { }); + + """, + code: """ + + f( [Attribute] () => { }); + + """); } -} -"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] - public async Task NewInConstructorConstraint() - { - await AssertFormatAsync( - expected: @" -class C -{ - void M() where T : new() + [Fact] + public async Task FormatAttributeOnLambdaParameter() { + await AssertFormatAsync(expected: """ + var f = ([Attribute] int x = 1) => x; + """, code: """ + var f = ( [ Attribute ]int x=1)=>x; + """); } -} -", - code: @" -class C -{ - void M() where T : new ( ) { - } -} -"); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] - public async Task NewMethodOverloadWithTupleReturnType() - { - await AssertFormatAsync( - expected: @" -class C -{ - new (int, int) M() { } -} -", - code: @" -class C -{ - new (int, int) M() { } -} -"); - } + [Fact] + public async Task FormatRawStringInterpolation() + { + await AssertFormatAsync( + expected: """" - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] - public async Task NewPropertyWithTupleReturnType() - { - await AssertFormatAsync( - expected: @" -class C -{ - new (int, int) Property { get; set; } -} -", - code: @" -class C -{ - new (int, int) Property { get; set; } -} -"); - } + var s = $"""{s}""" - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56498")] - public async Task NewIndexerWithTupleReturnType() - { - await AssertFormatAsync( - expected: @" -class C -{ - new (int, int) this[int i] { get => throw null; } -} -", - code: @" -class C -{ - new (int, int) this[int i] { get => throw null; } -} -"); - } + """", + code: """" - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] - public async Task FormatAttributeOnLambda() - { - await AssertFormatAsync( - expected: @" -var f = [Attribute] () => { }; -", - code: @" -var f = [Attribute] () => { }; -"); - } + var s = $"""{s}""" - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] - public async Task FormatAttributeOnLambda_TwoAttributes() - { - await AssertFormatAsync( - expected: @" -var f = [Attribute][Attribute2] () => { }; -", - code: @" -var f = [Attribute] [Attribute2] () => { }; -"); - } + """"); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] - public async Task FormatAttributeOnMethod_TwoAttributes() - { - await AssertFormatAsync( - expected: @" -[Attribute][Attribute2] -void M() -{ } -", - code: @" - [Attribute] [Attribute2] -void M() -{ } -"); - } + [Fact] + public async Task FormatRawStringInterpolation2() + { + await AssertFormatAsync( + expected: """" - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] - public async Task FormatAttributeOnTypeParameter_TwoAttributes() - { - await AssertFormatAsync( - expected: @" -class C<[Attribute][Attribute2] T> { } -", - code: @" -class C< [Attribute] [Attribute2] T > { } -"); - } + var s = $"""{s,0: x }""" - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] - public async Task FormatAttributeOnTypeParameter_TwoAttributes_Method() - { - await AssertFormatAsync( - expected: @" -class C -{ - void M<[Attribute][Attribute2] T>() { } -} -", - code: @" -class C -{ - void M< [Attribute] [Attribute2] T > ( ) { } -} -"); - } + """", + code: """" - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] - public async Task FormatAttributeOnParameter_TwoAttributes() - { - await AssertFormatAsync( - expected: @" -class C -{ - void M([Attribute][Attribute2] T t) { } -} -", - code: @" -class C -{ - void M( [Attribute] [Attribute2] T t ) { } -} -"); - } + var s = $"""{s, 0 : x }""" - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] - public async Task FormatAttributeOnLambdaWithExplicitType() - { - await AssertFormatAsync( - expected: @" -var f = [Attribute] int () => 1; -", - code: @" -var f = [Attribute] int () => 1; -"); - } + """"); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56543")] - public async Task FormatAttributeOnLambdaInInvocation() - { - await AssertFormatAsync( - expected: @" -f([Attribute] () => { }); -", - code: @" -f( [Attribute] () => { }); -"); - } + [Fact] + public async Task FormatUsingAliasToType1() + { + await AssertFormatAsync( + expected: """ - [Fact] - public async Task FormatAttributeOnLambdaParameter() - { - await AssertFormatAsync(expected: """ - var f = ([Attribute] int x = 1) => x; - """, code: """ - var f = ( [ Attribute ]int x=1)=>x; - """); - } + f([Attribute] () => { }); - [Fact] - public async Task FormatRawStringInterpolation() - { - await AssertFormatAsync( - expected: @" -var s = $""""""{s}"""""" -", - code: @" -var s = $""""""{s}"""""" -"); - } + """, + code: """ - [Fact] - public async Task FormatRawStringInterpolation2() - { - await AssertFormatAsync( - expected: @" -var s = $""""""{s,0: x }"""""" -", - code: @" -var s = $""""""{s, 0 : x }"""""" -"); - } + f( [Attribute] () => { }); - [Fact] - public async Task FormatUsingAliasToType1() - { - await AssertFormatAsync( - expected: @" -f([Attribute] () => { }); -", - code: @" -f( [Attribute] () => { }); -"); - } + """); + } - [Theory] - [InlineData("using X=int ;", "using X = int;")] - [InlineData("global using X=int ;", "global using X = int;")] - [InlineData("using X=nint;", "using X = nint;")] - [InlineData("using X=dynamic;", "using X = dynamic;")] - [InlineData("using X=int [] ;", "using X = int[];")] - [InlineData("using X=(int,int) ;", "using X = (int, int);")] - [InlineData("using unsafe X=int * ;", "using unsafe X = int*;")] - [InlineData("global using unsafe X=int * ;", "global using unsafe X = int*;")] - [InlineData("using X=int ?;", "using X = int?;")] - [InlineData("using X=delegate * ;", "using X = delegate*;")] - public async Task TestNormalizeUsingAlias(string text, string expected) - { - await AssertFormatAsync(expected, text); - } + [Theory] + [InlineData("using X=int ;", "using X = int;")] + [InlineData("global using X=int ;", "global using X = int;")] + [InlineData("using X=nint;", "using X = nint;")] + [InlineData("using X=dynamic;", "using X = dynamic;")] + [InlineData("using X=int [] ;", "using X = int[];")] + [InlineData("using X=(int,int) ;", "using X = (int, int);")] + [InlineData("using unsafe X=int * ;", "using unsafe X = int*;")] + [InlineData("global using unsafe X=int * ;", "global using unsafe X = int*;")] + [InlineData("using X=int ?;", "using X = int?;")] + [InlineData("using X=delegate * ;", "using X = delegate*;")] + public async Task TestNormalizeUsingAlias(string text, string expected) + { + await AssertFormatAsync(expected, text); } } diff --git a/src/Workspaces/CSharpTest/Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj b/src/Workspaces/CSharpTest/Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj index 65dae6561ce44..065c2a4dd7aed 100644 --- a/src/Workspaces/CSharpTest/Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj +++ b/src/Workspaces/CSharpTest/Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj @@ -7,6 +7,9 @@ $(NetVSShared);net472 + + + diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ICompilationExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ICompilationExtensions.cs index 2a8b64755a480..d28f62304e326 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ICompilationExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ICompilationExtensions.cs @@ -3,8 +3,10 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; +using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -69,12 +71,24 @@ public static ImmutableArray GetReferencedAssemblySymbols(this return builder.ToImmutableAndFree(); } + public static INamedTypeSymbol? ArgumentExceptionType(this Compilation compilation) + => compilation.GetTypeByMetadataName(typeof(ArgumentException).FullName!); + + public static INamedTypeSymbol? ArgumentNullExceptionType(this Compilation compilation) + => compilation.GetTypeByMetadataName(typeof(ArgumentNullException).FullName!); + public static INamedTypeSymbol? ArrayType(this Compilation compilation) => compilation.GetTypeByMetadataName(typeof(Array).FullName!); public static INamedTypeSymbol? AttributeType(this Compilation compilation) => compilation.GetTypeByMetadataName(typeof(Attribute).FullName!); + public static INamedTypeSymbol? BlockingCollectionOfTType(this Compilation compilation) + => compilation.GetTypeByMetadataName(typeof(BlockingCollection<>).FullName!); + + public static INamedTypeSymbol? CollectionOfTType(this Compilation compilation) + => compilation.GetTypeByMetadataName(typeof(Collection<>).FullName!); + public static INamedTypeSymbol? ExceptionType(this Compilation compilation) => compilation.GetTypeByMetadataName(typeof(Exception).FullName!);