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()));
}
}
}
}