private void AnalyzeLockStatement(SyntaxNodeAnalysisContext context)
        {
            var lockStatement = (LockStatementSyntax)context.Node;
            var semanticModel = context.SemanticModel;

            foreach (var token in lockStatement.DescendantTokens().Where(_ => _.IsKind(SyntaxKind.IdentifierToken)))
            {
                var identifier = token.Parent;

                var type = identifier.GetTypeSymbol(semanticModel);
                if (type?.TypeKind == TypeKind.Delegate)
                {
                    if (token.GetSymbol(semanticModel) is IEventSymbol)
                    {
                        // found by rule MiKo 3092
                        continue;
                    }

                    // only warn if it is an invocation
                    switch (identifier.Parent.Kind())
                    {
                    case SyntaxKind.ConditionalAccessExpression:
                    case SyntaxKind.InvocationExpression:
                    {
                        var method = context.GetEnclosingMethod();
                        var issue  = Issue(method.Name, token);
                        context.ReportDiagnostic(issue);

                        break;
                    }
                    }
                }
            }
        }
示例#2
0
        private void AnalyzeConstructor(SyntaxNodeAnalysisContext context)
        {
            var method = (ConstructorDeclarationSyntax)context.Node;

            var parameters = method.ParameterList.Parameters;

            if (parameters.Count == 0)
            {
                return;
            }

            var methodBody = method.Body ?? (SyntaxNode)method.ExpressionBody?.Expression;

            if (methodBody is null)
            {
                return; // unfinished code or code that has no body (such as interface methods or abstract methods)
            }

            var methodSymbol = context.GetEnclosingMethod();

            if (methodSymbol is null)
            {
                return;
            }

            var results = Analyze(context, methodBody, methodSymbol);

            foreach (var diagnostic in results)
            {
                context.ReportDiagnostic(diagnostic);
            }
        }
        private void AnalyzeSimpleMemberAccessExpression(SyntaxNodeAnalysisContext context)
        {
            var node = (MemberAccessExpressionSyntax)context.Node;

            if (node.Expression is IdentifierNameSyntax invokedClass)
            {
                if (AllowedAssertionMethods.Contains(node.GetName()))
                {
                    return;
                }

                if (Constants.Names.AssertionTypes.Contains(invokedClass.GetName()) is false)
                {
                    return;
                }

                var testFrameworkNamespace = invokedClass.GetTypeSymbol(context.SemanticModel)?.ContainingNamespace.FullyQualifiedName();

                if (Constants.Names.AssertionNamespaces.Contains(testFrameworkNamespace) is false)
                {
                    return; // ignore other test frameworks
                }

                var method = context.GetEnclosingMethod();
                if (method is null)
                {
                    // nameof() is also a SimpleMemberAccessExpression, so assignments of lists etc. may cause an NRE to be thrown
                    return;
                }

                context.ReportDiagnostic(Issue(method.Name, node));
            }
        }
示例#4
0
        private void AnalyzeFinallyClause(SyntaxNodeAnalysisContext context)
        {
            var finallyBlock = ((FinallyClauseSyntax)context.Node).Block;

            if (finallyBlock is null)
            {
                return;
            }

            foreach (var statement in finallyBlock.DescendantNodesAndSelf().OfType <ThrowStatementSyntax>())
            {
                var location = statement.GetLocation();
                var method   = context.GetEnclosingMethod();
                var issue    = Issue(method, location);
                context.ReportDiagnostic(issue);
            }
        }
示例#5
0
        private void AnalyzeLockStatement(SyntaxNodeAnalysisContext context)
        {
            var lockStatement = (LockStatementSyntax)context.Node;

            var method = context.GetEnclosingMethod();
            var events = method.ContainingType.GetMembersIncludingInherited <IEventSymbol>().Select(_ => _.Name).ToHashSet();

            foreach (var token in lockStatement.DescendantTokens().Where(_ => _.IsKind(SyntaxKind.IdentifierToken)))
            {
                var eventName = token.ValueText;

                if (events.Contains(eventName) && token.GetSymbol(context.SemanticModel) is IEventSymbol)
                {
                    var issue = Issue(method.Name, token);
                    context.ReportDiagnostic(issue);
                }
            }
        }
        private void AnalyzeSimpleMemberAccessExpression(SyntaxNodeAnalysisContext context)
        {
            var node = (MemberAccessExpressionSyntax)context.Node;

            if (NodeHasIssue(node, context.SemanticModel))
            {
                var methodSymbol = context.GetEnclosingMethod();
                if (methodSymbol is null)
                {
                    // nameof() is also a SimpleMemberAccessExpression, so assignments of lists etc. may cause an NRE to be thrown
                    return;
                }

                var issue = Issue(methodSymbol.Name, node);

                context.ReportDiagnostic(issue);
            }
        }
        private void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode methodBody, SeparatedSyntaxList <ParameterSyntax> parameters)
        {
            if (methodBody is null)
            {
                return;
            }

            if (parameters.Count == 0)
            {
                return;
            }

            var methodSymbol = context.GetEnclosingMethod();

            if (CanBeIgnored(methodSymbol))
            {
                return;
            }

            var used = GetAllUsedVariables(context, methodBody);

            foreach (var parameter in parameters)
            {
                var parameterName = parameter.GetName();

                if (used.Contains(parameterName))
                {
                    continue;
                }

                // TODO: RKN check if the documentation contains the phrase 'Unused.' and Do not report an issue in such case
                if (methodSymbol.IsEnhancedByPostSharpAdvice())
                {
                    continue;
                }

                var diagnostic = Issue(parameterName, parameter.Identifier);
                context.ReportDiagnostic(diagnostic);
            }
        }
        private void AnalyzeFinallyClause(SyntaxNodeAnalysisContext context)
        {
            var finallyBlock = ((FinallyClauseSyntax)context.Node).Block;

            if (finallyBlock is null)
            {
                return;
            }

            var method = context.GetEnclosingMethod();
            var events = method.ContainingType.GetMembersIncludingInherited <IEventSymbol>().Select(_ => _.Name).ToHashSet();

            foreach (var token in finallyBlock.DescendantTokens().Where(_ => _.IsKind(SyntaxKind.IdentifierToken)))
            {
                var eventName = token.ValueText;

                if (events.Contains(eventName) && token.GetSymbol(context.SemanticModel) is IEventSymbol)
                {
                    var issue = Issue(method.Name, token, eventName);
                    context.ReportDiagnostic(issue);
                }
            }
        }
示例#9
0
        private new void AnalyzeLocalDeclarationStatement(SyntaxNodeAnalysisContext context)
        {
            var node        = (LocalDeclarationStatementSyntax)context.Node;
            var declaration = node.Declaration;

            if (declaration.Variables.Any(_ => _.IsTypeUnderTestVariable()))
            {
                // inspect associated test method
                var method = context.GetEnclosingMethod();
                if (method.IsTestMethod())
                {
                    var testClass = method.ContainingType;

                    var typeUnderTest     = declaration.GetTypeSymbol(context.SemanticModel);
                    var typeUnderTestName = GetTypeUnderTestName(testClass, typeUnderTest);

                    if (TestClassStartsWithName(testClass, typeUnderTestName) is false)
                    {
                        var diagnostic = Issue(testClass, typeUnderTestName + Constants.TestsSuffix);
                        context.ReportDiagnostic(diagnostic);
                    }
                }
            }
        }
示例#10
0
 private bool CanBeIgnored(SyntaxNodeAnalysisContext context) => ShallAnalyze(context.GetEnclosingMethod()) is false;