public static DisposeAnalysisResult?TryGetOrComputeResult(
            ControlFlowGraph cfg,
            ISymbol owningSymbol,
            WellKnownTypeProvider wellKnownTypeProvider,
            AnalyzerOptions analyzerOptions,
            DiagnosticDescriptor rule,
            ImmutableHashSet <INamedTypeSymbol> disposeOwnershipTransferLikelyTypes,
            bool trackInstanceFields,
            bool exceptionPathsAnalysis,
            CancellationToken cancellationToken,
            out PointsToAnalysisResult?pointsToAnalysisResult,
            InterproceduralAnalysisKind interproceduralAnalysisKind = InterproceduralAnalysisKind.ContextSensitive,
            bool performCopyAnalysisIfNotUserConfigured             = false,
            InterproceduralAnalysisPredicate?interproceduralAnalysisPredicateOpt = null,
            bool defaultDisposeOwnershipTransferAtConstructor = false,
            bool defaultDisposeOwnershipTransferAtMethodCall  = false)
        {
            Debug.Assert(!owningSymbol.IsConfiguredToSkipAnalysis(analyzerOptions, rule, wellKnownTypeProvider.Compilation, cancellationToken));

            var interproceduralAnalysisConfig = InterproceduralAnalysisConfiguration.Create(
                analyzerOptions, rule, interproceduralAnalysisKind, cancellationToken);
            var disposeOwnershipTransferAtConstructor = analyzerOptions.GetDisposeOwnershipTransferAtConstructorOption(
                rule, defaultValue: defaultDisposeOwnershipTransferAtConstructor, cancellationToken);
            var disposeOwnershipTransferAtMethodCall = analyzerOptions.GetDisposeOwnershipTransferAtMethodCall(
                rule, defaultValue: defaultDisposeOwnershipTransferAtMethodCall, cancellationToken);

            return(TryGetOrComputeResult(cfg, owningSymbol, analyzerOptions, wellKnownTypeProvider,
                                         interproceduralAnalysisConfig, interproceduralAnalysisPredicateOpt,
                                         disposeOwnershipTransferLikelyTypes, disposeOwnershipTransferAtConstructor,
                                         disposeOwnershipTransferAtMethodCall, trackInstanceFields, exceptionPathsAnalysis,
                                         performCopyAnalysis: analyzerOptions.GetCopyAnalysisOption(rule, defaultValue: performCopyAnalysisIfNotUserConfigured, cancellationToken),
                                         excludedSymbols: analyzerOptions.GetExcludedSymbolNamesOption(rule, wellKnownTypeProvider.Compilation, cancellationToken),
                                         out pointsToAnalysisResult));
        }
        /// <summary>
        /// Returns true if the given symbol has been configured to be excluded from analysis by options.
        /// </summary>
        public static bool IsConfiguredToSkipAnalysis(
            this ISymbol symbol,
            AnalyzerOptions options,
            DiagnosticDescriptor rule,
            Compilation compilation,
            CancellationToken cancellationToken)
        {
            var excludedSymbols = options.GetExcludedSymbolNamesOption(rule, compilation, cancellationToken);
            var excludedTypeNamesWithDerivedTypes = options.GetExcludedTypeNamesWithDerivedTypesOption(rule, compilation, cancellationToken);

            if (excludedSymbols.IsEmpty && excludedTypeNamesWithDerivedTypes.IsEmpty)
            {
                return(false);
            }

            while (symbol != null)
            {
                if (excludedSymbols.Contains(symbol))
                {
                    return(true);
                }

                if (symbol is INamedTypeSymbol namedType && !excludedTypeNamesWithDerivedTypes.IsEmpty)
                {
                    foreach (var type in namedType.GetBaseTypesAndThis())
                    {
                        if (excludedTypeNamesWithDerivedTypes.Contains(type))
                        {
                            return(true);
                        }
                    }
                }

                symbol = symbol.ContainingSymbol;
            }

            return(false);
        }