private static void AnalyzeIsExpression(SyntaxNodeAnalysisContext context) { var isExpression = (BinaryExpressionSyntax)context.Node; IsExpressionInfo isExpressionInfo = SyntaxInfo.IsExpressionInfo(isExpression); if (!isExpressionInfo.Success) { return; } ExpressionSyntax expression = isExpressionInfo.Expression; var identifierName = expression as IdentifierNameSyntax; if (identifierName == null) { if (expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { var memberAccess = (MemberAccessExpressionSyntax)expression; if (memberAccess.Expression.IsKind(SyntaxKind.ThisExpression)) { identifierName = memberAccess.Name as IdentifierNameSyntax; } } if (identifierName == null) { return; } } ExpressionSyntax left = isExpression.WalkUpParentheses(); SyntaxNode node = left.Parent; if (node.ContainsDiagnostics) { return; } switch (node.Kind()) { case SyntaxKind.LogicalAndExpression: { var logicalAnd = (BinaryExpressionSyntax)node; if (left != logicalAnd.Left) { return; } ExpressionSyntax right = logicalAnd.Right; if (right == null) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; if (semanticModel.GetTypeSymbol(isExpressionInfo.Type, cancellationToken).IsNullableType()) { return; } if (logicalAnd.Parent.IsInExpressionTree(semanticModel, cancellationToken)) { return; } if (!IsFixable(right, identifierName, semanticModel, cancellationToken)) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UsePatternMatchingInsteadOfIsAndCast, logicalAnd); break; } case SyntaxKind.IfStatement: { var ifStatement = (IfStatementSyntax)node; if (left != ifStatement.Condition) { return; } StatementSyntax statement = ifStatement.Statement; if (statement == null) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; if (semanticModel.GetTypeSymbol(isExpressionInfo.Type, cancellationToken).IsNullableType()) { return; } if (!IsFixable(statement, identifierName, semanticModel, cancellationToken)) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UsePatternMatchingInsteadOfIsAndCast, ifStatement.Condition); break; } } }
public static void AnalyzeWhereAndCast(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo) { SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression); if (!invocationInfo2.Success) { return; } ArgumentSyntax argument = invocationInfo2.Arguments.SingleOrDefault(shouldThrow: false); if (argument == null) { return; } if (!string.Equals(invocationInfo2.NameText, "Where", StringComparison.Ordinal)) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; IMethodSymbol methodSymbol = semanticModel.GetReducedExtensionMethodInfo(invocationInfo.InvocationExpression, cancellationToken).Symbol; if (methodSymbol == null) { return; } if (!SymbolUtility.IsLinqCast(methodSymbol, semanticModel)) { return; } IMethodSymbol methodSymbol2 = semanticModel.GetReducedExtensionMethodInfo(invocationInfo2.InvocationExpression, cancellationToken).Symbol; if (methodSymbol2 == null) { return; } if (!SymbolUtility.IsLinqWhere(methodSymbol2, semanticModel)) { return; } IsExpressionInfo isExpressionInfo = SyntaxInfo.IsExpressionInfo(GetLambdaExpression(argument.Expression)); if (!isExpressionInfo.Success) { return; } TypeSyntax type2 = (invocationInfo.Name as GenericNameSyntax)?.TypeArgumentList?.Arguments.SingleOrDefault(shouldThrow: false); if (type2 == null) { return; } ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(isExpressionInfo.Type, cancellationToken); if (typeSymbol == null) { return; } ITypeSymbol typeSymbol2 = semanticModel.GetTypeSymbol(type2, cancellationToken); if (!typeSymbol.Equals(typeSymbol2)) { return; } TextSpan span = TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocationInfo.InvocationExpression.Span.End); if (invocationInfo.InvocationExpression.ContainsDirectives(span)) { return; } context.ReportDiagnostic( DiagnosticDescriptors.SimplifyLinqMethodChain, Location.Create(invocationInfo.InvocationExpression.SyntaxTree, span)); SyntaxNode GetLambdaExpression(ExpressionSyntax expression) { CSharpSyntaxNode body = (expression as LambdaExpressionSyntax)?.Body; if (body?.Kind() == SyntaxKind.Block) { StatementSyntax statement = ((BlockSyntax)body).Statements.SingleOrDefault(shouldThrow: false); if (statement?.Kind() == SyntaxKind.ReturnStatement) { var returnStatement = (ReturnStatementSyntax)statement; return(returnStatement.Expression); } } return(body); } }