private static bool CheckSymbol( SimpleMemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken) { IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationInfo.InvocationExpression, cancellationToken); return(SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol) && methodSymbol.IsContainingType(SpecialType.System_String) && methodSymbol.IsReturnType(SpecialType.System_String) && !methodSymbol.Parameters.Any()); }
public static bool IsFixable( InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (!ParentIsElementAccessOrForEachExpression(invocation.WalkUpParentheses())) { return(false); } SimpleMemberInvocationExpressionInfo info = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation); if (!info.Success) { return(false); } if (info.Arguments.Any()) { return(false); } if (!string.Equals(info.NameText, "ToCharArray")) { return(false); } IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocation, cancellationToken); if (!SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, "ToCharArray")) { return(false); } if (methodSymbol.ContainingType?.SpecialType != SpecialType.System_String) { return(false); } if (methodSymbol.Parameters.Any()) { return(false); } if (!(methodSymbol.ReturnType is IArrayTypeSymbol arrayType)) { return(false); } return(arrayType.ElementType.SpecialType == SpecialType.System_Char); }
public static async Task ComputeRefactoringAsync(RefactoringContext context, InvocationExpressionSyntax invocation) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocation, context.CancellationToken); if (SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, "Contains") && methodSymbol.IsContainingType(SpecialType.System_String) && methodSymbol.HasSingleParameter(SpecialType.System_String)) { context.RegisterRefactoring( "Replace Contains with IndexOf", //Call 'IndexOf' instead of 'Replace' cancellationToken => RefactorAsync(context.Document, invocation, cancellationToken)); } }
private static void Analyze( SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo, SimpleMemberInvocationExpressionInfo invocationInfo2) { if (invocationInfo2.InvocationExpression.SpanContainsDirectives()) { return; } string name2 = invocationInfo2.NameText; if (name2 != "Equals" && name2 != "StartsWith" && name2 != "EndsWith" && name2 != "IndexOf" && name2 != "LastIndexOf" && name2 != "Contains") { return; } SeparatedSyntaxList <ArgumentSyntax> arguments = invocationInfo2.Arguments; if (arguments.Count != 1) { return; } ExpressionSyntax argumentExpression = arguments[0].Expression.WalkDownParentheses(); string name = invocationInfo.NameText; SimpleMemberInvocationExpressionInfo invocationInfo3; bool isStringLiteral = argumentExpression.IsKind(SyntaxKind.StringLiteralExpression); if (!isStringLiteral) { invocationInfo3 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(argumentExpression); if (!invocationInfo3.Success) { return; } string name3 = invocationInfo3.NameText; if (name != name3) { return; } } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; if (!CheckSymbol(invocationInfo, semanticModel, cancellationToken)) { return; } IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationInfo2.InvocationExpression, cancellationToken); if (!SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, name2)) { return; } if (!methodSymbol.IsContainingType(SpecialType.System_String)) { return; } SpecialType returnType = (name2.EndsWith("IndexOf", StringComparison.Ordinal)) ? SpecialType.System_Int32 : SpecialType.System_Boolean; if (!methodSymbol.IsReturnType(returnType)) { return; } if (!methodSymbol.HasSingleParameter(SpecialType.System_String)) { return; } if (!isStringLiteral && !CheckSymbol(invocationInfo3, semanticModel, cancellationToken)) { return; } ReportDiagnostic(context, invocationInfo2); }
public static bool IsFixable( SimpleMemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (invocationInfo.Expression.Kind() == SyntaxKind.BaseExpression) { return(false); } InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationExpression, cancellationToken); if (SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, "ToString") && methodSymbol.ReturnType.SpecialType == SpecialType.System_String && !methodSymbol.Parameters.Any()) { INamedTypeSymbol containingType = methodSymbol.ContainingType; if (containingType?.IsReferenceType == true && containingType.SpecialType != SpecialType.System_Enum) { if (containingType.SpecialType == SpecialType.System_String) { return(true); } ExpressionSyntax expression = invocationExpression.WalkUpParentheses(); SyntaxNode parent = expression.Parent; if (parent != null) { SyntaxKind kind = parent.Kind(); if (kind == SyntaxKind.Interpolation) { return(IsNotHidden(methodSymbol, containingType)); } else if (kind == SyntaxKind.AddExpression) { if (!parent.ContainsDiagnostics && IsNotHidden(methodSymbol, containingType)) { var addExpression = (BinaryExpressionSyntax)expression.Parent; if (CSharpUtility.IsStringConcatenation(addExpression, semanticModel, cancellationToken)) { BinaryExpressionSyntax newAddExpression = addExpression.ReplaceNode(expression, invocationInfo.Expression); IMethodSymbol speculativeSymbol = semanticModel.GetSpeculativeMethodSymbol(addExpression.SpanStart, newAddExpression); return(SymbolUtility.IsStringAdditionOperator(speculativeSymbol)); } } } } } } return(false); }