private static void AnalyzeSwitchStatement(SyntaxNodeAnalysisContext context) { var switchStatement = (SwitchStatementSyntax)context.Node; SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections; if (!sections.Any()) { return; } ExpressionSyntax switchExpression = switchStatement.Expression; SingleLocalDeclarationStatementInfo localInfo = default; string name = GetName(); if (name == null) { return; } ITypeSymbol kindSymbol = context.SemanticModel.GetTypeSymbol(switchExpression, context.CancellationToken); if (kindSymbol?.HasMetadataName(CSharpMetadataNames.Microsoft_CodeAnalysis_CSharp_SyntaxKind) != true) { return; } foreach (SwitchSectionSyntax section in sections) { SwitchLabelSyntax label = section.Labels.SingleOrDefault(shouldThrow: false); if (label == null) { return; } SyntaxKind labelKind = label.Kind(); if (labelKind == SyntaxKind.DefaultSwitchLabel) { continue; } if (labelKind != SyntaxKind.CaseSwitchLabel) { Debug.Assert(labelKind == SyntaxKind.CasePatternSwitchLabel, labelKind.ToString()); return; } var caseLabel = (CaseSwitchLabelSyntax)label; ExpressionSyntax value = caseLabel.Value; if (!value.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { return; } var memberAccess = (MemberAccessExpressionSyntax)value; if (!(memberAccess.Name is IdentifierNameSyntax identifierName)) { return; } string kindName = identifierName.Identifier.ValueText; if (!_syntaxKindNames.Contains(kindName)) { return; } SyntaxList <StatementSyntax> statements = section.Statements; StatementSyntax statement = statements.FirstOrDefault(); if (statement == null) { return; } if (statement is BlockSyntax block) { statement = block.Statements.FirstOrDefault(); } if (!statement.IsKind(SyntaxKind.LocalDeclarationStatement)) { return; } SingleLocalDeclarationStatementInfo localStatement = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)statement); if (!localStatement.Success) { return; } if (!(localStatement.Value is CastExpressionSyntax castExpression)) { return; } if (!(castExpression.Expression is IdentifierNameSyntax localName)) { return; } if (name != localName.Identifier.ValueText) { return; } if (!IsFixableSyntaxSymbol(castExpression.Type, kindName, context.SemanticModel, context.CancellationToken)) { return; } } if (localInfo.Success && IsLocalVariableReferenced(context, localInfo, switchStatement)) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UsePatternMatching, switchStatement.SwitchKeyword); string GetName() { switch (switchExpression.Kind()) { case SyntaxKind.IdentifierName: { StatementSyntax previousStatement = switchStatement.PreviousStatement(); if (!previousStatement.IsKind(SyntaxKind.LocalDeclarationStatement)) { return(null); } localInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo((LocalDeclarationStatementSyntax)previousStatement); if (!localInfo.Success) { return(null); } if (localInfo.IdentifierText != ((IdentifierNameSyntax)switchExpression).Identifier.ValueText) { return(null); } if (!localInfo.Value.IsKind(SyntaxKind.InvocationExpression)) { return(null); } return(GetName2((InvocationExpressionSyntax)localInfo.Value)); } case SyntaxKind.InvocationExpression: { return(GetName2((InvocationExpressionSyntax)switchExpression)); } default: { return(null); } } }
public static int GetInsertionIndex <TDeclaration>( SyntaxList <TDeclaration> declarationList, TDeclaration declaration, CodeGenerationOptions options, IList <bool> availableIndices, IComparer <TDeclaration> comparerWithoutNameCheck, IComparer <TDeclaration> comparerWithNameCheck, Func <SyntaxList <TDeclaration>, TDeclaration> after = null, Func <SyntaxList <TDeclaration>, TDeclaration> before = null) where TDeclaration : SyntaxNode { Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1); if (options != null) { // Try to strictly obey the after option by inserting immediately after the member containing the location if (options.AfterThisLocation != null) { var afterMember = declarationList.LastOrDefault(m => m.SpanStart <= options.AfterThisLocation.SourceSpan.Start); if (afterMember != null) { var index = declarationList.IndexOf(afterMember); index = GetPreferredIndex(index + 1, availableIndices, forward: true); if (index != -1) { return(index); } } } // Try to strictly obey the before option by inserting immediately before the member containing the location if (options.BeforeThisLocation != null) { var beforeMember = declarationList.FirstOrDefault(m => m.Span.End >= options.BeforeThisLocation.SourceSpan.End); if (beforeMember != null) { var index = declarationList.IndexOf(beforeMember); index = GetPreferredIndex(index, availableIndices, forward: false); if (index != -1) { return(index); } } } if (options.AutoInsertionLocation) { if (declarationList.IsEmpty()) { return(0); } var desiredIndex = TryGetDesiredIndexIfGrouped( declarationList, declaration, availableIndices, comparerWithoutNameCheck, comparerWithNameCheck); if (desiredIndex.HasValue) { return(desiredIndex.Value); } if (after != null) { var member = after(declarationList); if (member != null) { var index = declarationList.IndexOf(member); if (index >= 0) { index = GetPreferredIndex(index + 1, availableIndices, forward: true); if (index != -1) { return(index); } } } } if (before != null) { var member = before(declarationList); if (member != null) { var index = declarationList.IndexOf(member); if (index >= 0) { index = GetPreferredIndex(index, availableIndices, forward: false); if (index != -1) { return(index); } } } } } } // Otherwise, add the declaration to the end. { var index = GetPreferredIndex(declarationList.Count, availableIndices, forward: false); if (index != -1) { return(index); } } return(declarationList.Count); }
public static MemberDeclarationSyntax FirstMember(SyntaxList <MemberDeclarationSyntax> members) { return(members.FirstOrDefault()); }
public static MemberDeclarationSyntax FirstMethod(SyntaxList <MemberDeclarationSyntax> members) { return(members.FirstOrDefault(m => m is MethodDeclarationSyntax)); }
public static int GetInsertionIndex <TDeclaration>( SyntaxList <TDeclaration> declarationList, TDeclaration declaration, CodeGenerationOptions options, IList <bool> availableIndices, Func <SyntaxList <TDeclaration>, TDeclaration> after = null, Func <SyntaxList <TDeclaration>, TDeclaration> before = null) where TDeclaration : SyntaxNode { Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1); if (options != null) { // Try to strictly obey the after option by inserting immediately after the member containing the location if (options.AfterThisLocation != null) { var afterMember = declarationList.LastOrDefault(m => m.SpanStart <= options.AfterThisLocation.SourceSpan.Start); if (afterMember != null) { var index = declarationList.IndexOf(afterMember); index = GetPreferredIndex(index + 1, availableIndices, forward: true); if (index != -1) { return(index); } } } // Try to strictly obey the before option by inserting immediately before the member containing the location if (options.BeforeThisLocation != null) { var beforeMember = declarationList.FirstOrDefault(m => m.Span.End >= options.BeforeThisLocation.SourceSpan.End); if (beforeMember != null) { var index = declarationList.IndexOf(beforeMember); index = GetPreferredIndex(index, availableIndices, forward: false); if (index != -1) { return(index); } } } if (options.AutoInsertionLocation) { if (declarationList.IsEmpty()) { return(0); } else if (declarationList.IsSorted(CSharpDeclarationComparer.Instance)) { var result = Array.BinarySearch(declarationList.ToArray(), declaration, CSharpDeclarationComparer.Instance); var index = GetPreferredIndex(result < 0 ? ~result : result, availableIndices, forward: true); if (index != -1) { return(index); } } if (after != null) { var member = after(declarationList); if (member != null) { var index = declarationList.IndexOf(member); if (index >= 0) { index = GetPreferredIndex(index + 1, availableIndices, forward: true); if (index != -1) { return(index); } } } } if (before != null) { var member = before(declarationList); if (member != null) { var index = declarationList.IndexOf(member); if (index >= 0) { index = GetPreferredIndex(index, availableIndices, forward: false); if (index != -1) { return(index); } } } } } } // Otherwise, add the declaration to the end. { var index = GetPreferredIndex(declarationList.Count, availableIndices, forward: false); if (index != -1) { return(index); } } return(declarationList.Count); }
public static MemberDeclarationSyntax?FirstMethod(SyntaxList <MemberDeclarationSyntax> members) => members.FirstOrDefault(m => m is MethodDeclarationSyntax);
public static MemberDeclarationSyntax?FirstMember(SyntaxList <MemberDeclarationSyntax> members) => members.FirstOrDefault();
private bool TryRemoveSummaryPrefix(ref SyntaxList <XmlNodeSyntax> summaryContent, string prefix) { XmlNodeSyntax firstContent = summaryContent.FirstOrDefault(IsContentElement); XmlTextSyntax firstText = firstContent as XmlTextSyntax; if (firstText == null) { return(false); } string firstTextContent = string.Concat(firstText.DescendantTokens()); if (!firstTextContent.TrimStart().StartsWith(prefix, StringComparison.Ordinal)) { return(false); } // Find the token containing the prefix, such as "Gets or sets " SyntaxToken prefixToken = default(SyntaxToken); foreach (SyntaxToken textToken in firstText.TextTokens) { if (textToken.IsMissing) { continue; } if (!textToken.Text.TrimStart().StartsWith(prefix, StringComparison.Ordinal)) { continue; } prefixToken = textToken; break; } if (prefixToken.IsMissingOrDefault()) { return(false); } string text = prefixToken.Text; string valueText = prefixToken.ValueText; int index = text.IndexOf(prefix); if (index >= 0) { bool additionalCharacters = index + prefix.Length < text.Length; text = text.Substring(0, index) + (additionalCharacters ? char.ToUpperInvariant(text[index + prefix.Length]).ToString() : string.Empty) + text.Substring(index + (additionalCharacters ? (prefix.Length + 1) : prefix.Length)); } index = valueText.IndexOf(prefix); if (index >= 0) { valueText = valueText.Remove(index, prefix.Length); } SyntaxToken replaced = SyntaxFactory.Token(prefixToken.LeadingTrivia, prefixToken.Kind(), text, valueText, prefixToken.TrailingTrivia); summaryContent = summaryContent.Replace(firstText, firstText.ReplaceToken(prefixToken, replaced)); return(true); }
private static SwitchSectionSyntax GetDefaultExpression(SyntaxList <SwitchSectionSyntax> caseSyntaxes) { return(caseSyntaxes.FirstOrDefault(x => x.Labels.FirstOrDefault() is DefaultSwitchLabelSyntax)); }