예제 #1
0
        private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context)
        {
            var fieldDeclarationSyntax = context.GetSuppressibleNode <VariableDeclaratorSyntax>(diagnostic);

            if (fieldDeclarationSyntax == null)
            {
                return;
            }

            var model = context.GetSemanticModel(diagnostic.Location.SourceTree);

            if (!(model.GetDeclaredSymbol(fieldDeclarationSyntax) is IFieldSymbol fieldSymbol))
            {
                return;
            }

            if (!IsSuppressable(fieldSymbol))
            {
                return;
            }

            foreach (var descriptor in SupportedSuppressions.Where(d => d.SuppressedDiagnosticId == diagnostic.Id))
            {
                context.ReportSuppression(Suppression.Create(descriptor, diagnostic));
            }
        }
예제 #2
0
        private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context)
        {
            var binaryExpression = context.GetSuppressibleNode <BinaryExpressionSyntax>(diagnostic);

            if (binaryExpression == null)
            {
                return;
            }

            AnalyzeBinaryExpression(diagnostic, context, binaryExpression);
        }
        private static void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context)
        {
            var model = context.GetSemanticModel(diagnostic.Location.SourceTree);
            var methodDeclarationSyntax = context.GetSuppressibleNode <MethodDeclarationSyntax>(diagnostic);

            // Reuse the same detection logic regarding decorated methods with *InitializeOnLoadMethodAttribute
            if (InitializeOnLoadMethodAnalyzer.MethodMatches(methodDeclarationSyntax, model, out _, out _))
            {
                context.ReportSuppression(Suppression.Create(Rule, diagnostic));
            }
        }
예제 #4
0
        public override void ReportSuppressions(SuppressionAnalysisContext context)
        {
            foreach (var diagnostic in context.ReportedDiagnostics)
            {
                var root = diagnostic.Location.SourceTree.GetRoot();
                var node = root?.FindNode(diagnostic.Location.SourceSpan);

                var classDeclaration = node?.FirstAncestorOrSelf <ClassDeclarationSyntax>();
                if (classDeclaration is null)
                {
                    continue;
                }

                var model  = context.GetSemanticModel(diagnostic.Location.SourceTree);
                var symbol = model?.GetDeclaredSymbol(classDeclaration);
                if (symbol is null)
                {
                    continue;
                }

                var scriptInfo = new ScriptInfo(symbol);
                if (!scriptInfo.HasMessages)
                {
                    continue;
                }

                var propertyDeclaration = node.FirstAncestorOrSelf <PropertyDeclarationSyntax>();

                //handle properties before fields to minimize double checking of potential backing fields
                if (!(propertyDeclaration is null))
                {
                    AnalyzeProperties(propertyDeclaration, diagnostic, context, root);
                    continue;
                }

                var fieldDeclaration = context.GetSuppressibleNode <VariableDeclaratorSyntax>(diagnostic);
                if (fieldDeclaration != null)
                {
                    AnalyzeFields(fieldDeclaration, diagnostic, context, root);
                }

                //TODO handle nullable warnings for constructors => diagnostic location is now on constructor
                //TODO handle other Unity objects that cannot be initialized => e.g. Unity's new Input system
            }
        }
        private static void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context)
        {
            var sourceTree = diagnostic.Location.SourceTree;
            var root       = sourceTree.GetRoot(context.CancellationToken);

            var methodDeclarationSyntax = context.GetSuppressibleNode <MethodDeclarationSyntax>(diagnostic);

            if (methodDeclarationSyntax == null)
            {
                return;
            }

            var model = context.GetSemanticModel(diagnostic.Location.SourceTree);

            if (!(model.GetDeclaredSymbol(methodDeclarationSyntax) is IMethodSymbol methodSymbol))
            {
                return;
            }

            var typeSymbol = methodSymbol.ContainingType;

            if (!typeSymbol.Extends(typeof(UnityEngine.MonoBehaviour)))
            {
                return;
            }

            while (typeSymbol.ContainingType != null && typeSymbol.ContainingType.Extends(typeof(UnityEngine.MonoBehaviour)))
            {
                typeSymbol = typeSymbol.ContainingType;
            }

            var references = new List <InvocationExpressionSyntax>();

            foreach (var typeNode in typeSymbol.Locations.Select(location => root.FindNode(location.SourceSpan)))
            {
                references.AddRange(typeNode.DescendantNodes()
                                    .OfType <InvocationExpressionSyntax>()
                                    .Where(e => MethodInvocationAnalyzer.InvocationMatches(e, out string argument) && argument == methodSymbol.Name));
            }

            if (references.Any())
            {
                context.ReportSuppression(Suppression.Create(Rule, diagnostic));
            }
        }
예제 #6
0
        private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context)
        {
            var location = diagnostic.Location;
            var model    = context.GetSemanticModel(location.SourceTree);
            var symbols  = new List <ISymbol>();

            var node = context.GetSuppressibleNode <SyntaxNode>(diagnostic, n => n is MethodDeclarationSyntax || n is VariableDeclaratorSyntax || n is FieldDeclarationSyntax);

            switch (node)
            {
            case MethodDeclarationSyntax method:
                symbols.Add(model.GetDeclaredSymbol(method));
                break;

            case VariableDeclaratorSyntax vdec:
                symbols.Add(model.GetDeclaredSymbol(vdec));
                break;

            case FieldDeclarationSyntax fdec:
                symbols.AddRange(fdec.Declaration.Variables.Select(v => model.GetDeclaredSymbol(v)));
                break;
            }

            var reportableSymbols = symbols
                                    .Where(IsReportable)
                                    .ToList();

            if (!reportableSymbols.Any())
            {
                return;
            }

            if (reportableSymbols.FirstOrDefault() is IMethodSymbol)
            {
                context.ReportSuppression(Suppression.Create(ContextMenuRule, diagnostic));
            }
            else
            {
                foreach (var descriptor in SupportedSuppressions.Where(d => d.SuppressedDiagnosticId == diagnostic.Id))
                {
                    context.ReportSuppression(Suppression.Create(descriptor, diagnostic));
                }
            }
        }
        private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context)
        {
            var node = context.GetSuppressibleNode <SyntaxNode>(diagnostic, n => n is ParameterSyntax || n is MethodDeclarationSyntax);

            if (node is ParameterSyntax)
            {
                node = node
                       .Ancestors()
                       .OfType <MethodDeclarationSyntax>()
                       .FirstOrDefault();
            }

            if (node == null)
            {
                return;
            }

            var model = context.GetSemanticModel(diagnostic.Location.SourceTree);

            if (!(model.GetDeclaredSymbol(node) is IMethodSymbol methodSymbol))
            {
                return;
            }

            var scriptInfo = new ScriptInfo(methodSymbol.ContainingType);

            if (!scriptInfo.IsMessage(methodSymbol))
            {
                return;
            }

            foreach (var suppression in SupportedSuppressions)
            {
                if (suppression.SuppressedDiagnosticId == diagnostic.Id)
                {
                    context.ReportSuppression(Suppression.Create(suppression, diagnostic));
                }
            }
        }