public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { SyntaxNode parent = invocationInfo.InvocationExpression.WalkUpParentheses().Parent; if (parent.Kind() != SyntaxKind.LogicalNotExpression) { return; } SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(invocationInfo.Arguments.First().Expression.WalkDownParentheses()); if (!lambdaInfo.Success) { return; } ExpressionSyntax expression = GetReturnExpression(lambdaInfo.Body)?.WalkDownParentheses(); if (expression?.IsKind(SyntaxKind.LogicalNotExpression) != true) { return; } if (!context.SemanticModel.TryGetExtensionMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.Reduced, context.CancellationToken)) { return; } if (!methodInfo.IsLinqExtensionOfIEnumerableOfTWithPredicate()) { return; } context.ReportDiagnostic(DiagnosticDescriptors.SimplifyLogicalNegation, parent); }
public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; if (invocationExpression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; if (!semanticModel.TryGetExtensionMethodInfo(invocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.Reduced, cancellationToken)) { return; } if (!methodInfo.IsLinqExtensionOfIEnumerableOfTWithoutParameters("Any")) { return; } string propertyName = CSharpUtility.GetCountOrLengthPropertyName(invocationInfo.Expression, semanticModel, cancellationToken); if (propertyName == null) { return; } context.ReportDiagnostic( DiagnosticDescriptors.UseCountOrLengthPropertyInsteadOfAnyMethod, Location.Create(context.Node.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.Span.Start, invocationExpression.Span.End)), ImmutableDictionary.CreateRange(new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("PropertyName", propertyName) }), propertyName); }
private static bool IsFixable( SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo, ArgumentSyntax argument, SeparatedSyntaxList <ArgumentSyntax> arguments) { if (object.ReferenceEquals(argument, arguments[0])) { ExpressionSyntax expression = arguments[1].Expression?.WalkDownParentheses(); if (expression != null) { SyntaxKind kind = expression.Kind(); if (kind == SyntaxKind.InvocationExpression) { return(TryCreateCaseChangingInvocation(expression, out MemberInvocationExpressionInfo invocationInfo2) && invocationInfo.NameText == invocationInfo2.NameText && CheckSymbol(invocationInfo, context.SemanticModel, context.CancellationToken) && CheckSymbol(invocationInfo2, context.SemanticModel, context.CancellationToken)); } else if (kind == SyntaxKind.StringLiteralExpression) { return(CheckSymbol(invocationInfo, context.SemanticModel, context.CancellationToken)); } } } else { return(arguments[0].Expression?.WalkDownParentheses().Kind() == SyntaxKind.StringLiteralExpression && CheckSymbol(invocationInfo, context.SemanticModel, context.CancellationToken)); } return(false); }
public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { ExpressionSyntax expression = invocationInfo.InvocationExpression.WalkUpParentheses(); SyntaxNode parent = expression.Parent; SyntaxKind kind = parent.Kind(); if (kind == SyntaxKind.SimpleMemberAccessExpression) { MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(parent.Parent); if (!invocationInfo2.Success) { return; } Analyze(context, invocationInfo, invocationInfo2); } else if (kind == SyntaxKind.Argument) { Analyze(context, invocationInfo, (ArgumentSyntax)parent); } else if (kind == SyntaxKind.EqualsExpression || kind == SyntaxKind.NotEqualsExpression) { Analyze(context, invocationInfo, expression, (BinaryExpressionSyntax)parent); } }
public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { ExpressionSyntax expression = invocationInfo.Expression; if (expression.Kind() != SyntaxKind.SimpleMemberAccessExpression) { return; } var memberAccessExpression = (MemberAccessExpressionSyntax)expression; var fieldSymbol = context.SemanticModel.GetSymbol(memberAccessExpression, context.CancellationToken) as IFieldSymbol; if (fieldSymbol == null) { return; } INamedTypeSymbol containingType = fieldSymbol.ContainingType; if (containingType?.TypeKind != TypeKind.Enum) { return; } if (containingType.HasAttribute(context.GetTypeByMetadataName(MetadataNames.System_FlagsAttribute))) { return; } context.ReportDiagnostic(DiagnosticDescriptors.UseNameOfOperator, invocationInfo.InvocationExpression); }
public static bool CanRefactor( MemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken) { ExpressionSyntax argumentExpression = invocationInfo.Arguments[0].Expression; if (argumentExpression?.IsMissing != false) { return(false); } if (invocationInfo.Expression?.IsMissing != false) { return(false); } if (!semanticModel.TryGetExtensionMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.Reduced, cancellationToken)) { return(false); } if (!methodInfo.IsLinqElementAt(allowImmutableArrayExtension: true)) { return(false); } ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken); return(SymbolUtility.HasAccessibleIndexer(typeSymbol, semanticModel, invocationInfo.InvocationExpression.SpanStart)); }
public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { ExpressionSyntax expression = invocationInfo.Expression; if (expression.IsKind(SyntaxKind.InvocationExpression)) { MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo((InvocationExpressionSyntax)expression); if (invocationInfo2.Success) { switch (invocationInfo2.NameText) { case "OrderBy": case "OrderByDescending": { if (IsLinqExtensionOfIEnumerableOfT(context, invocationInfo.InvocationExpression) && IsLinqExtensionOfIEnumerableOfT(context, invocationInfo2.InvocationExpression)) { context.ReportDiagnostic( DiagnosticDescriptors.CallThenByInsteadOfOrderBy, invocationInfo.Name, (invocationInfo.NameText == "OrderByDescending") ? "Descending" : null); } break; } } } } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case DiagnosticIdentifiers.OptimizeStringBuilderAppendCall: { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo((InvocationExpressionSyntax)argument.Parent.Parent); CodeAction codeAction = CodeAction.Create( $"Optimize '{invocationInfo.NameText}' call", cancellationToken => OptimizeStringBuilderAppendCallRefactoring.RefactorAsync(context.Document, argument, invocationInfo, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }
public static bool IsFixable( MemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; if (!invocationInfo.Expression.IsKind(SyntaxKind.BaseExpression) && semanticModel.TryGetMethodInfo(invocationExpression, out MethodInfo info, cancellationToken) && info.IsName("ToString") && info.IsPublic && !info.IsStatic && info.IsReturnType(SpecialType.System_String) && !info.IsGenericMethod && !info.IsExtensionMethod && !info.Parameters.Any()) { INamedTypeSymbol containingType = info.ContainingType; if (containingType?.IsReferenceType == true && containingType.SpecialType != SpecialType.System_Enum) { if (containingType.IsString()) { return(true); } if (invocationExpression.IsParentKind(SyntaxKind.Interpolation)) { return(IsNotHidden(info.Symbol, containingType)); } ExpressionSyntax expression = invocationExpression.WalkUpParentheses(); SyntaxNode parent = expression.Parent; if (parent?.IsKind(SyntaxKind.AddExpression) == true && !parent.ContainsDiagnostics && IsNotHidden(info.Symbol, containingType)) { var addExpression = (BinaryExpressionSyntax)expression.Parent; ExpressionSyntax left = addExpression.Left; ExpressionSyntax right = addExpression.Right; if (left == expression) { return(IsFixable(invocationInfo, addExpression, right, left, semanticModel, cancellationToken)); } else { return(IsFixable(invocationInfo, addExpression, left, right, semanticModel, cancellationToken)); } } } } return(false); }
private static InvocationExpressionSyntax ConvertInterpolatedStringExpressionToInvocationExpression( InterpolatedStringExpressionSyntax interpolatedString, MemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel) { bool isVerbatim = interpolatedString.IsVerbatim(); bool isAppendLine = string.Equals(invocationInfo.NameText, "AppendLine", StringComparison.Ordinal); InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression; InvocationExpressionSyntax newExpression = null; SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents; for (int i = 0; i < contents.Count; i++) { InterpolatedStringContentConversion conversion = InterpolatedStringContentConversion.Create(contents[i], isVerbatim); string methodName = conversion.MethodName; SeparatedSyntaxList <ArgumentSyntax> arguments = conversion.Arguments; if (i == contents.Count - 1 && isAppendLine && string.Equals(methodName, "Append", StringComparison.Ordinal) && (conversion.Kind == SyntaxKind.InterpolatedStringText || semanticModel.IsImplicitConversion(((InterpolationSyntax)contents[i]).Expression, semanticModel.Compilation.GetSpecialType(SpecialType.System_String)))) { methodName = "AppendLine"; } if (newExpression == null) { newExpression = invocation .ReplaceNode(invocationInfo.Name, IdentifierName(methodName).WithTriviaFrom(invocationInfo.Name)) .WithArgumentList(invocation.ArgumentList.WithArguments(arguments).WithoutTrailingTrivia()); } else { newExpression = SimpleMemberInvocationExpression( newExpression, IdentifierName(methodName), ArgumentList(arguments)); } if (i == contents.Count - 1 && isAppendLine && !string.Equals(methodName, "AppendLine", StringComparison.Ordinal)) { newExpression = SimpleMemberInvocationExpression( newExpression, IdentifierName("AppendLine"), ArgumentList()); } } return(newExpression); }
public static bool IsFixable( MemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; SyntaxNode parent = invocationExpression.Parent; switch (parent?.Kind()) { case SyntaxKind.ExpressionStatement: { var expressionStatement = (ExpressionStatementSyntax)parent; if (!(WalkDownMethodChain(invocationInfo).Expression is IdentifierNameSyntax identifierName)) { break; } string name = identifierName.Identifier.ValueText; return(WithoutAssignment.Analyze(invocationInfo, expressionStatement, name, semanticModel, cancellationToken)); } case SyntaxKind.SimpleAssignmentExpression: { var assinmentExpression = (AssignmentExpressionSyntax)parent; if (!(assinmentExpression.Left is IdentifierNameSyntax identifierName)) { break; } if (assinmentExpression.Right != invocationExpression) { break; } if (!(assinmentExpression.Parent is ExpressionStatementSyntax expressionStatement)) { break; } string name = identifierName.Identifier.ValueText; if (name != (WalkDownMethodChain(invocationInfo).Expression as IdentifierNameSyntax)?.Identifier.ValueText) { break; } return(WithAssignment.Analyze(invocationInfo, expressionStatement, name, semanticModel, cancellationToken)); } } return(false); }
public static async Task <Document> RefactorAsync( Document document, InvocationExpressionSyntax invocationExpression, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); MemberDeclarationSyntax memberDeclaration = invocationExpression.FirstAncestor <MemberDeclarationSyntax>(); Debug.Assert(memberDeclaration != null, ""); if (memberDeclaration != null) { BaseTypeDeclarationSyntax typeDeclaration = memberDeclaration.FirstAncestor <BaseTypeDeclarationSyntax>(); Debug.Assert(typeDeclaration != null, ""); if (typeDeclaration != null) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression); string fieldName = NameGenerator.Default.EnsureUniqueLocalName("_regex", semanticModel, invocationExpression.SpanStart, cancellationToken: cancellationToken); MemberAccessExpressionSyntax newMemberAccess = invocationInfo.MemberAccessExpression.WithExpression(IdentifierName(Identifier(fieldName).WithRenameAnnotation())); ArgumentListPair pair = RewriteArgumentLists(invocationInfo.ArgumentList, semanticModel, cancellationToken); InvocationExpressionSyntax newInvocationExpression = invocationExpression .WithExpression(newMemberAccess) .WithArgumentList(pair.ArgumentList1); MemberDeclarationSyntax newTypeDeclaration = typeDeclaration.ReplaceNode(invocationExpression, newInvocationExpression); TypeSyntax regexType = semanticModel.GetTypeByMetadataName(MetadataNames.System_Text_RegularExpressions_Regex).ToMinimalTypeSyntax(semanticModel, typeDeclaration.SpanStart); FieldDeclarationSyntax fieldDeclaration = FieldDeclaration( (ShouldBeStatic(memberDeclaration, semanticModel, cancellationToken)) ? Modifiers.PrivateStaticReadOnly() : Modifiers.PrivateReadOnly(), regexType, Identifier(fieldName), EqualsValueClause( ObjectCreationExpression(regexType, pair.ArgumentList2))); SyntaxList <MemberDeclarationSyntax> newMembers = newTypeDeclaration .GetMembers() .InsertMember(fieldDeclaration, MemberDeclarationComparer.ByKind); newTypeDeclaration = newTypeDeclaration.WithMembers(newMembers); return(await document.ReplaceNodeAsync(typeDeclaration, newTypeDeclaration, cancellationToken).ConfigureAwait(false)); } } return(document); }
private static bool CheckSymbol( MemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken) { return(semanticModel.TryGetMethodInfo(invocationInfo.InvocationExpression, out MethodInfo info, cancellationToken) && info.IsPublicInstanceStringMethod() && info.ReturnsString && !info.Parameters.Any()); }
public bool Analyze( MemberInvocationExpressionInfo invocationInfo, StatementSyntax statement, string name, SemanticModel semanticModel, CancellationToken cancellationToken) { if (statement.SpanOrTrailingTriviaContainsDirectives()) { return(false); } StatementsInfo statementsInfo = SyntaxInfo.StatementsInfo(statement); if (!statementsInfo.Success) { return(false); } SyntaxList <StatementSyntax> statements = statementsInfo.Statements; if (statements.Count == 1) { return(false); } if (!semanticModel.TryGetMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, cancellationToken)) { return(false); } ITypeSymbol typeSymbol = methodInfo.ReturnType; int i = statements.IndexOf(statement); if (i != 0 && IsFixableStatement(statements[i - 1], name, typeSymbol, semanticModel, cancellationToken)) { return(false); } int j = i; while (j < statements.Count - 1) { if (!IsFixableStatement(statements[j + 1], name, typeSymbol, semanticModel, cancellationToken)) { break; } j++; } return(j > i); }
private static bool IsFixable(InvocationExpressionSyntax invocationExpression, SemanticModel semanticModel, CancellationToken cancellationToken) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression); if (!invocationInfo.Success) { return(false); } if (!semanticModel.TryGetMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, cancellationToken)) { return(false); } if (!methodInfo.IsContainingType(SpecialType.System_String)) { return(false); } if (!methodInfo.IsReturnType(SpecialType.System_String)) { return(false); } switch (methodInfo.Name) { case "Substring": { if (methodInfo.HasParameters(SpecialType.System_Int32, SpecialType.System_Int32)) { return(true); } break; } case "Remove": { if (methodInfo.HasParameter(SpecialType.System_Int32)) { return(true); } break; } case "Format": { return(true); } } return(false); }
private string GetTextToAppend(ExpressionStatementSyntax expressionStatement) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(GetInvocationExpression(expressionStatement)); MemberInvocationExpressionInfo firstMemberInvocation = WalkDownMethodChain(invocationInfo); InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; return(invocationExpression .ToString() .Substring(firstMemberInvocation.OperatorToken.SpanStart - invocationExpression.SpanStart)); }
internal static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context) { var invocationExpression = (InvocationExpressionSyntax)context.Node; if (!invocationExpression.ContainsDiagnostics && !invocationExpression.SpanContainsDirectives()) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression); if (invocationInfo.Success && invocationInfo.NameText == "Any") { ArgumentSyntax argument1 = invocationInfo.Arguments.SingleOrDefault(shouldthrow: false); if (argument1 != null) { MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(invocationInfo.Expression); if (invocationInfo2.Success && invocationInfo2.NameText == "Where") { ArgumentSyntax argument2 = invocationInfo2.Arguments.SingleOrDefault(shouldthrow: false); if (argument2 != null) { SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; if (semanticModel.TryGetExtensionMethodInfo(invocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.None, cancellationToken) && methodInfo.IsLinqExtensionOfIEnumerableOfTWithPredicate("Any") && semanticModel.TryGetExtensionMethodInfo(invocationInfo2.InvocationExpression, out MethodInfo methodInfo2, ExtensionMethodKind.None, cancellationToken) && methodInfo2.IsLinqWhere(allowImmutableArrayExtension: true)) { SingleParameterLambdaExpressionInfo lambda = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument1.Expression); if (lambda.Success && lambda.Body is ExpressionSyntax) { SingleParameterLambdaExpressionInfo lambda2 = SyntaxInfo.SingleParameterLambdaExpressionInfo(argument2.Expression); if (lambda2.Success && lambda2.Body is ExpressionSyntax && lambda.ParameterName.Equals(lambda2.ParameterName, StringComparison.Ordinal)) { context.ReportDiagnostic( DiagnosticDescriptors.SimplifyLinqMethodChain, Location.Create(context.SyntaxTree(), TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocationExpression.Span.End))); } } } } } } } } }
public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; var methodSymbol = semanticModel.GetSymbol(invocationExpression, cancellationToken) as IMethodSymbol; if (methodSymbol == null) { return; } if (!ExtensionMethodInfo.TryCreate(methodSymbol, semanticModel, out ExtensionMethodInfo extensionMethodInfo, ExtensionMethodKind.Reduced)) { return; } if (!extensionMethodInfo.MethodInfo.IsLinqCast()) { return; } ITypeSymbol typeArgument = extensionMethodInfo.ReducedSymbol.TypeArguments.SingleOrDefault(shouldThrow: false); if (typeArgument == null) { return; } var memberAccessExpressionType = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken) as INamedTypeSymbol; if (memberAccessExpressionType?.IsConstructedFromIEnumerableOfT() != true) { return; } if (!typeArgument.Equals(memberAccessExpressionType.TypeArguments[0])) { return; } if (invocationExpression.ContainsDirectives(TextSpan.FromBounds(invocationInfo.Expression.Span.End, invocationExpression.Span.End))) { return; } context.ReportDiagnostic( DiagnosticDescriptors.RemoveRedundantCast, Location.Create(invocationExpression.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationInfo.ArgumentList.Span.End))); }
internal static Task <Document> RefactorAsync( Document document, MemberInvocationExpressionInfo invocationInfo, string comparisonName, CancellationToken cancellationToken) { SeparatedSyntaxList <ArgumentSyntax> arguments = invocationInfo.Arguments; InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression; if (arguments.Count == 2) { ArgumentListSyntax newArgumentList = ArgumentList( CreateArgument(arguments[0]), CreateArgument(arguments[1]), Argument(CreateStringComparison(comparisonName))); InvocationExpressionSyntax newNode = invocation.WithArgumentList(newArgumentList); return(document.ReplaceNodeAsync(invocation, newNode, cancellationToken)); } else { var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression; var invocation2 = (InvocationExpressionSyntax)memberAccess.Expression; var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression; MemberAccessExpressionSyntax newMemberAccess = memberAccess.WithExpression(memberAccess2.Expression); bool isContains = memberAccess.Name.Identifier.ValueText == "Contains"; if (isContains) { newMemberAccess = newMemberAccess.WithName(newMemberAccess.Name.WithIdentifier(Identifier("IndexOf").WithTriviaFrom(newMemberAccess.Name.Identifier))); } ArgumentListSyntax newArgumentList = ArgumentList( CreateArgument(arguments[0]), Argument(CreateStringComparison(comparisonName))); ExpressionSyntax newNode = invocation .WithExpression(newMemberAccess) .WithArgumentList(newArgumentList); if (isContains) { newNode = GreaterThanOrEqualExpression(newNode.Parenthesize(), NumericLiteralExpression(0)).Parenthesize(); } return(document.ReplaceNodeAsync(invocation, newNode, cancellationToken)); } }
public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { if (IsFixable(invocationInfo, context.SemanticModel, context.CancellationToken)) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; TextSpan span = TextSpan.FromBounds(invocationInfo.OperatorToken.Span.Start, invocationExpression.Span.End); if (!invocationExpression.ContainsDirectives(span)) { context.ReportDiagnostic( DiagnosticDescriptors.RemoveRedundantToStringCall, Location.Create(invocationExpression.SyntaxTree, span)); } } }
protected static MemberInvocationExpressionInfo WalkDownMethodChain(MemberInvocationExpressionInfo invocationInfo) { while (true) { MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(invocationInfo.Expression); if (invocationInfo2.Success) { invocationInfo = invocationInfo2; } else { break; } } return(invocationInfo); }
private static void Analyze( SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo, ArgumentSyntax argument) { if (!(argument.Parent is ArgumentListSyntax argumentList)) { return; } SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments; if (arguments.Count != 2) { return; } MemberInvocationExpressionInfo equalsInvocation = SyntaxInfo.MemberInvocationExpressionInfo(argumentList.Parent); if (!equalsInvocation.Success) { return; } if (equalsInvocation.NameText != "Equals") { return; } if (!IsFixable(context, invocationInfo, argument, arguments)) { return; } if (!context.SemanticModel.TryGetMethodInfo(equalsInvocation.InvocationExpression, out MethodInfo info, context.CancellationToken) || !info.IsPublicStaticStringMethod("Equals") || !info.ReturnsBoolean || !info.HasParameters(SpecialType.System_String, SpecialType.System_String)) { return; } ReportDiagnostic(context, equalsInvocation); }
public static Task <Document> RefactorAsync( Document document, MemberInvocationExpressionInfo invocationInfo, CancellationToken cancellationToken) { MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(invocationInfo.Expression); SyntaxTriviaList trivia = invocationInfo2.InvocationExpression .GetTrailingTrivia() .EmptyIfWhitespace() .AddRange(invocationInfo.InvocationExpression.GetTrailingTrivia()); InvocationExpressionSyntax newNode = invocationInfo2 .WithName("AppendLine") .InvocationExpression .WithTrailingTrivia(trivia); return(document.ReplaceNodeAsync(invocationInfo.InvocationExpression, newNode, cancellationToken)); }
private static InvocationExpressionSyntax CreateInvocationExpression( InvocationExpressionSyntax innerInvocationExpression, InvocationExpressionSyntax outerInvocationExpression) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(innerInvocationExpression); switch (invocationInfo.NameText) { case "Substring": { SeparatedSyntaxList <ArgumentSyntax> arguments = invocationInfo.Arguments; ArgumentListSyntax argumentList = ArgumentList( Argument(invocationInfo.Expression), arguments[0], arguments[1] ); return(CreateNewInvocationExpression(outerInvocationExpression, "Append", argumentList)); } case "Remove": { SeparatedSyntaxList <ArgumentSyntax> arguments = invocationInfo.Arguments; ArgumentListSyntax argumentList = ArgumentList( Argument(invocationInfo.Expression), Argument(NumericLiteralExpression(0)), arguments[0] ); return(CreateNewInvocationExpression(outerInvocationExpression, "Append", argumentList)); } case "Format": { return(CreateNewInvocationExpression(outerInvocationExpression, "AppendFormat", invocationInfo.ArgumentList)); } } Debug.Fail(innerInvocationExpression.ToString()); return(outerInvocationExpression); }
protected override bool IsFixableStatement( StatementSyntax statement, string name, ITypeSymbol typeSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { if (statement.SpanOrLeadingTriviaContainsDirectives()) { return(false); } if (!(statement is ExpressionStatementSyntax expressionStatement)) { return(false); } MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(expressionStatement.Expression); if (!invocationInfo.Success) { return(false); } if (!(WalkDownMethodChain(invocationInfo).Expression is IdentifierNameSyntax identifierName)) { return(false); } if (name != identifierName.Identifier.ValueText) { return(false); } if (!semanticModel.TryGetMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, cancellationToken)) { return(false); } return(!methodInfo.IsStatic && methodInfo.ContainingType?.Equals(typeSymbol) == true && methodInfo.ReturnType.Equals(typeSymbol)); }
private static bool RegisterCodeFix( CodeFixContext context, Diagnostic diagnostic, MemberInvocationExpressionInfo invocationInfo, INamedTypeSymbol comparisonSymbol, string comparisonName) { if (!comparisonSymbol.ExistsField(comparisonName)) { return(false); } CodeAction codeAction = CodeAction.Create( GetTitle(comparisonName), cancellationToken => UseStringComparisonRefactoring.RefactorAsync(context.Document, invocationInfo, comparisonName, cancellationToken), GetEquivalenceKey(DiagnosticIdentifiers.UseStringComparison, comparisonName)); context.RegisterCodeFix(codeAction, diagnostic); return(true); }
private static bool IsFixable( MemberInvocationExpressionInfo invocationInfo, BinaryExpressionSyntax addExpression, ExpressionSyntax left, ExpressionSyntax right, SemanticModel semanticModel, CancellationToken cancellationToken) { if (semanticModel.GetTypeSymbol(left, cancellationToken)?.SpecialType == SpecialType.System_String) { BinaryExpressionSyntax newAddExpression = addExpression.ReplaceNode(right, invocationInfo.Expression); return(semanticModel .GetSpeculativeMethodSymbol(addExpression.SpanStart, newAddExpression)? .ContainingType? .SpecialType == SpecialType.System_String); } return(false); }
public static Task <Document> RefactorAsync( Document document, InvocationExpressionSyntax invocationExpression, CancellationToken cancellationToken) { MemberInvocationExpressionInfo invocationInfo = SyntaxInfo.MemberInvocationExpressionInfo(invocationExpression); MemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.MemberInvocationExpressionInfo(invocationInfo.Expression); SingleParameterLambdaExpressionInfo lambda = SyntaxInfo.SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo.Arguments.First().Expression); SingleParameterLambdaExpressionInfo lambda2 = SyntaxInfo.SingleParameterLambdaExpressionInfo((LambdaExpressionSyntax)invocationInfo2.Arguments.First().Expression); BinaryExpressionSyntax logicalAnd = CSharpFactory.LogicalAndExpression( ((ExpressionSyntax)lambda2.Body).Parenthesize(), ((ExpressionSyntax)lambda.Body).Parenthesize()); InvocationExpressionSyntax newNode = invocationInfo2.InvocationExpression .ReplaceNode(invocationInfo2.Name, invocationInfo.Name.WithTriviaFrom(invocationInfo2.Name)) .WithArgumentList(invocationInfo2.ArgumentList.ReplaceNode((ExpressionSyntax)lambda2.Body, logicalAnd)); return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken)); }
public static bool CanRefactor(MemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken) { if (invocationInfo.Expression?.IsMissing != false) { return(false); } if (!semanticModel.TryGetExtensionMethodInfo(invocationInfo.InvocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.Reduced, cancellationToken)) { return(false); } if (!methodInfo.IsLinqExtensionOfIEnumerableOfTWithoutParameters("First", allowImmutableArrayExtension: true)) { return(false); } ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken); return(SymbolUtility.HasAccessibleIndexer(typeSymbol, semanticModel, invocationInfo.InvocationExpression.SpanStart)); }
private static void Analyze( SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo, ExpressionSyntax leftOrRight, BinaryExpressionSyntax binaryExpression) { if (object.ReferenceEquals(leftOrRight, binaryExpression.Left)) { ExpressionSyntax right = binaryExpression.Right?.WalkDownParentheses(); if (right != null) { SyntaxKind kind = right.Kind(); if (kind == SyntaxKind.InvocationExpression) { if (TryCreateCaseChangingInvocation(right, out MemberInvocationExpressionInfo invocationInfo2) && invocationInfo.NameText == invocationInfo2.NameText && CheckSymbol(invocationInfo, context.SemanticModel, context.CancellationToken) && CheckSymbol(invocationInfo2, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, binaryExpression); } } else if (kind == SyntaxKind.StringLiteralExpression) { if (CheckSymbol(invocationInfo, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, binaryExpression); } } } } else if (binaryExpression.Left?.WalkDownParentheses().Kind() == SyntaxKind.StringLiteralExpression && CheckSymbol(invocationInfo, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, binaryExpression); } }