Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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));
        }
Ejemplo n.º 13
0
        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);
            }
        }
Ejemplo n.º 14
0
        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);
            }
        }
Ejemplo n.º 15
0
        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);
        }
Ejemplo n.º 16
0
        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));
        }
Ejemplo n.º 18
0
 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)));
 }
Ejemplo n.º 19
0
        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);
        }
Ejemplo n.º 20
0
        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);
        }
Ejemplo n.º 21
0
        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);
            }
        }
Ejemplo n.º 22
0
        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));
        }
Ejemplo n.º 24
0
        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);
                }
            }
        }
Ejemplo n.º 26
0
        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);
            }
        }
Ejemplo n.º 27
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 28
0
        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);
        }