yog-script-analyze 0.4.0

Yog Script (.ys, .yns) analyzed: its lexer, parser and syntax tree, names resolved, the class index model — what the build and the editors read a source with.
Documentation
namespace System.Logging;

/// One provider's logger of a category, with the rule it follows: the
/// minimum level and filter the factory's rules give it.
public readonly sealed class ProviderLogger {
    public readonly ILogger Logger;
    /// Its provider keeps its own scopes (it doesn't write the factory's).
    public readonly bool KeepsOwnScopes;
    /// Its provider's names in the rules: its type's, its alias.
    public readonly string ProviderName;
    public readonly string? Alias;
    public readonly string Category;
    public readonly LogLevel MinLevel;
    public readonly Func<string?, string?, LogLevel, bool>? Filter;

    public ProviderLogger(in ILoggerProvider provider, string category, in LoggerFilterOptions options) {
        Logger = provider.CreateLogger(category);
        ProviderName = provider.GetType().FullName ?? provider.GetType().Name;
        Alias = AliasOf(provider);
        let (min, filter) = LoggerRuleSelector.Select(in options, (ProviderName, Alias), category);
        MinLevel = min;
        Filter = filter;
        Category = category;
        KeepsOwnScopes = !(provider is ISupportExternalScope);
    }

    /// `provider`'s `[ProviderAlias]`, if it has one.
    private static string? AliasOf(in ILoggerProvider provider) {
        foreach (let a in provider.GetType().GetCustomAttributes(false)) {
            if (a is ProviderAlias alias) {
                return alias.Alias;
            }
        }
        return null;
    }

    /// Whether its rule lets entries of `level` through to its logger.
    public bool Lets(LogLevel level) {
        if (level < MinLevel || level == LogLevel.None) {
            return false;
        }
        return Filter == null || Filter(ProviderName, Category, level);
    }
}