private static void AnalyzeAnonymousMethodExpression(SyntaxNodeAnalysisContext context) { var anonymousMethod = (AnonymousMethodExpressionSyntax)context.Node; if (anonymousMethod.ContainsDiagnostics) { return; } ParameterInfo parameterInfo = SyntaxInfo.ParameterInfo(anonymousMethod); if (!parameterInfo.Success) { return; } var methodSymbol = (IMethodSymbol)context.SemanticModel.GetSymbol(anonymousMethod, context.CancellationToken); if (methodSymbol == null) { return; } if (SymbolUtility.IsEventHandlerMethod(methodSymbol)) { return; } Analyze(context, parameterInfo); }
private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context, bool shouldCheckWindowsRuntimeTypes) { var methodDeclaration = (MethodDeclarationSyntax)context.Node; if (methodDeclaration.Modifiers.Contains(SyntaxKind.OverrideKeyword)) { return; } if (methodDeclaration.Identifier.ValueText.EndsWith("Async", StringComparison.Ordinal)) { IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken); if (methodSymbol.IsAsync) { return; } if (!methodSymbol.Name.EndsWith("Async", StringComparison.Ordinal)) { return; } if (SymbolUtility.IsAwaitable(methodSymbol.ReturnType, shouldCheckWindowsRuntimeTypes)) { return; } SyntaxToken identifier = methodDeclaration.Identifier; DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.NonAsynchronousMethodNameShouldNotEndWithAsync, identifier); DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.NonAsynchronousMethodNameShouldNotEndWithAsyncFadeOut, Location.Create(identifier.SyntaxTree, TextSpan.FromBounds(identifier.Span.End - 5, identifier.Span.End))); } else { IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken); if (methodSymbol.Name.EndsWith("Async", StringComparison.Ordinal)) { return; } if (SymbolUtility.CanBeEntryPoint(methodSymbol)) { return; } if (!SymbolUtility.IsAwaitable(methodSymbol.ReturnType, shouldCheckWindowsRuntimeTypes)) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.AsynchronousMethodNameShouldEndWithAsync, methodDeclaration.Identifier); } }
private static bool IsOrderByOrOrderByDescending(InvocationExpressionSyntax invocationExpression, SemanticModel semanticModel, CancellationToken cancellationToken) { IMethodSymbol methodSymbol = semanticModel.GetExtensionMethodInfo(invocationExpression, cancellationToken).Symbol; return(methodSymbol?.IsName("OrderBy", "OrderByDescending") == true && SymbolUtility.IsLinqExtensionOfIEnumerableOfT(methodSymbol, semanticModel)); }
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)); }
private static void AddCallToConfigureAwait(SyntaxNodeAnalysisContext context) { var awaitExpression = (AwaitExpressionSyntax)context.Node; ExpressionSyntax expression = awaitExpression.Expression; if (IsConfigureAwait(expression)) { return; } ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(expression, context.CancellationToken); if (typeSymbol == null) { return; } if (!SymbolUtility.IsAwaitable(typeSymbol)) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.AddCallToConfigureAwaitOrViceVersa, awaitExpression.Expression); }
public static bool IsFixable( MemberAccessExpressionSyntax memberAccess, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (memberAccess.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { return(false); } if (memberAccess.Expression == null) { return(false); } if (memberAccess.Name?.Identifier.ValueText != "Empty") { return(false); } var fieldSymbol = semanticModel.GetSymbol(memberAccess.Name, cancellationToken) as IFieldSymbol; return(SymbolUtility.IsPublicStaticReadOnly(fieldSymbol) && fieldSymbol.ContainingType?.SpecialType == SpecialType.System_String); }
private static bool ComputeRefactoring( RefactoringContext context, InvocationExpressionSyntax invocation, SemanticModel semanticModel, string fromMethodName, string toMethodName) { IMethodSymbol methodSymbol = semanticModel.GetExtensionMethodInfo(invocation, context.CancellationToken).Symbol; if (methodSymbol == null) { return(false); } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithPredicate(methodSymbol, semanticModel, fromMethodName)) { return(false); } ExpressionSyntax expression = GetExpression(invocation); if (expression == null) { return(false); } context.RegisterRefactoring( $"Replace '{fromMethodName}' with '{toMethodName}'", ct => RefactorAsync(context.Document, invocation, toMethodName, expression, ct), RefactoringIdentifiers.ReplaceAnyWithAllOrAllWithAny); return(true); }
private static ThrowInfo GetUndocumentedExceptionInfo( SyntaxNode node, ExpressionSyntax expression, MemberDeclarationSyntax declaration, ISymbol declarationSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { if (expression != null) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); if (typeSymbol?.IsErrorType() == false && SymbolUtility.IsException(typeSymbol, semanticModel)) { DocumentationCommentTriviaSyntax comment = declaration.GetSingleLineDocumentationComment(); if (comment != null && !ContainsException(comment, typeSymbol, semanticModel, cancellationToken)) { return(ThrowInfo.Create(node, typeSymbol, declarationSymbol)); } } } return(null); }
public static void AnalyzeLocalFunctionStatement(SyntaxNodeAnalysisContext context, INamedTypeSymbol eventArgsSymbol) { var localFunctionStatement = (LocalFunctionStatementSyntax)context.Node; if (localFunctionStatement.ContainsDiagnostics) { return; } ParameterInfo parameterInfo = SyntaxInfo.ParameterInfo(localFunctionStatement); if (!parameterInfo.Success) { return; } IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(localFunctionStatement, context.CancellationToken); if (methodSymbol == null) { return; } if (SymbolUtility.IsEventHandlerMethod(methodSymbol, eventArgsSymbol)) { return; } Analyze(context, parameterInfo); }
public static void AnalyzeParenthesizedLambdaExpression(SyntaxNodeAnalysisContext context, INamedTypeSymbol eventArgsSymbol) { var lambda = (ParenthesizedLambdaExpressionSyntax)context.Node; if (lambda.ContainsDiagnostics) { return; } ParameterInfo parameterInfo = SyntaxInfo.ParameterInfo(lambda); if (!parameterInfo.Success) { return; } var methodSymbol = (IMethodSymbol)context.SemanticModel.GetSymbol(lambda, context.CancellationToken); if (methodSymbol == null) { return; } if (SymbolUtility.IsEventHandlerMethod(methodSymbol, eventArgsSymbol)) { return; } Analyze(context, parameterInfo); }
private static void AnalyzeLocalFunctionStatement(SyntaxNodeAnalysisContext context) { var localFunction = (LocalFunctionStatementSyntax)context.Node; if (localFunction.Modifiers.Contains(SyntaxKind.AsyncKeyword)) { return; } BlockSyntax body = localFunction.Body; if (body == null) { return; } if (!body.Statements.Any()) { return; } IMethodSymbol methodSymbol = context.SemanticModel.GetDeclaredSymbol(localFunction, context.CancellationToken); if (!SymbolUtility.IsAwaitable(methodSymbol.ReturnType)) { return; } if (IsFixable(body, context)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.UseAsyncAwait, localFunction.Identifier); } }
public static bool IsFixable( SimpleMemberInvocationExpressionInfo invocationInfo, SemanticModel semanticModel, CancellationToken cancellationToken) { if (invocationInfo.Expression?.IsMissing != false) { return(false); } IMethodSymbol methodSymbol = semanticModel.GetReducedExtensionMethodInfo(invocationInfo.InvocationExpression, cancellationToken).Symbol; if (methodSymbol == null) { return(false); } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, "Last", semanticModel, allowImmutableArrayExtension: true)) { return(false); } ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken); return(SymbolUtility.HasAccessibleIndexer(typeSymbol, semanticModel, invocationInfo.InvocationExpression.SpanStart)); }
private static void AnalyzeAnonymousMethodExpression(SyntaxNodeAnalysisContext context) { var anonymousMethod = (AnonymousMethodExpressionSyntax)context.Node; if (anonymousMethod.AsyncKeyword.IsKind(SyntaxKind.AsyncKeyword)) { return; } BlockSyntax body = anonymousMethod.Block; if (body == null) { return; } if (context.SemanticModel.GetSymbol(anonymousMethod, context.CancellationToken) is not IMethodSymbol methodSymbol) { return; } if (!SymbolUtility.IsAwaitable(methodSymbol.ReturnType)) { return; } if (IsFixable(body, context)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.UseAsyncAwait, anonymousMethod); } }
private static void AnalyzeParenthesizedLambdaExpression(SyntaxNodeAnalysisContext context) { var parenthesizedLambda = (ParenthesizedLambdaExpressionSyntax)context.Node; if (parenthesizedLambda.AsyncKeyword.IsKind(SyntaxKind.AsyncKeyword)) { return; } if (parenthesizedLambda.Body is not BlockSyntax body) { return; } if (context.SemanticModel.GetSymbol(parenthesizedLambda, context.CancellationToken) is not IMethodSymbol methodSymbol) { return; } if (!SymbolUtility.IsAwaitable(methodSymbol.ReturnType)) { return; } if (IsFixable(body, context)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.UseAsyncAwait, parenthesizedLambda); } }
private static void AnalyzeSimpleMemberAccessExpression(SyntaxNodeAnalysisContext context) { var memberAccess = (MemberAccessExpressionSyntax)context.Node; if (memberAccess.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { return; } if (memberAccess.Expression == null) { return; } if (memberAccess.Name?.Identifier.ValueText != "Empty") { return; } var fieldSymbol = context.SemanticModel.GetSymbol(memberAccess.Name, context.CancellationToken) as IFieldSymbol; if (!SymbolUtility.IsPublicStaticReadOnly(fieldSymbol)) { return; } if (fieldSymbol.ContainingType?.SpecialType != SpecialType.System_String) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseEmptyStringLiteralInsteadOfStringEmptyOrViceVersa, memberAccess); }
internal static IFieldSymbol FindEnumDefaultField(INamedTypeSymbol enumSymbol) { if (enumSymbol == null) { throw new ArgumentNullException(nameof(enumSymbol)); } if (enumSymbol.EnumUnderlyingType == null) { throw new ArgumentException($"'{enumSymbol}' is not an enumeration.", nameof(enumSymbol)); } foreach (ISymbol symbol in enumSymbol.GetMembers()) { if (symbol.Kind == SymbolKind.Field) { var fieldSymbol = (IFieldSymbol)symbol; if (fieldSymbol.HasConstantValue && SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, enumSymbol) == 0) { return(fieldSymbol); } } } return(default(IFieldSymbol)); }
public static void AnalyzeWhere(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo) { SimpleMemberInvocationExpressionInfo invocationInfo2 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationInfo.Expression); if (!invocationInfo2.Success) { return; } if (invocationInfo2.Arguments.Count != 1) { return; } if (invocationInfo2.NameText != "Where") { return; } InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression; SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; IMethodSymbol methodSymbol = semanticModel.GetExtensionMethodInfo(invocation, cancellationToken).Symbol; if (methodSymbol == null) { return; } if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithoutParameters(methodSymbol, invocationInfo.NameText, semanticModel)) { return; } IMethodSymbol methodSymbol2 = semanticModel.GetExtensionMethodInfo(invocationInfo2.InvocationExpression, cancellationToken).Symbol; if (methodSymbol2 == null) { return; } if (!SymbolUtility.IsLinqWhere(methodSymbol2, semanticModel, allowImmutableArrayExtension: true)) { return; } TextSpan span = TextSpan.FromBounds(invocationInfo2.Name.SpanStart, invocation.Span.End); if (invocation.ContainsDirectives(span)) { return; } context.ReportDiagnostic( DiagnosticDescriptors.SimplifyLinqMethodChain, Location.Create(invocation.SyntaxTree, span)); }
public static bool IsTaskOrTaskOfT(ITypeSymbol typeSymbol) { return(typeSymbol != null && SymbolUtility.CanPossiblyBeAwaitable(typeSymbol) && (typeSymbol is INamedTypeSymbol namedTypeSymbol) && (namedTypeSymbol.HasMetadataName(MetadataNames.System_Threading_Tasks_Task) || namedTypeSymbol.OriginalDefinition.EqualsOrInheritsFrom(MetadataNames.System_Threading_Tasks_Task_T))); }
private static void Analyze( SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo, ArgumentSyntax argument) { if (!(argument.Parent is ArgumentListSyntax argumentList)) { return; } SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments; if (arguments.Count != 2) { return; } SimpleMemberInvocationExpressionInfo equalsInvocation = SyntaxInfo.SimpleMemberInvocationExpressionInfo(argumentList.Parent); if (!equalsInvocation.Success) { return; } if (equalsInvocation.NameText != "Equals") { return; } if (!IsFixable(context, invocationInfo, argument, arguments)) { return; } IMethodSymbol methodSymbol = context.SemanticModel.GetMethodSymbol(equalsInvocation.InvocationExpression, context.CancellationToken); if (!SymbolUtility.IsPublicStaticNonGeneric(methodSymbol, "Equals")) { return; } if (!methodSymbol.IsContainingType(SpecialType.System_String)) { return; } if (!methodSymbol.IsReturnType(SpecialType.System_Boolean)) { return; } if (!methodSymbol.HasTwoParameters(SpecialType.System_String, SpecialType.System_String)) { return; } ReportDiagnostic(context, equalsInvocation); }
public static bool IsEmptyStringExpression( ExpressionSyntax expression, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } if (semanticModel == null) { throw new ArgumentNullException(nameof(semanticModel)); } SyntaxKind kind = expression.Kind(); if (kind == SyntaxKind.StringLiteralExpression) { return(((LiteralExpressionSyntax)expression).Token.ValueText.Length == 0); } else if (kind == SyntaxKind.InterpolatedStringExpression) { return(!((InterpolatedStringExpressionSyntax)expression).Contents.Any()); } else if (kind == SyntaxKind.SimpleMemberAccessExpression) { var memberAccess = (MemberAccessExpressionSyntax)expression; if (memberAccess.Name?.Identifier.ValueText == "Empty") { ISymbol symbol = semanticModel.GetSymbol(memberAccess, cancellationToken); if (symbol?.Kind == SymbolKind.Field) { var fieldSymbol = (IFieldSymbol)symbol; if (SymbolUtility.IsPublicStaticReadOnly(fieldSymbol, "Empty") && fieldSymbol.ContainingType?.SpecialType == SpecialType.System_String && fieldSymbol.Type.IsString()) { return(true); } } } } Optional <object> optional = semanticModel.GetConstantValue(expression, cancellationToken); if (optional.HasValue) { var value = optional.Value as string; return(value?.Length == 0); } return(false); }
public static async Task ComputeRefactoringsAsync(RefactoringContext context, ForEachStatementSyntax forEachStatement) { if (context.IsAnyRefactoringEnabled( RefactoringDescriptors.UseImplicitType, RefactoringDescriptors.UseExplicitType, RefactoringDescriptors.ChangeTypeAccordingToExpression)) { await ChangeTypeAsync(context, forEachStatement).ConfigureAwait(false); } if (context.IsRefactoringEnabled(RefactoringDescriptors.RenameIdentifierAccordingToTypeName)) { await RenameIdentifierAccordingToTypeNameAsync(context, forEachStatement).ConfigureAwait(false); } SemanticModel semanticModel = null; if (context.IsAnyRefactoringEnabled(RefactoringDescriptors.ConvertForEachToFor, RefactoringDescriptors.ConvertForEachToForAndReverseLoop) && context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(forEachStatement)) { semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(forEachStatement.Expression, context.CancellationToken); if (SymbolUtility.HasAccessibleIndexer(typeSymbol, semanticModel, forEachStatement.SpanStart)) { if (context.IsRefactoringEnabled(RefactoringDescriptors.ConvertForEachToFor)) { context.RegisterRefactoring( "Convert to 'for'", ct => ConvertForEachToForRefactoring.RefactorAsync(context.Document, forEachStatement, semanticModel: semanticModel, reverseLoop: false, cancellationToken: ct), RefactoringDescriptors.ConvertForEachToFor); } if (context.IsRefactoringEnabled(RefactoringDescriptors.ConvertForEachToForAndReverseLoop)) { context.RegisterRefactoring( "Convert to 'for' and reverse loop", ct => ConvertForEachToForRefactoring.RefactorAsync(context.Document, forEachStatement, semanticModel: semanticModel, reverseLoop: true, cancellationToken: ct), RefactoringDescriptors.ConvertForEachToForAndReverseLoop); } } } if (context.IsRefactoringEnabled(RefactoringDescriptors.DeconstructForeachVariable) && TextSpan.FromBounds(forEachStatement.Type.SpanStart, forEachStatement.Identifier.Span.End).Contains(context.Span)) { semanticModel ??= await context.GetSemanticModelAsync().ConfigureAwait(false); DeconstructForeachVariableRefactoring.ComputeRefactoring(context, forEachStatement, semanticModel); } if (context.IsRefactoringEnabled(RefactoringDescriptors.UseEnumeratorExplicitly) && context.Span.IsEmptyAndContainedInSpan(forEachStatement.ForEachKeyword)) { UseEnumeratorExplicitlyRefactoring.ComputeRefactoring(context, forEachStatement); } }
public static bool CanRefactor( ForEachStatementSyntax forEachStatement, SemanticModel semanticModel, CancellationToken cancellationToken = default(CancellationToken)) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(forEachStatement.Expression, cancellationToken); return(SymbolUtility.HasAccessibleIndexer(typeSymbol, semanticModel, forEachStatement.SpanStart)); }
private static async Task <Document> DeclareExplicitValueAsync( Document document, EnumDeclarationSyntax enumDeclaration, INamedTypeSymbol enumSymbol, ImmutableArray <ulong> values, SemanticModel semanticModel, CancellationToken cancellationToken) { bool isFlags = enumSymbol.HasAttribute(MetadataNames.System_FlagsAttribute); List <ulong> reservedValues = values.ToList(); SeparatedSyntaxList <EnumMemberDeclarationSyntax> members = enumDeclaration.Members; SeparatedSyntaxList <EnumMemberDeclarationSyntax> newMembers = members; for (int i = 0; i < members.Count; i++) { if (members[i].EqualsValue == null) { IFieldSymbol fieldSymbol = semanticModel.GetDeclaredSymbol(members[i], cancellationToken); ulong?value = null; if (isFlags) { Optional <ulong> optional = FlagsUtility <ulong> .Instance.GetUniquePowerOfTwo(reservedValues); if (optional.HasValue && ConvertHelpers.CanConvert(optional.Value, enumSymbol.EnumUnderlyingType.SpecialType)) { value = optional.Value; } } else { value = SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, enumSymbol); } if (value != null) { reservedValues.Add(value.Value); EqualsValueClauseSyntax equalsValue = EqualsValueClause(NumericLiteralExpression(value.Value, enumSymbol.EnumUnderlyingType.SpecialType)); EnumMemberDeclarationSyntax newMember = members[i].WithEqualsValue(equalsValue); newMembers = newMembers.ReplaceAt(i, newMember); } } } EnumDeclarationSyntax newEnumDeclaration = enumDeclaration.WithMembers(newMembers); return(await document.ReplaceNodeAsync(enumDeclaration, newEnumDeclaration, cancellationToken).ConfigureAwait(false)); }
private static Task <Document> RefactorAsync( Document document, EnumDeclarationSyntax enumDeclaration, SeparatedSyntaxListSelection <EnumMemberDeclarationSyntax> selectedMembers, INamedTypeSymbol enumSymbol, string name, SemanticModel semanticModel, CancellationToken cancellationToken) { ExpressionSyntax expression = null; EnumMemberDeclarationSyntax lastMember = null; using (IEnumerator <EnumMemberDeclarationSyntax> en = GetMembersToCombine().GetEnumerator()) { if (en.MoveNext()) { lastMember = en.Current; expression = IdentifierName(en.Current.Identifier.WithoutTrivia()); while (en.MoveNext()) { expression = BitwiseOrExpression( IdentifierName(en.Current.Identifier.WithoutTrivia()), expression); } } } EnumMemberDeclarationSyntax newEnumMember = EnumMemberDeclaration( Identifier(name).WithRenameAnnotation(), EqualsValueClause(expression)); EnumDeclarationSyntax newEnumDeclaration = enumDeclaration .WithMembers(enumDeclaration.Members.Insert(selectedMembers.UnderlyingList.IndexOf(lastMember) + 1, newEnumMember)); return(document.ReplaceNodeAsync(enumDeclaration, newEnumDeclaration, cancellationToken)); IEnumerable <EnumMemberDeclarationSyntax> GetMembersToCombine() { for (int i = selectedMembers.Count - 1; i >= 0; i--) { IFieldSymbol symbol = semanticModel.GetDeclaredSymbol(selectedMembers[i], cancellationToken); if (symbol.HasConstantValue) { ulong value = SymbolUtility.GetEnumValueAsUInt64(symbol.ConstantValue, enumSymbol); if (!FlagsUtility <ulong> .Instance.IsComposite(value)) { yield return(selectedMembers[i]); } } } } }
public static void AnalyzeAddExpression(SyntaxNodeAnalysisContext context) { var addExpression = (BinaryExpressionSyntax)context.Node; if (addExpression.ContainsDiagnostics) { return; } IMethodSymbol methodSymbol = context.SemanticModel.GetMethodSymbol(addExpression, context.CancellationToken); if (!SymbolUtility.IsStringAdditionOperator(methodSymbol)) { return; } ExpressionSyntax expression = GetObjectExpression()?.WalkDownParentheses(); if (expression == null) { return; } if (expression.Kind() == SyntaxKind.AddExpression) { return; } ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(expression, context.CancellationToken); if (typeSymbol?.IsValueType != true) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.AvoidBoxingOfValueType, expression); ExpressionSyntax GetObjectExpression() { ImmutableArray <IParameterSymbol> parameters = methodSymbol.Parameters; if (parameters[0].Type.SpecialType == SpecialType.System_Object) { return(addExpression.Left); } else if (parameters[1].Type.SpecialType == SpecialType.System_Object) { return(addExpression.Right); } else { return(null); } } }
private static Task <Document> RefactorAsync( Document document, EnumDeclarationSyntax enumDeclaration, INamedTypeSymbol enumSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { ulong value = 0; SpecialType numericType = enumSymbol.EnumUnderlyingType.SpecialType; IEnumerable <EnumMemberDeclarationSyntax> newMembers = (enumSymbol.HasAttribute(MetadataNames.System_FlagsAttribute)) ? enumDeclaration.Members.Select(CreateNewFlagsMember) : enumDeclaration.Members.Select(CreateNewMember); EnumDeclarationSyntax newEnumDeclaration = enumDeclaration.WithMembers(newMembers.ToSeparatedSyntaxList()); return(document.ReplaceNodeAsync(enumDeclaration, newEnumDeclaration, cancellationToken)); EnumMemberDeclarationSyntax CreateNewFlagsMember(EnumMemberDeclarationSyntax enumMember) { if (!ConvertHelpers.CanConvert(value, numericType)) { return(enumMember); } IFieldSymbol fieldSymbol = semanticModel.GetDeclaredSymbol(enumMember, cancellationToken); if (fieldSymbol.HasConstantValue && FlagsUtility <ulong> .Instance.IsComposite(SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, enumSymbol))) { return(enumMember); } EnumMemberDeclarationSyntax newEnumMember = CreateNewEnumMember(enumMember, value, numericType); value = (value == 0) ? 1 : value * 2; return(newEnumMember); } EnumMemberDeclarationSyntax CreateNewMember(EnumMemberDeclarationSyntax enumMember) { if (!ConvertHelpers.CanConvert(value, numericType)) { return(enumMember); } EnumMemberDeclarationSyntax newEnumMember = CreateNewEnumMember(enumMember, value, numericType); value++; return(newEnumMember); } }
public static void Analyze( SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation, MemberAccessExpressionSyntax memberAccess) { if (memberAccess.Expression?.IsKind(SyntaxKind.InvocationExpression) == true) { var invocation2 = (InvocationExpressionSyntax)memberAccess.Expression; if (invocation2.ArgumentList?.Arguments.Count == 1 && invocation2.Expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true) { var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression; SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; if (string.Equals(memberAccess2.Name?.Identifier.ValueText, "Where", StringComparison.Ordinal)) { ExtensionMethodInfo info2 = semanticModel.GetExtensionMethodInfo(invocation2, ExtensionMethodKind.Reduced, cancellationToken); if (info2.MethodInfo.IsLinqExtensionOfIEnumerableOfT("Where", parameterCount: 2)) { if (SymbolUtility.IsPredicateFunc( info2.Symbol.Parameters[1].Type, info2.Symbol.TypeArguments[0], semanticModel)) { if (semanticModel .GetExtensionMethodInfo(invocation, ExtensionMethodKind.Reduced, cancellationToken) .MethodInfo .IsLinqWhere()) { Analyze(context, invocation, invocation2, memberAccess, memberAccess2); } } else if (SymbolUtility.IsPredicateFunc( info2.Symbol.Parameters[1].Type, info2.Symbol.TypeArguments[0], semanticModel.Compilation.GetSpecialType(SpecialType.System_Int32), semanticModel)) { if (semanticModel .GetExtensionMethodInfo(invocation, ExtensionMethodKind.Reduced, cancellationToken) .MethodInfo .IsLinqWhereWithIndex()) { Analyze(context, invocation, invocation2, memberAccess, memberAccess2); } } } } } } }
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()); }
private static async Task <Document> RefactorAsync( Document document, EnumDeclarationSyntax enumDeclaration, IEnumerable <EnumMemberDeclarationSyntax> enumMembers, bool keepCompositeValue, CancellationToken cancellationToken) { SemanticModel semanticModel = null; if (keepCompositeValue) { semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); INamedTypeSymbol enumSymbol = semanticModel.GetDeclaredSymbol(enumDeclaration, cancellationToken); keepCompositeValue = enumSymbol.HasAttribute(MetadataNames.System_FlagsAttribute); } IEnumerable <TextChange> textChanges = enumMembers .Where(enumMember => { ExpressionSyntax expression = enumMember.EqualsValue?.Value; if (expression == null) { return(false); } if (keepCompositeValue && !(expression is LiteralExpressionSyntax)) { IFieldSymbol fieldSymbol = semanticModel.GetDeclaredSymbol(enumMember, cancellationToken); if (!fieldSymbol.HasConstantValue) { return(false); } ulong value = SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, fieldSymbol.ContainingType); if (FlagsUtility <ulong> .Instance.IsComposite(value)) { return(false); } } return(true); }) .Select(f => new TextChange(TextSpan.FromBounds(f.Identifier.Span.End, f.EqualsValue.Span.End), "")); return(await document.WithTextChangesAsync(textChanges, cancellationToken).ConfigureAwait(false)); }
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); }