using System; using System.Collections.Generic; using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp; internal sealed class BindingDiagnosticBag : BindingDiagnosticBag { private static readonly ObjectPool s_poolWithBoth = new ObjectPool((Factory)(() => new BindingDiagnosticBag(s_poolWithBoth, new DiagnosticBag(), new HashSet())), true); private static readonly ObjectPool s_poolWithDiagnosticsOnly = new ObjectPool((Factory)(() => new BindingDiagnosticBag(s_poolWithDiagnosticsOnly, new DiagnosticBag(), null)), true); private static readonly ObjectPool s_poolWithDependenciesOnly = new ObjectPool((Factory)(() => new BindingDiagnosticBag(s_poolWithDependenciesOnly, null, new HashSet())), true); private static readonly ObjectPool s_poolWithConcurrent = new ObjectPool((Factory)(() => new BindingDiagnosticBag(s_poolWithConcurrent, new DiagnosticBag(), (ICollection?)new ConcurrentSet())), true); public static readonly BindingDiagnosticBag Discarded = new BindingDiagnosticBag(null, null); private readonly ObjectPool? _pool; private BindingDiagnosticBag(DiagnosticBag? diagnosticBag, ICollection? dependenciesBag) : base(diagnosticBag, dependenciesBag) { } private BindingDiagnosticBag(ObjectPool pool, DiagnosticBag? diagnosticBag, ICollection? dependenciesBag) : base(diagnosticBag, dependenciesBag) { _pool = pool; } internal static BindingDiagnosticBag GetInstance() { return s_poolWithBoth.Allocate(); } internal static BindingDiagnosticBag GetInstance(bool withDiagnostics, bool withDependencies) { if (withDiagnostics) { if (withDependencies) { return GetInstance(); } return s_poolWithDiagnosticsOnly.Allocate(); } if (withDependencies) { return s_poolWithDependenciesOnly.Allocate(); } return Discarded; } internal static BindingDiagnosticBag GetInstance(BindingDiagnosticBag template) { return GetInstance(((BindingDiagnosticBag)template).AccumulatesDiagnostics, ((BindingDiagnosticBag)(object)template).AccumulatesDependencies); } internal static BindingDiagnosticBag GetConcurrentInstance() { return s_poolWithConcurrent.Allocate(); } internal override void Free() { ObjectPool pool = _pool; if (pool != null) { base.Clear(); pool.Free(this); } else { base.Free(); } } internal void AddDependencies(Symbol? symbol) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((object)symbol != null && base.DependenciesBag != null) { base.AddDependencies(symbol.GetUseSiteInfo()); } } internal bool ReportUseSite(Symbol? symbol, SyntaxNode node) { return ReportUseSite(symbol, (SyntaxNode val) => val.Location, node); } internal bool ReportUseSite(Symbol? symbol, SyntaxToken token) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) return ReportUseSite(symbol, (SyntaxToken val) => ((SyntaxToken)(ref val)).GetLocation(), token); } internal bool ReportUseSite(Symbol? symbol, Location location) { return ReportUseSite(symbol, (Location result) => result, location); } internal bool ReportUseSite(Symbol? symbol, Func getLocation, TData data) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if ((object)symbol != null) { return base.Add(symbol.GetUseSiteInfo(), getLocation, data); } return false; } internal void AddAssembliesUsedByNamespaceReference(NamespaceSymbol ns) { if (base.DependenciesBag != null) { addAssembliesUsedByNamespaceReferenceImpl(ns); } void addAssembliesUsedByNamespaceReferenceImpl(NamespaceSymbol namespaceSymbol) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if ((int)namespaceSymbol.Extent.Kind == 3) { ImmutableArray.Enumerator enumerator = namespaceSymbol.ConstituentNamespaces.GetEnumerator(); while (enumerator.MoveNext()) { NamespaceSymbol current = enumerator.Current; addAssembliesUsedByNamespaceReferenceImpl(current); } } else { AssemblySymbol containingAssembly = namespaceSymbol.ContainingAssembly; if ((object)containingAssembly != null && !containingAssembly.IsMissing) { base.DependenciesBag.Add(containingAssembly); } } } } protected override bool ReportUseSiteDiagnostic(DiagnosticInfo diagnosticInfo, DiagnosticBag diagnosticBag, Location location) { return Symbol.ReportUseSiteDiagnostic(diagnosticInfo, diagnosticBag, location); } internal CSDiagnosticInfo Add(ErrorCode code, Location location) { CSDiagnosticInfo cSDiagnosticInfo = new CSDiagnosticInfo(code); Add((DiagnosticInfo?)(object)cSDiagnosticInfo, location); return cSDiagnosticInfo; } internal CSDiagnosticInfo Add(ErrorCode code, SyntaxNode syntax, params object[] args) { return Add(code, syntax.Location, args); } internal CSDiagnosticInfo Add(ErrorCode code, SyntaxToken syntax, params object[] args) { return Add(code, ((SyntaxToken)(ref syntax)).GetLocation(), args); } internal CSDiagnosticInfo Add(ErrorCode code, Location location, params object[] args) { CSDiagnosticInfo cSDiagnosticInfo = new CSDiagnosticInfo(code, args); Add((DiagnosticInfo?)(object)cSDiagnosticInfo, location); return cSDiagnosticInfo; } internal CSDiagnosticInfo Add(ErrorCode code, Location location, ImmutableArray symbols, params object[] args) { CSDiagnosticInfo cSDiagnosticInfo = new CSDiagnosticInfo(code, args, symbols, ImmutableArray.Empty); Add((DiagnosticInfo?)(object)cSDiagnosticInfo, location); return cSDiagnosticInfo; } internal void Add(DiagnosticInfo? info, Location location) { if (info != null) { ((BindingDiagnosticBag)this).DiagnosticBag?.Add(info, location); } } }