public override IEnumerable <Diagnostic> Analyze(Compilation compilation, SemanticModel semanticModel, SyntaxNode node, CancellationToken cancel)
        {
            var classSyntax = (ClassDeclarationSyntax)node;
            var types       = new ExtensibilityTypes(compilation);
            var classSymbol = semanticModel.GetDeclaredSymbol(classSyntax, cancel);

            if (classSymbol == null)
            {
                yield break;
            }
            // only look at concrete implementations.
            if (classSymbol.IsAbstract)
            {
                yield break;
            }
            if (!classSymbol.AllInterfaces.Any(i => SymbolEqualityComparer.Default.Equals(i, types.IPlugin)))
            {
                yield break;
            }
            if (classSymbol.GetAttributes()
                .FirstOrDefault(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, types.PluginAttribute)) is not AttributeData pluginAttribute)
            {
                yield break;
            }
            if (pluginAttribute.ConstructorArguments.FirstOrDefault().Value is not string attributeName)
            {
                yield break;
            }
            if (string.Equals(attributeName, "common", System.StringComparison.InvariantCultureIgnoreCase))
            {
                yield return(Diagnostic.Create(Rule, pluginAttribute.ApplicationSyntaxReference?.GetSyntax(cancel).GetLocation(), classSymbol.Name));
            }
        }
        public override IEnumerable <Diagnostic> Analyze(Compilation compilation, SemanticModel semanticModel, SyntaxNode node, CancellationToken cancel)
        {
            var types        = new ExtensibilityTypes(compilation);
            var methodSyntax = (MethodDeclarationSyntax)node;

            if (semanticModel.GetDeclaredSymbol(methodSyntax) is not IMethodSymbol methodSymbol)
            {
                yield break;
            }
            if (methodSymbol.Name != "Compose")
            {
                yield break;
            }
            if (!methodSymbol.ContainingType.AllInterfaces.Any(i => SymbolEqualityComparer.Default.Equals(i, types.IComposable)))
            {
                yield break;
            }

            var importedServices = new HashSet <INamedTypeSymbol>();

            foreach (var attr in methodSymbol.GetAttributes())
            {
                if (!SymbolEqualityComparer.Default.Equals(attr.AttributeClass, types.ImportServiceAttribute))
                {
                    continue;
                }
                if (attr.ConstructorArguments.FirstOrDefault().Value is not INamedTypeSymbol importedType)
                {
                    continue;
                }
                importedServices.Add(importedType);
            }

            foreach (var expr in methodSyntax.Body?.DescendantNodes()
                     .Where(a => a is MemberAccessExpressionSyntax).Cast <MemberAccessExpressionSyntax>()
                     ?? Enumerable.Empty <MemberAccessExpressionSyntax>())
            {
                if (semanticModel.GetSymbolInfo(expr, cancel).Symbol is not IMethodSymbol getMethod)
                {
                    continue;
                }
                if (getMethod.Name != "Get" || !getMethod.IsGenericMethod || !SymbolEqualityComparer.Default.Equals(getMethod.ContainingType, types.IServiceRepository))
                {
                    continue;
                }
                var requestedType = getMethod.TypeArguments.FirstOrDefault();
                if (!importedServices.Contains(requestedType))
                {
                    yield return(Diagnostic.Create(Rule, expr.GetLocation(), requestedType?.Name));
                }
            }
        }
        public override IEnumerable <Diagnostic> Analyze(Compilation compilation, SemanticModel semanticModel, SyntaxNode node, CancellationToken cancel)
        {
            var classSyntax = (ClassDeclarationSyntax)node;
            var types       = new ExtensibilityTypes(compilation);
            var classSymbol = semanticModel.GetDeclaredSymbol(classSyntax, cancel);

            if (classSymbol == null)
            {
                yield break;
            }
            // only look at concrete implementations.
            if (classSymbol.IsAbstract)
            {
                yield break;
            }
            if (!classSymbol.AllInterfaces.Any(i => SymbolEqualityComparer.Default.Equals(i, types.IPlugin)))
            {
                yield break;
            }
            if (!classSymbol.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, types.PluginAttribute)))
            {
                yield return(Diagnostic.Create(Rule, classSyntax.GetLocation(), classSymbol.Name));
            }
        }