Skip to content

Commit

Permalink
Merge pull request #66956 from CyrusNajmabadi/usePatterns
Browse files Browse the repository at this point in the history
Update IDE code to use list patterns.
  • Loading branch information
CyrusNajmabadi authored Feb 20, 2023
2 parents 7d69096 + a9fdc85 commit 4190056
Show file tree
Hide file tree
Showing 65 changed files with 102 additions and 219 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,8 @@ methodDeclaration.Parent is not TypeDeclarationSyntax containingTypeDeclaration
return false;

// If the user renamed the 'args' parameter, we can't convert to top level statements.
if (methodDeclaration.ParameterList.Parameters.Count == 1 &&
methodDeclaration.ParameterList.Parameters[0].Identifier.ValueText != "args")
{
if (methodDeclaration.ParameterList.Parameters is [{ Identifier.ValueText: not "args" }])
return false;
}

// Found a suitable candidate. See if this matches the entrypoint the compiler has actually chosen.
var entryPointMethod = semanticModel.Compilation.GetEntryPoint(cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,9 @@ protected UseExpressionBodyHelper(

protected static AccessorDeclarationSyntax? GetSingleGetAccessor(AccessorListSyntax? accessorList)
{
if (accessorList != null &&
accessorList.Accessors.Count == 1 &&
accessorList.Accessors[0].AttributeLists.Count == 0 &&
accessorList.Accessors[0].IsKind(SyntaxKind.GetAccessorDeclaration))
{
return accessorList.Accessors[0];
}

return null;
return accessorList is { Accessors: [{ AttributeLists.Count: 0, RawKind: (int)SyntaxKind.GetAccessorDeclaration } accessor] }
? accessor
: null;
}

protected static BlockSyntax? GetBodyFromSingleGetAccessor(AccessorListSyntax accessorList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ private void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol
{
ReportArrayCreationDiagnostic(context, arrayCreationOperation.Syntax, option.Notification.Severity);
}
else if (elements.Length > 0 && elements[0].Syntax.Parent is ArgumentSyntax)
else if (elements is [{ Syntax.Parent: ArgumentSyntax }, ..])
{
// For regular parameter arrays the code fix will need to search down
ReportParameterArrayDiagnostic(context, arrayCreationOperation.Syntax, elements, option.Notification.Severity, ArrayCreationOperationLocation.Descendants);
}
else if (elements.Length > 0 && elements[0].Syntax.Parent.IsKind(SyntaxKind.CollectionInitializerExpression))
else if (elements is [{ Syntax.Parent: (kind: SyntaxKind.CollectionInitializerExpression) }, ..])
{
// For collection initializers where the Add method takes a parameter array, the code fix
// will have to search up
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -775,8 +775,7 @@ node is XmlElementSyntax element &&
: token);

if (index == 0 &&
tokens.Length >= 2 &&
tokens[0].IsKind(SyntaxKind.XmlTextLiteralNewLineToken))
tokens is [(kind: SyntaxKind.XmlTextLiteralNewLineToken), _, ..])
{
// remove the starting line and trivia from the first line
tokens = tokens.RemoveAt(0);
Expand All @@ -786,10 +785,8 @@ node is XmlElementSyntax element &&
tokens = tokens.Replace(tokens[0], tokens[0].WithoutLeadingTrivia());

if (index == summaryContent.Count - 1 &&
tokens.Length >= 2 &&
tokens[^1].IsKind(SyntaxKind.XmlTextLiteralToken) &&
tokens[^1].Text.GetFirstNonWhitespaceIndexInString() == -1 &&
tokens[^2].IsKind(SyntaxKind.XmlTextLiteralNewLineToken))
tokens is [.., (kind: SyntaxKind.XmlTextLiteralNewLineToken), (kind: SyntaxKind.XmlTextLiteralToken) textLiteral] &&
textLiteral.Text.GetFirstNonWhitespaceIndexInString() == -1)
{
// the last text token contains a new line, then a whitespace only text (which would start the closing tag)
// remove the new line and the trivia from the extra text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ private static TSyntaxNode EnsureLeadingBlankLineBeforeFirstMember<TSyntaxNode>(
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.
if (firstMemberTrivia.Count > 0 && firstMemberTrivia.First().IsKind(SyntaxKind.EndOfLineTrivia))
if (firstMemberTrivia is [(kind: SyntaxKind.EndOfLineTrivia), ..])
return node;

var newFirstMember = firstMember.WithLeadingTrivia(firstMemberTrivia.Insert(0, SyntaxFactory.CarriageReturnLineFeed));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,8 @@ public static bool TryGetAnalyzer(Compilation compilation, [NotNullWhen(true)] o
return default;

// Unwind through nested blocks. This also handles if we're in an 'unchecked' block in C#
while (blockOperation.Operations.Length == 1 &&
blockOperation.Operations[0] is IBlockOperation childBlock)
{
while (blockOperation.Operations is [IBlockOperation childBlock])
blockOperation = childBlock;
}

var statements = blockOperation.Operations.WhereAsArray(o => !o.IsImplicit);
var (accessesBase, members) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -824,15 +824,8 @@ private static bool TryGetSuppressedDiagnosticId(
category = null;

if (suppressMessageAttributeType.Equals(attribute.AttributeClass) &&
attribute.AttributeConstructor?.Parameters.Length >= 2 &&
attribute.AttributeConstructor.Parameters[1].Name == "checkId" &&
attribute.AttributeConstructor.Parameters[1].Type.SpecialType == SpecialType.System_String &&
attribute.ConstructorArguments.Length >= 2 &&
attribute.ConstructorArguments[1] is
{
Kind: TypedConstantKind.Primitive,
Value: string checkId
})
attribute.AttributeConstructor?.Parameters is [_, { Name: "checkId", Type.SpecialType: SpecialType.System_String }, ..] &&
attribute.ConstructorArguments is [_, { Kind: TypedConstantKind.Primitive, Value: string checkId }, ..])
{
// CheckId represents diagnostic ID, followed by an option ':' and name.
// For example, "CA1801:ReviewUnusedParameters"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,15 +587,9 @@ private void AddDebuggerDisplayAttributeArgumentsCore(ISymbol symbol, ArrayBuild
foreach (var attribute in symbol.GetAttributes())
{
if (attribute.AttributeClass == _debuggerDisplayAttributeType &&
attribute.ConstructorArguments.Length == 1 &&
attribute.ConstructorArguments[0] is var arg &&
arg.Kind == TypedConstantKind.Primitive &&
arg.Type.SpecialType == SpecialType.System_String)
attribute.ConstructorArguments is [{ Kind: TypedConstantKind.Primitive, Type.SpecialType: SpecialType.System_String, Value: string value }])
{
if (arg.Value is string value)
{
builder.Add(value);
}
builder.Add(value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,8 @@ parameter.ContainingSymbol is not IMethodSymbol method ||
// as event handlers are required to match this signature
// regardless of whether or not the parameters are used.
if (_eventArgsTypeOpt != null &&
method.Parameters.Length == 2 &&
method.Parameters[0].Type.SpecialType == SpecialType.System_Object &&
method.Parameters[1].Type.InheritsFromOrEquals(_eventArgsTypeOpt))
method.Parameters is [{ Type.SpecialType: SpecialType.System_Object }, var secondParam] &&
secondParam.Type.InheritsFromOrEquals(_eventArgsTypeOpt))
{
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ static bool TryGetLinqWhereExtensionMethod(INamedTypeSymbol enumerableType, [Not
{
var parameters = whereMethodSymbol.Parameters;

if (parameters.Length == 2 &&
parameters.Last().Type is INamedTypeSymbol systemFunc &&
systemFunc.Arity == 2)
if (parameters is [_, { Type: INamedTypeSymbol { Arity: 2 } }])
{
// This is the where overload that does not take and index (i.e. Where(source, Func<T, bool>) vs Where(source, Func<T, int, bool>))
whereMethod = whereMethodSymbol;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,10 +541,8 @@ private static bool ShouldAddBraceForObjectCreationExpression(ObjectCreationExpr
/// This would change field to property, and change event field to event declaration.
/// </summary>
private static bool ShouldAddBraceForBaseFieldDeclaration(BaseFieldDeclarationSyntax baseFieldDeclarationNode)
=> baseFieldDeclarationNode.Declaration.Variables.Count == 1
&& baseFieldDeclarationNode.Declaration.Variables[0].Initializer == null
&& !baseFieldDeclarationNode.Modifiers.Any(SyntaxKind.ReadOnlyKeyword)
&& baseFieldDeclarationNode.SemicolonToken.IsMissing;
=> baseFieldDeclarationNode is { Declaration.Variables: [{ Initializer: null }], SemicolonToken.IsMissing: true }
&& !baseFieldDeclarationNode.Modifiers.Any(SyntaxKind.ReadOnlyKeyword);

private static bool ShouldAddBraceForAccessorDeclaration(AccessorDeclarationSyntax accessorDeclarationNode)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ public static bool RawContentMustBeMultiLine(SourceText text, ImmutableArray<Tex
Contract.ThrowIfTrue(spans.Length == 0);

// Empty raw string must be multiline.
if (spans.Length == 1 && spans[0].IsEmpty)
if (spans is [{ IsEmpty: true }])
return true;

// Or if it starts/ends with a quote
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public AbstractSnippetFunctionGenerateSwitchCases(AbstractSnippetExpansionClient
: base(snippetExpansionClient, subjectBuffer)
{
this.CaseGenerationLocationField = caseGenerationLocationField;
this.SwitchExpressionField = (switchExpressionField.Length >= 2 && switchExpressionField[0] == '$' && switchExpressionField[^1] == '$')
? switchExpressionField[1..^1] : switchExpressionField;
this.SwitchExpressionField = switchExpressionField is ['$', .. var middle, '$'] ? middle : switchExpressionField;
}

protected abstract bool TryGetEnumTypeSymbol(CancellationToken cancellationToken, [NotNullWhen(returnValue: true)] out ITypeSymbol? typeSymbol);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,11 @@ public static async Task<bool> TryPresentLocationOrNavigateIfOneAsync(
if (builder.Count == 0)
return null;

if (builder.Count == 1 &&
builder[0].item.SourceSpans.Length <= 1)
if (builder is [{ item.SourceSpans.Length: <= 1, location: var location }])
{
// There was only one location to navigate to. Just directly go to that location. If we're directly
// going to a location we need to activate the preview so that focus follows to the new cursor position.

return builder[0].location;
return location;
}

if (presenter == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static ISymUnmanagedReader5 OpenDummySymReader(ImmutableArray<byte> pdbIm
pdbImage.WriteToStream(pdbStream);

var pdbStreamCom = SymUnmanagedStreamFactory.CreateStream(pdbStream);
if (pdbImage.Length > 4 && pdbImage[0] == 'B' && pdbImage[1] == 'S' && pdbImage[2] == 'J' && pdbImage[3] == 'B')
if (pdbImage is [(byte)'B', (byte)'S', (byte)'J', (byte)'B', ..])
{
var hr = symBinder.GetReaderFromPdbStream(metadataImportProvider, pdbStreamCom, out var symReader);
Assert.Equal(0, hr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ private static void ReadVisualBasicImportsDebugInfo(
{
RoslynDebug.AssertNotNull(importString);

if (importString.Length > 0 && importString[0] == '*')
if (importString is ['*', ..])
{
string? alias = null;
string? target = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private static string TryRemoveKnownPrefixes(ITypeSymbol type)
{
return name[1..];
}
else if (name.Length == 1 && name[0] == DefaultGenericParameterPrefix)
else if (name is [DefaultGenericParameterPrefix])
{
return ITypeSymbolExtensions.DefaultParameterName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,7 @@ private static async Task<CompletionChange> GetConversionChangeAsync(
if (item.Properties.ContainsKey(RehydrateName))
{
var symbols = await SymbolCompletionItem.GetSymbolsAsync(item, document, cancellationToken).ConfigureAwait(false);
if (symbols.Length == 3 &&
symbols[0] is INamedTypeSymbol containingType &&
symbols[1] is ITypeSymbol fromType &&
symbols[2] is ITypeSymbol toType)
if (symbols is [INamedTypeSymbol containingType, ITypeSymbol fromType, ITypeSymbol toType])
{
return CodeGenerationSymbolFactory.CreateConversionSymbol(
toType: toType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#nullable disable

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.ConvertLinq.ConvertForEachToLinqQuery;
Expand Down Expand Up @@ -35,7 +36,7 @@ public override void Convert(SyntaxEditor editor, bool convertToQuery, Cancellat
// If there is a single statement and it is a block, leave it as is.
// Otherwise, wrap with a block.
var block = WrapWithBlockIfNecessary(
ForEachInfo.Statements.Select(statement => statement.KeepCommentsAndAddElasticMarkers()));
ForEachInfo.Statements.SelectAsArray(statement => statement.KeepCommentsAndAddElasticMarkers()));

editor.ReplaceNode(
ForEachInfo.ForEachStatement,
Expand Down Expand Up @@ -98,7 +99,7 @@ private StatementSyntax CreateDefaultReplacementStatement(
}
}

private static BlockSyntax WrapWithBlockIfNecessary(IEnumerable<StatementSyntax> statements)
=> (statements.Count() == 1 && statements.Single() is BlockSyntax block) ? block : SyntaxFactory.Block(statements);
private static BlockSyntax WrapWithBlockIfNecessary(ImmutableArray<StatementSyntax> statements)
=> statements is [BlockSyntax block] ? block : SyntaxFactory.Block(statements);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private static async Task<ClassDeclarationSyntax> GenerateProgramClassAsync(

// Workaround for simplification not being ready when we generate a new file. Substitute System.String[]
// with string[].
if (method.ParameterList.Parameters.Count == 1 && method.ParameterList.Parameters[0].Type is ArrayTypeSyntax arrayType)
if (method.ParameterList.Parameters is [{ Type: ArrayTypeSyntax arrayType }])
method = method.ReplaceNode(arrayType.ElementType, PredefinedType(Token(SyntaxKind.StringKeyword)));

if (oldClassDeclaration is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,9 @@ protected override bool IsSingleExteriorTrivia(DocumentationCommentTriviaSyntax
existingCommentText = textTokens.Count == 1 ? "" : firstTextToken.ValueText;

return lastTextToken.Kind() == SyntaxKind.XmlTextLiteralNewLineToken
&& firstTextToken.LeadingTrivia.Count == 1
&& firstTextToken.LeadingTrivia.ElementAt(0).Kind() == SyntaxKind.DocumentationCommentExteriorTrivia
&& firstTextToken.LeadingTrivia.ElementAt(0).ToString() == ExteriorTriviaText
&& lastTextToken.TrailingTrivia.Count == 0;
&& lastTextToken.TrailingTrivia.Count == 0
&& firstTextToken.LeadingTrivia is [(kind: SyntaxKind.DocumentationCommentExteriorTrivia) firstTrivia]
&& firstTrivia.ToString() == ExteriorTriviaText;
}

private static IList<SyntaxToken> GetTextTokensFollowingExteriorTrivia(XmlTextSyntax xmlText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public static void AssertIsBody(SyntaxNode syntax, bool allowLambda)
}

public static bool ContainsGlobalStatements(this CompilationUnitSyntax compilationUnit)
=> compilationUnit.Members.Count > 0 && compilationUnit.Members[0] is GlobalStatementSyntax;
=> compilationUnit.Members is [GlobalStatementSyntax, ..];

public static void FindLeafNodeAndPartner(SyntaxNode leftRoot, int leftPosition, SyntaxNode rightRoot, out SyntaxNode leftNode, out SyntaxNode rightNodeOpt)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,13 @@ protected override bool TryInitializeState(

var syntaxTree = semanticDocument.SyntaxTree;
var node = semanticDocument.Root.FindToken(textSpan.Start).GetAncestor<TypeSyntax>();
if (node != null)
if (node is { Parent: BaseTypeSyntax { Parent: BaseListSyntax { Types: [var firstType, ..] } baseList } })
{
if (node.Parent is BaseTypeSyntax && node.Parent.Parent is BaseListSyntax baseList)
if (baseList.Parent is TypeDeclarationSyntax(SyntaxKind.ClassDeclaration or SyntaxKind.RecordDeclaration) parentTypeDecl &&
firstType.Type == node)
{
if (baseList.Parent != null &&
baseList.Types.Count > 0 &&
baseList.Types[0].Type == node &&
baseList?.Parent is (kind: SyntaxKind.ClassDeclaration or SyntaxKind.RecordDeclaration))
{
var semanticModel = semanticDocument.SemanticModel;
classType = semanticModel.GetDeclaredSymbol(baseList.Parent, cancellationToken) as INamedTypeSymbol;
return classType != null;
}
classType = semanticDocument.SemanticModel.GetDeclaredSymbol(parentTypeDecl, cancellationToken);
return classType != null;
}
}

Expand Down
Loading

0 comments on commit 4190056

Please sign in to comment.