Esempio n. 1
0
        private void AnalyzeExpression(SyntaxNodeAnalysisContext context, ConcurrentDictionary <int, Diagnostic> reports)
        {
            var parentKind = context.Node.Parent.Kind();

            // will be handled at higher level
            if (parentKind == SyntaxKind.SimpleMemberAccessExpression || parentKind == SyntaxKind.QualifiedName)
            {
                return;
            }

            var target = GetTargetOfNode(context.Node, context.SemanticModel);

            if (target == null)
            {
                return;
            }

            var platform = Analyzer.GetPlatformForSymbol(target);

            // Some quick escapes
            if (platform.Kind == PlatformKind.Unchecked)
            {
                return;
            }

            if (platform.Kind == PlatformKind.Uwp && platform.Version == Analyzer.N2SDKVersion)
            {
                return;
            }

            // Is this expression inside a method/constructor/property that claims to be specific?
            DeclarationStatementSyntax containingMember = context.Node.FirstAncestorOrSelf <MethodBlockBaseSyntax>();

            if (containingMember is AccessorBlockSyntax)
            {
                containingMember = containingMember.FirstAncestorOrSelf <PropertyBlockSyntax>();
            }

            // Is this invocation properly guarded? See readme.md for explanations.
            if (IsProperlyGuarded(context.Node, context.SemanticModel))
            {
                return;
            }

            if (containingMember != null)
            {
                foreach (var ret in containingMember.DescendantNodes().OfType <ReturnStatementSyntax>())
                {
                    if (IsProperlyGuarded(ret, context.SemanticModel))
                    {
                        return;
                    }
                }
            }

            // We'll report only a single diagnostic per line, the first.
            var loc = context.Node.GetLocation();

            if (!loc.IsInSource)
            {
                return;
            }

            var line = loc.GetLineSpan().StartLinePosition.Line;

            if (reports.TryGetValue(line, out var diagnostic) && diagnostic.Location.SourceSpan.Start <= loc.SourceSpan.Start)
            {
                return;
            }

            diagnostic = Diagnostic.Create(platform.Kind == PlatformKind.Uwp ? Analyzer.VersionRule : Analyzer.PlatformRule, loc);

            reports[line] = diagnostic;

            context.ReportDiagnostic(diagnostic);
        }