private void AnalyzeClassDeclaration()

in src/Microsoft.VisualStudio.SDK.Analyzers/VSSDK004ProvideAutoLoadAttributeAnalyzer.cs [61:104]


        private void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context, INamedTypeSymbol autoLoadAttributeType, INamedTypeSymbol packageAutoLoadFlagsType, INamedTypeSymbol packageType, INamedTypeSymbol asyncPackageType)
        {
            var declaration = (ClassDeclarationSyntax)context.Node;
            INamedTypeSymbol userClassSymbol = context.SemanticModel.GetDeclaredSymbol(declaration, context.CancellationToken);

            BaseTypeSyntax? baseType = declaration.BaseList?.Types.FirstOrDefault();
            if (baseType == null)
            {
                return;
            }

            // Don't evaluate if base type is not Package
            var baseTypeSymbol = context.SemanticModel.GetSymbolInfo(baseType.Type, context.CancellationToken).Symbol?.OriginalDefinition as ITypeSymbol;
            if (!Utils.IsEqualToOrDerivedFrom(baseTypeSymbol, packageType))
            {
                return;
            }

            bool isBaseTypeAsyncPackage = Utils.IsEqualToOrDerivedFrom(baseTypeSymbol, asyncPackageType);

            // Enumerate all attribute lists and attribute to find ProvideAutoLoad attributes as there can be multiple ones
            if (userClassSymbol is object)
            {
                foreach (AttributeData autoLoadInstance in userClassSymbol.GetAttributes().Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, autoLoadAttributeType)))
                {
                    TypedConstant flagsArgument = autoLoadInstance.ConstructorArguments.FirstOrDefault(p => SymbolEqualityComparer.Default.Equals(p.Type, packageAutoLoadFlagsType));
                    Types.PackageAutoLoadFlags.Values flagsValue = flagsArgument.IsNull ? Types.PackageAutoLoadFlags.Values.None : (Types.PackageAutoLoadFlags.Values)flagsArgument.Value;

                    // Check if AutoLoad attribute applies to VS versions with AsyncPackage support
                    if (flagsValue.HasFlag(Types.PackageAutoLoadFlags.Values.SkipWhenUIContextRulesActive))
                    {
                        continue;
                    }

                    // Check if BackgroundLoad flag is present and base class is AsyncPackage
                    if (!(flagsValue.HasFlag(Types.PackageAutoLoadFlags.Values.BackgroundLoad) && isBaseTypeAsyncPackage))
                    {
                        var attributeSyntax = (AttributeSyntax)autoLoadInstance.ApplicationSyntaxReference.GetSyntax(context.CancellationToken);
                        Location location = attributeSyntax.GetLocation();
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, attributeSyntax.GetLocation()));
                    }
                }
            }
        }