private void ClassSealedCheck(SymbolAnalysisContext context)
        {
            // I don't care about generated code.
            if (context.IsGeneratedOrNonUserCode())
            {
                return;
            }

            INamedTypeSymbol symbol = context.Symbol as INamedTypeSymbol;

            // It's all about the class, no structure.
            if ((!symbol.IsValueType) && (!symbol.IsSealed) && (!symbol.IsStatic) && (!symbol.IsAbstract))
            {
                var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name);
                context.ReportDiagnostic(diagnostic);
            }
        }
        private void ClassSealedCheck(SymbolAnalysisContext context)
        {
            // I don't care about generated code.
            if (context.IsGeneratedOrNonUserCode())
            {
                return;
            }

            INamedTypeSymbol symbol = context.Symbol as INamedTypeSymbol;

            // It's all about the class, no structure.
            if ((!symbol.IsValueType) && (!symbol.IsSealed) && (!symbol.IsStatic) && (!symbol.IsAbstract))
            {
                var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name);
                context.ReportDiagnostic(diagnostic);
            }
        }
        private static void AnalyzeMethod(SymbolAnalysisContext context)
        {
            // I don't care about generated code.
            if (context.IsGeneratedOrNonUserCode())
            {
                return;
            }

            // Look for a return of Task<T> or Task
            // Look at method name
            // If doesn't end in Async, report diagnostic

            IMethodSymbol methodSymbol     = (IMethodSymbol)context.Symbol;
            ITypeSymbol   returnTypeSymbol = methodSymbol.ReturnType;

            // Make sure we are dealing with the true system type.
            String assemblyName = returnTypeSymbol?.ContainingAssembly?.Identity?.Name;

            if ((assemblyName != null) && (!assemblyName.Contains("mscorlib")))
            {
                return;
            }

            // Account for both Task and Task<T>
            if (!returnTypeSymbol.Name.StartsWith("Task"))
            {
                return;
            }

            // Now look at the method name from the code.
            if (methodSymbol.Name.ToString().EndsWith("Async"))
            {
                return;
            }

            // If here, we found an async method that does not end with "Async"
            var diagnostic = Diagnostic.Create(Rule,
                                               methodSymbol.Locations[0],
                                               methodSymbol.Name);

            context.ReportDiagnostic(diagnostic);
        }
        private static void AnalyzeMethod(SymbolAnalysisContext context)
        {
            // I don't care about generated code.
            if (context.IsGeneratedOrNonUserCode())
            {
                return;
            }

            // Look for a return of Task<T> or Task
            // Look at method name
            // If doesn't end in Async, report diagnostic

            IMethodSymbol methodSymbol = (IMethodSymbol)context.Symbol;
            ITypeSymbol returnTypeSymbol = methodSymbol.ReturnType;

            // Make sure we are dealing with the true system type.
            String assemblyName = returnTypeSymbol?.ContainingAssembly?.Identity?.Name;
            if ((assemblyName != null) && (!assemblyName.Contains("mscorlib")))
            {
                return;
            }

            // Account for both Task and Task<T>
            if (!returnTypeSymbol.Name.StartsWith("Task"))
            {
                return;
            }

            // Now look at the method name from the code.
            if (methodSymbol.Name.ToString().EndsWith("Async"))
            {
                return;
            }

            // If here, we found an async method that does not end with "Async"
            var diagnostic = Diagnostic.Create(Rule,
                                               methodSymbol.Locations[0],
                                               methodSymbol.Name);

            context.ReportDiagnostic(diagnostic);
        }
        private void AnalyzeSuppressMessage(SymbolAnalysisContext context)
        {
            if (context.IsGeneratedOrNonUserCode())
            {
                return;
            }

            // Look at the attributes for SuppressMessage.
            var attributes = context.Symbol.GetAttributes();
            for (Int32 i = 0; i < attributes.Count(); i++)
            {
                if (attributes[i].AttributeClass.Name.Equals("SuppressMessageAttribute"))
                {
                    Boolean hasJustification = false;

                    // Look for the named parameters for Justification and if it doesn't exist, 
                    // is empty, or has the text <Pending>, report the error.
                    var namedParams = attributes[i].NamedArguments;
                    for (Int32 j = 0; j < namedParams.Count(); j++)
                    {
                        if (namedParams[j].Key.Equals("Justification"))
                        {
                            String textValue = namedParams[j].Value.Value.ToString();
                            if ((String.IsNullOrEmpty(textValue) || (String.Equals(textValue, Resources.PendingText))))
                            {
                                var diagnostic = Diagnostic.Create(Rule, context.Symbol.Locations[0], context.Symbol.Name);
                                context.ReportDiagnostic(diagnostic);
                            }
                            hasJustification = true;
                        }
                    }

                    if (!hasJustification)
                    {
                        var diagnostic = Diagnostic.Create(Rule, context.Symbol.Locations[0], context.Symbol.Name);
                        context.ReportDiagnostic(diagnostic);
                    }
                }
            }
        }