diff --git a/src/Analyzers/CSharp/Analyzers/UseIndexOrRangeOperator/CSharpUseRangeOperatorDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseIndexOrRangeOperator/CSharpUseRangeOperatorDiagnosticAnalyzer.cs index f6bfbb9944301..c8d7838f53517 100644 --- a/src/Analyzers/CSharp/Analyzers/UseIndexOrRangeOperator/CSharpUseRangeOperatorDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseIndexOrRangeOperator/CSharpUseRangeOperatorDiagnosticAnalyzer.cs @@ -311,8 +311,6 @@ private Diagnostic CreateDiagnostic(Result result, NotificationOption2 notificat { // Keep track of the invocation node var invocation = result.Invocation; - var additionalLocations = ImmutableArray.Create( - invocation.GetLocation()); // Mark the span under the two arguments to .Slice(..., ...) as what we will be // updating. @@ -325,7 +323,7 @@ private Diagnostic CreateDiagnostic(Result result, NotificationOption2 notificat location, notificationOption, analyzerOptions, - additionalLocations, + [invocation.GetLocation()], ImmutableDictionary.Empty, result.SliceLikeMethod.Name); } diff --git a/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs index 46c989508c2ed..9ba94be199535 100644 --- a/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MisplacedUsingDirectives/MisplacedUsingDirectivesCodeFixProvider.cs @@ -328,10 +328,9 @@ private static SyntaxList GetMembers(SyntaxNode node) private static TSyntaxNode RemoveLeadingBlankLinesFromFirstMember(TSyntaxNode node) where TSyntaxNode : SyntaxNode { var members = GetMembers(node); - if (members.Count == 0) + if (members is not [var firstMember, ..]) return node; - var firstMember = members.First(); var firstMemberTrivia = firstMember.GetLeadingTrivia(); // If there is no leading trivia, then return the node as it is. @@ -367,10 +366,9 @@ private static IEnumerable> SplitIntoLines(SyntaxTrivi private static TSyntaxNode EnsureLeadingBlankLineBeforeFirstMember(TSyntaxNode node) where TSyntaxNode : SyntaxNode { var members = GetMembers(node); - if (members.Count == 0) + if (members is not [var firstMember, ..]) return node; - var firstMember = members.First(); var firstMemberTrivia = firstMember.GetLeadingTrivia(); // If the first member already contains a leading new line then, this will already break up the usings from these members. diff --git a/src/Analyzers/Core/Analyzers/Helpers/HashCodeAnalyzer/HashCodeAnalyzer.cs b/src/Analyzers/Core/Analyzers/Helpers/HashCodeAnalyzer/HashCodeAnalyzer.cs index 4931395a53f80..f158e00b66003 100644 --- a/src/Analyzers/Core/Analyzers/Helpers/HashCodeAnalyzer/HashCodeAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/Helpers/HashCodeAnalyzer/HashCodeAnalyzer.cs @@ -14,23 +14,15 @@ namespace Microsoft.CodeAnalysis.Shared.Utilities; /// /// Helper code to support analysis of HashCode methods /// -internal readonly partial struct HashCodeAnalyzer +internal readonly partial struct HashCodeAnalyzer( + IMethodSymbol objectGetHashCodeMethod, + INamedTypeSymbol? equalityComparerType, + INamedTypeSymbol systemHashCodeType) { - private readonly Compilation _compilation; - private readonly IMethodSymbol _objectGetHashCodeMethod; - private readonly INamedTypeSymbol? _equalityComparerType; + private readonly IMethodSymbol _objectGetHashCodeMethod = objectGetHashCodeMethod; + private readonly INamedTypeSymbol? _equalityComparerType = equalityComparerType; - public readonly INamedTypeSymbol SystemHashCodeType; - - private HashCodeAnalyzer( - Compilation compilation, IMethodSymbol objectGetHashCodeMethod, - INamedTypeSymbol? equalityComparerType, INamedTypeSymbol systemHashCodeType) - { - _compilation = compilation; - _objectGetHashCodeMethod = objectGetHashCodeMethod; - _equalityComparerType = equalityComparerType; - SystemHashCodeType = systemHashCodeType; - } + public readonly INamedTypeSymbol SystemHashCodeType = systemHashCodeType; public static bool TryGetAnalyzer(Compilation compilation, [NotNullWhen(true)] out HashCodeAnalyzer analyzer) { @@ -47,7 +39,7 @@ public static bool TryGetAnalyzer(Compilation compilation, [NotNullWhen(true)] o if (systemHashCodeType == null) return false; - analyzer = new HashCodeAnalyzer(compilation, objectGetHashCodeMethod, equalityComparerType, systemHashCodeType); + analyzer = new HashCodeAnalyzer(objectGetHashCodeMethod, equalityComparerType, systemHashCodeType); return true; } @@ -129,31 +121,19 @@ public static bool TryGetAnalyzer(Compilation compilation, [NotNullWhen(true)] o // First statement has to be the declaration of the accumulator. // Last statement has to be the return of it. - if (statements.First() is not IVariableDeclarationGroupOperation varDeclStatement || - !(statements.Last() is IReturnOperation { ReturnedValue: { } returnedValue })) - { + if (statements is not [IVariableDeclarationGroupOperation varDeclStatement, .., IReturnOperation { ReturnedValue: { } returnedValue }]) return null; - } var variables = varDeclStatement.GetDeclaredVariables(); - if (variables.Length != 1 || - varDeclStatement.Declarations.Length != 1) - { + if (variables.Length != 1) return null; - } - var declaration = varDeclStatement.Declarations[0]; - if (declaration.Declarators.Length != 1) - { + if (varDeclStatement.Declarations is not [{ Declarators: [var declarator] } declaration]) return null; - } - var declarator = declaration.Declarators[0]; var initializerValue = declaration.Initializer?.Value ?? declarator.Initializer?.Value; if (initializerValue == null) - { return null; - } var hashCodeVariable = declarator.Symbol; if (!(IsLocalReference(returnedValue, hashCodeVariable))) diff --git a/src/EditorFeatures/Core/InlineRename/InlineRenameSession.OpenTextBufferManager.cs b/src/EditorFeatures/Core/InlineRename/InlineRenameSession.OpenTextBufferManager.cs index 63bfdce6c2549..9a7ddc572ed2e 100644 --- a/src/EditorFeatures/Core/InlineRename/InlineRenameSession.OpenTextBufferManager.cs +++ b/src/EditorFeatures/Core/InlineRename/InlineRenameSession.OpenTextBufferManager.cs @@ -231,7 +231,7 @@ private void OnTextBufferChanged(object sender, TextContentChangedEventArgs args var spansTouchedInEdit = new NormalizedSpanCollection(args.Changes.Select(c => c.NewSpan)); var intersectionSpans = NormalizedSpanCollection.Intersection(trackingSpansAfterEdit, spansTouchedInEdit); - if (intersectionSpans.Count == 0) + if (intersectionSpans is not ([var firstSpan, ..] and [.., var lastSpan])) { // In Razor we sometimes get formatting changes during inline rename that // do not intersect with any of our spans. Ideally this shouldn't happen at @@ -243,7 +243,7 @@ private void OnTextBufferChanged(object sender, TextContentChangedEventArgs args // spans, but they should still all map to a single tracked rename span (e.g. // renaming "two" to "one two three" may be interpreted as two distinct // additions of "one" and "three"). - var boundingIntersectionSpan = Span.FromBounds(intersectionSpans.First().Start, intersectionSpans.Last().End); + var boundingIntersectionSpan = Span.FromBounds(firstSpan.Start, lastSpan.End); var trackingSpansTouched = GetEditableSpansForSnapshot(args.After).Where(ss => ss.IntersectsWith(boundingIntersectionSpan)); Debug.Assert(trackingSpansTouched.Count() == 1); diff --git a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_TagsChanged.cs b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_TagsChanged.cs index a0862bffeebb7..c81993f1f283d 100644 --- a/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_TagsChanged.cs +++ b/src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_TagsChanged.cs @@ -50,14 +50,14 @@ private ValueTask ProcessTagsChangedAsync( foreach (var collection in snapshotSpans) { - if (collection.Count == 0) + if (collection is not ([var firstSpan, ..] and [.., var lastSpan])) continue; - var snapshot = collection.First().Snapshot; + var snapshot = firstSpan.Snapshot; // Coalesce the spans if there are a lot of them. var coalesced = collection.Count > CoalesceDifferenceCount - ? new NormalizedSnapshotSpanCollection(snapshot.GetSpanFromBounds(collection.First().Start, collection.Last().End)) + ? new NormalizedSnapshotSpanCollection(snapshot.GetSpanFromBounds(firstSpan.Start, lastSpan.End)) : collection; _dataSource.BeforeTagsChanged(snapshot); diff --git a/src/EditorFeatures/Core/Tagging/AsynchronousViewportTaggerProvider.SingleViewportTaggerProvider.cs b/src/EditorFeatures/Core/Tagging/AsynchronousViewportTaggerProvider.SingleViewportTaggerProvider.cs index f34ed12125033..079df1441acf3 100644 --- a/src/EditorFeatures/Core/Tagging/AsynchronousViewportTaggerProvider.SingleViewportTaggerProvider.cs +++ b/src/EditorFeatures/Core/Tagging/AsynchronousViewportTaggerProvider.SingleViewportTaggerProvider.cs @@ -74,12 +74,11 @@ protected override bool CancelOnNewWork // that, determine the start/end line for the buffer that is in view. var visibleSpan = textView.TextViewLines.FormattedSpan; var visibleSpansInBuffer = textView.BufferGraph.MapDownToBuffer(visibleSpan, SpanTrackingMode.EdgeInclusive, subjectBuffer); - if (visibleSpansInBuffer.Count == 0) + if (visibleSpansInBuffer is not ([var firstVisibleSpan, ..] and [.., var lastVisibleSpan])) return null; - var visibleStart = visibleSpansInBuffer.First().Start; - var visibleEnd = visibleSpansInBuffer.Last().End; - + var visibleStart = firstVisibleSpan.Start; + var visibleEnd = lastVisibleSpan.End; var snapshot = subjectBuffer.CurrentSnapshot; var startLine = visibleStart.GetContainingLineNumber(); var endLine = visibleEnd.GetContainingLineNumber(); diff --git a/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs b/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs index fbf6694b316ba..b244a54ebf846 100644 --- a/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs +++ b/src/Features/CSharp/Portable/ConvertIfToSwitch/CSharpConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertIfToSwitch; internal sealed partial class CSharpConvertIfToSwitchCodeRefactoringProvider { - private static readonly Dictionary s_operatorMap = new Dictionary + private static readonly Dictionary s_operatorMap = new() { { BinaryOperatorKind.LessThan, SyntaxKind.LessThanToken }, { BinaryOperatorKind.GreaterThan, SyntaxKind.GreaterThanToken }, @@ -27,13 +27,12 @@ internal sealed partial class CSharpConvertIfToSwitchCodeRefactoringProvider { BinaryOperatorKind.GreaterThanOrEqual, SyntaxKind.GreaterThanEqualsToken }, }; - public override SyntaxNode CreateSwitchExpressionStatement(SyntaxNode target, ImmutableArray sections, Feature feature) - { - return ReturnStatement( + public override SyntaxNode CreateSwitchExpressionStatement( + ExpressionSyntax target, ImmutableArray sections, Feature feature) + => ReturnStatement( SwitchExpression( - (ExpressionSyntax)target, + target, [.. sections.Select(section => AsSwitchExpressionArmSyntax(section, feature))])); - } private static SwitchExpressionArmSyntax AsSwitchExpressionArmSyntax(AnalyzedSwitchSection section, Feature feature) { @@ -59,23 +58,24 @@ private static SwitchExpressionArmSyntax AsSwitchExpressionArmSyntax(AnalyzedSwi private static ExpressionSyntax AsExpressionSyntax(IOperation operation) => operation switch { - IReturnOperation { ReturnedValue: { } value } => (ExpressionSyntax)value.Syntax, - IThrowOperation { Exception: { } exception } => ThrowExpression((ExpressionSyntax)exception.Syntax), - IBlockOperation op => AsExpressionSyntax(op.Operations.Single()), + IReturnOperation { ReturnedValue.Syntax: ExpressionSyntax value } => value, + IThrowOperation { Exception.Syntax: ExpressionSyntax exception } => ThrowExpression(exception), + IBlockOperation { Operations: [var op] } => AsExpressionSyntax(op), var v => throw ExceptionUtilities.UnexpectedValue(v.Kind) }; - public override SyntaxNode CreateSwitchStatement(IfStatementSyntax ifStatement, SyntaxNode expression, IEnumerable sectionList) + public override SyntaxNode CreateSwitchStatement( + IfStatementSyntax ifStatement, ExpressionSyntax expression, IEnumerable sectionList) { var block = ifStatement.Statement as BlockSyntax; return SwitchStatement( - switchKeyword: SwitchKeyword.WithTriviaFrom(ifStatement.IfKeyword), - openParenToken: ifStatement.OpenParenToken, - expression: (ExpressionSyntax)expression, - closeParenToken: ifStatement.CloseParenToken.WithPrependedLeadingTrivia(ElasticMarker), - openBraceToken: block?.OpenBraceToken ?? OpenBraceToken, - sections: [.. sectionList.Cast()], - closeBraceToken: block?.CloseBraceToken.WithoutLeadingTrivia() ?? CloseBraceToken); + SwitchKeyword.WithTriviaFrom(ifStatement.IfKeyword), + ifStatement.OpenParenToken, + expression, + ifStatement.CloseParenToken.WithPrependedLeadingTrivia(ElasticMarker), + block?.OpenBraceToken ?? OpenBraceToken, + [.. sectionList.Cast()], + block?.CloseBraceToken.WithoutLeadingTrivia() ?? CloseBraceToken); } private static WhenClauseSyntax? AsWhenClause(AnalyzedSwitchLabel label) diff --git a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs index 3de10e2e95ec5..9794ced6bf2ff 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs @@ -18,7 +18,6 @@ using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; @@ -2678,14 +2677,14 @@ protected override TextSpan GetExceptionHandlingRegion(SyntaxNode node, out bool tryStatement = (TryStatementSyntax)node; coversAllChildren = false; - if (tryStatement.Catches.Count == 0) + if (tryStatement.Catches is not [var firstCatch, ..]) { RoslynDebug.Assert(tryStatement.Finally != null); return tryStatement.Finally.Span; } return TextSpan.FromBounds( - tryStatement.Catches.First().SpanStart, + firstCatch.SpanStart, (tryStatement.Finally != null) ? tryStatement.Finally.Span.End : tryStatement.Catches.Last().Span.End); diff --git a/src/Features/CSharp/Portable/GenerateConstructors/CSharpGenerateConstructorsCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/GenerateConstructors/CSharpGenerateConstructorsCodeRefactoringProvider.cs index 871064e1ddb43..7dd5413db607d 100644 --- a/src/Features/CSharp/Portable/GenerateConstructors/CSharpGenerateConstructorsCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/GenerateConstructors/CSharpGenerateConstructorsCodeRefactoringProvider.cs @@ -91,8 +91,8 @@ protected override async ValueTask PrefersThrowExpressionAsync(Document do return GetAccessedMemberName(arrowExpression.Expression); // { return this.name; } - if (body is BlockSyntax { Statements.Count: > 0 } block) - return GetAccessedMemberName(block.Statements.First()); + if (body is BlockSyntax { Statements: [var firstStatement, ..] }) + return GetAccessedMemberName(firstStatement); return null; } diff --git a/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Analyzer.cs b/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Analyzer.cs index e9e407707f585..c57f80b7da3a0 100644 --- a/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Analyzer.cs +++ b/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Analyzer.cs @@ -56,7 +56,8 @@ internal abstract class Analyzer(ISyntaxFacts syntaxFacts, AbstractConvertIfToSw /// /// Note that this is initially unset until we find a non-constant expression. /// - private SyntaxNode _switchTargetExpression = null!; + private TExpressionSyntax _switchTargetExpression = null!; + /// /// Holds the type of the /// @@ -68,7 +69,7 @@ internal abstract class Analyzer(ISyntaxFacts syntaxFacts, AbstractConvertIfToSw public bool Supports(Feature feature) => (Features & feature) != 0; - public (ImmutableArray, SyntaxNode TargetExpression) AnalyzeIfStatementSequence(ReadOnlySpan operations) + public (ImmutableArray, TExpressionSyntax TargetExpression) AnalyzeIfStatementSequence(ReadOnlySpan operations) { using var _ = ArrayBuilder.GetInstance(out var sections); if (!ParseIfStatementSequence(operations, sections, topLevel: true, out var defaultBodyOpt)) @@ -450,7 +451,9 @@ private bool CheckTargetExpression(IOperation operation) { operation = operation.WalkDownConversion(); - var expression = operation.Syntax; + if (operation.Syntax is not TExpressionSyntax expression) + return false; + // If we have not figured the switch expression yet, // we will assume that the first expression is the one. if (_switchTargetExpression is null) diff --git a/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs b/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs index 6473bfa66d988..3819ae7b88b6b 100644 --- a/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs +++ b/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs @@ -18,15 +18,15 @@ namespace Microsoft.CodeAnalysis.ConvertIfToSwitch; internal abstract partial class AbstractConvertIfToSwitchCodeRefactoringProvider< TIfStatementSyntax, TExpressionSyntax, TIsExpressionSyntax, TPatternSyntax> { - public abstract SyntaxNode CreateSwitchExpressionStatement(SyntaxNode target, ImmutableArray sections, Feature feature); - public abstract SyntaxNode CreateSwitchStatement(TIfStatementSyntax ifStatement, SyntaxNode target, IEnumerable sectionList); + public abstract SyntaxNode CreateSwitchExpressionStatement(TExpressionSyntax target, ImmutableArray sections, Feature feature); + public abstract SyntaxNode CreateSwitchStatement(TIfStatementSyntax ifStatement, TExpressionSyntax target, IEnumerable sectionList); public abstract IEnumerable AsSwitchSectionStatements(IOperation operation); public abstract SyntaxNode AsSwitchLabelSyntax(AnalyzedSwitchLabel label, Feature feature); protected abstract SyntaxTriviaList GetLeadingTriviaToTransfer(SyntaxNode syntaxToRemove); private async Task UpdateDocumentAsync( Document document, - SyntaxNode target, + TExpressionSyntax target, TIfStatementSyntax ifStatement, ImmutableArray sections, Feature feature, @@ -46,8 +46,7 @@ private async Task UpdateDocumentAsync( @switch = @switch .WithLeadingTrivia(ifStatement.GetLeadingTrivia()) .WithTrailingTrivia(lastNode.GetTrailingTrivia()) - .WithAdditionalAnnotations(Formatter.Annotation) - .WithAdditionalAnnotations(Simplifier.Annotation); + .WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation); var nodesToRemove = sections.Skip(1).Select(s => s.SyntaxToRemove).Where(s => s.Parent == ifStatement.Parent); root = root.RemoveNodes(nodesToRemove, SyntaxRemoveOptions.KeepNoTrivia); diff --git a/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.cs index 2b215f791388a..2723f8b73cfb1 100644 --- a/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertIfToSwitch/AbstractConvertIfToSwitchCodeRefactoringProvider.cs @@ -42,7 +42,9 @@ public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContex var ifStatement = await context.TryGetRelevantNodeAsync().ConfigureAwait(false); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var syntaxFactsService = document.GetRequiredLanguageService(); - if (!ShouldOfferRefactoring(ifStatement, semanticModel, syntaxFactsService, out var analyzer, out var sections, out var target)) + if (!ShouldOfferRefactoring( + ifStatement, semanticModel, syntaxFactsService, + out var analyzer, out var sections, out var target)) { return; } @@ -72,7 +74,7 @@ private bool ShouldOfferRefactoring( ISyntaxFactsService syntaxFactsService, [NotNullWhen(true)] out Analyzer? analyzer, [NotNullWhen(true)] out ImmutableArray sections, - [NotNullWhen(true)] out SyntaxNode? target) + [NotNullWhen(true)] out TExpressionSyntax? target) { analyzer = null; sections = default; diff --git a/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.Rewriting.vb b/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.Rewriting.vb index c80d4ba0c1b45..1e8872e650b97 100644 --- a/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.Rewriting.vb +++ b/src/Features/VisualBasic/Portable/ConvertIfToSwitch/VisualBasicConvertIfToSwitchCodeRefactoringProvider.Rewriting.vb @@ -20,11 +20,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertIfToSwitch {BinaryOperatorKind.GreaterThanOrEqual, (SyntaxKind.CaseGreaterThanOrEqualClause, SyntaxKind.GreaterThanEqualsToken)} } - Public Overrides Function CreateSwitchExpressionStatement(target As SyntaxNode, sections As ImmutableArray(Of AnalyzedSwitchSection), feature As Feature) As SyntaxNode + Public Overrides Function CreateSwitchExpressionStatement(target As ExpressionSyntax, sections As ImmutableArray(Of AnalyzedSwitchSection), feature As Feature) As SyntaxNode Throw ExceptionUtilities.Unreachable End Function - Public Overrides Function CreateSwitchStatement(ifStatement As ExecutableStatementSyntax, expression As SyntaxNode, sectionList As IEnumerable(Of SyntaxNode)) As SyntaxNode + Public Overrides Function CreateSwitchStatement(ifStatement As ExecutableStatementSyntax, expression As ExpressionSyntax, sectionList As IEnumerable(Of SyntaxNode)) As SyntaxNode Return VisualBasicSyntaxGenerator.Instance.SwitchStatement(expression, sectionList) End Function diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/EmbeddedLanguages/VirtualChars/CSharpVirtualCharService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/EmbeddedLanguages/VirtualChars/CSharpVirtualCharService.cs index 3b5dfe1af5ffd..ef1afc430db50 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/EmbeddedLanguages/VirtualChars/CSharpVirtualCharService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/EmbeddedLanguages/VirtualChars/CSharpVirtualCharService.cs @@ -178,7 +178,7 @@ private static VirtualCharSequence TryConvertMultiLineRawStringToVirtualChars( // they start right after some `{...}` interpolation var isFirstChunk = parentExpression is LiteralExpressionSyntax || - (parentExpression is InterpolatedStringExpressionSyntax { Contents: var contents } && contents.First() == token.GetRequiredParent()); + (parentExpression is InterpolatedStringExpressionSyntax { Contents: [var firstContent, ..] } && firstContent == token.GetRequiredParent()); if (parentExpression.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error)) return default; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs index 27be550e94c54..81012f4414972 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs @@ -109,7 +109,7 @@ private void AddSwitchIndentationOperation(List list, Synt var switchStatement = (SwitchStatementSyntax)node.Parent; var lastSection = switchStatement.Sections.Last() == node; - if (section.Statements.Count == 0) + if (section.Statements is not ([var firstStatement, ..] and [.., var lastStatement])) { // even if there is no statement under section, we still want indent operation var lastTokenOfLabel = section.Labels.Last().GetLastToken(includeZeroWidth: true); @@ -121,8 +121,8 @@ private void AddSwitchIndentationOperation(List list, Synt return; } - var startToken = section.Statements.First().GetFirstToken(includeZeroWidth: true); - var endToken = section.Statements.Last().GetLastToken(includeZeroWidth: true); + var startToken = firstStatement.GetFirstToken(includeZeroWidth: true); + var endToken = lastStatement.GetLastToken(includeZeroWidth: true); // see whether we are the last statement var span = CommonFormattingHelpers.GetSpanIncludingTrailingAndLeadingTriviaOfAdjacentTokens(startToken, endToken); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs index 153e48b8a9c08..a4e91ffcd8e60 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs @@ -220,9 +220,9 @@ private static void AddSpecificNodesSuppressOperations(ArrayBuilder nodes, CancellationToken cancellationToken) { - if (nodes.Length > 0) + if (nodes is [var firstNode, ..] and [.., var lastNode]) { - var span = TextSpan.FromBounds(nodes.First().Span.Start, nodes.Last().Span.End); + var span = TextSpan.FromBounds(firstNode.Span.Start, lastNode.Span.End); foreach (var node in nodes) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/CompilationUnitSyntaxExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/CompilationUnitSyntaxExtensions.cs index 19ef52954751c..38bb144fc7df3 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/CompilationUnitSyntaxExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/CompilationUnitSyntaxExtensions.cs @@ -55,8 +55,8 @@ private static TextSpan GetUsingsSpan(CompilationUnitSyntax root, BaseNamespaceD else { var start = 0; - var end = root.Members.Any() - ? root.Members.First().GetFirstToken().Span.End + var end = root.Members is [var firstMember, ..] + ? firstMember.GetFirstToken().Span.End : root.Span.End; return TextSpan.FromBounds(start, end); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/TypeDeclarationSyntaxExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/TypeDeclarationSyntaxExtensions.cs index a182161fcd7c0..aeb4af55c77d1 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/TypeDeclarationSyntaxExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/TypeDeclarationSyntaxExtensions.cs @@ -22,7 +22,7 @@ public static IList GetInsertionIndices(this TypeDeclarationSyntax destina var members = destination.Members; var indices = new List(); - if (members.Count == 0) + if (members is not [var firstMember, ..]) { var start = destination.OpenBraceToken.Span.End; var end = GetEndToken(destination).SpanStart; @@ -32,7 +32,7 @@ public static IList GetInsertionIndices(this TypeDeclarationSyntax destina else { var start = destination.OpenBraceToken.Span.End; - var end = destination.Members.First().SpanStart; + var end = firstMember.SpanStart; indices.Add(!destination.OverlapsHiddenPosition(TextSpan.FromBounds(start, end), cancellationToken)); for (var i = 0; i < members.Count - 1; i++) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Indentation/CSharpIndentationService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Indentation/CSharpIndentationService.cs index d6c46dcb91dc6..67edc4d42e236 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Indentation/CSharpIndentationService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Indentation/CSharpIndentationService.cs @@ -171,13 +171,11 @@ private static bool IsBracketedArgumentListMissingBrackets(BracketedArgumentList private static void ReplaceCaseIndentationRules(List list, SyntaxNode node) { - if (node is not SwitchSectionSyntax section || section.Statements.Count == 0) - { + if (node is not SwitchSectionSyntax { Statements: [var firstStatement, ..] and [.., var lastStatement] }) return; - } - var startToken = section.Statements.First().GetFirstToken(includeZeroWidth: true); - var endToken = section.Statements.Last().GetLastToken(includeZeroWidth: true); + var startToken = firstStatement.GetFirstToken(includeZeroWidth: true); + var endToken = lastStatement.GetLastToken(includeZeroWidth: true); for (var i = 0; i < list.Count; i++) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpRemoveUnnecessaryImportsService.Rewriter.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpRemoveUnnecessaryImportsService.Rewriter.cs index 3fe15eb795dba..ae41f6216372a 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpRemoveUnnecessaryImportsService.Rewriter.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpRemoveUnnecessaryImportsService.Rewriter.cs @@ -231,11 +231,11 @@ private SyntaxNode VisitBaseNamespaceDeclaration( var resultNamespace = namespaceDeclaration.WithUsings(finalUsings); if (finalUsings.Count == 0 && resultNamespace.Externs.Count == 0 && - resultNamespace.Members.Count >= 1) + resultNamespace.Members is [var firstMember, ..]) { // We've removed all the usings and now the first thing in the namespace is a // type. In this case, remove any newlines preceding the type. - var firstToken = resultNamespace.Members.First().GetFirstToken(); + var firstToken = firstMember.GetFirstToken(); var newFirstToken = RemoveUnnecessaryImportsHelpers.StripNewLines(CSharpSyntaxFacts.Instance, firstToken); resultNamespace = resultNamespace.ReplaceToken(firstToken, newFirstToken); }