190 lines
6.3 KiB
C#
190 lines
6.3 KiB
C#
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<AssemblySymbol>
|
|
{
|
|
private static readonly ObjectPool<BindingDiagnosticBag> s_poolWithBoth = new ObjectPool<BindingDiagnosticBag>((Factory<BindingDiagnosticBag>)(() => new BindingDiagnosticBag(s_poolWithBoth, new DiagnosticBag(), new HashSet<AssemblySymbol>())), true);
|
|
|
|
private static readonly ObjectPool<BindingDiagnosticBag> s_poolWithDiagnosticsOnly = new ObjectPool<BindingDiagnosticBag>((Factory<BindingDiagnosticBag>)(() => new BindingDiagnosticBag(s_poolWithDiagnosticsOnly, new DiagnosticBag(), null)), true);
|
|
|
|
private static readonly ObjectPool<BindingDiagnosticBag> s_poolWithDependenciesOnly = new ObjectPool<BindingDiagnosticBag>((Factory<BindingDiagnosticBag>)(() => new BindingDiagnosticBag(s_poolWithDependenciesOnly, null, new HashSet<AssemblySymbol>())), true);
|
|
|
|
private static readonly ObjectPool<BindingDiagnosticBag> s_poolWithConcurrent = new ObjectPool<BindingDiagnosticBag>((Factory<BindingDiagnosticBag>)(() => new BindingDiagnosticBag(s_poolWithConcurrent, new DiagnosticBag(), (ICollection<AssemblySymbol>?)new ConcurrentSet<AssemblySymbol>())), true);
|
|
|
|
public static readonly BindingDiagnosticBag Discarded = new BindingDiagnosticBag(null, null);
|
|
|
|
private readonly ObjectPool<BindingDiagnosticBag>? _pool;
|
|
|
|
private BindingDiagnosticBag(DiagnosticBag? diagnosticBag, ICollection<AssemblySymbol>? dependenciesBag)
|
|
: base(diagnosticBag, dependenciesBag)
|
|
{
|
|
}
|
|
|
|
private BindingDiagnosticBag(ObjectPool<BindingDiagnosticBag> pool, DiagnosticBag? diagnosticBag, ICollection<AssemblySymbol>? 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<AssemblySymbol>)(object)template).AccumulatesDependencies);
|
|
}
|
|
|
|
internal static BindingDiagnosticBag GetConcurrentInstance()
|
|
{
|
|
return s_poolWithConcurrent.Allocate();
|
|
}
|
|
|
|
internal override void Free()
|
|
{
|
|
ObjectPool<BindingDiagnosticBag> 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<TData>(Symbol? symbol, Func<TData, Location> getLocation, TData data)
|
|
{
|
|
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
|
|
if ((object)symbol != null)
|
|
{
|
|
return base.Add<TData>(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<NamespaceSymbol>.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<Symbol> symbols, params object[] args)
|
|
{
|
|
CSDiagnosticInfo cSDiagnosticInfo = new CSDiagnosticInfo(code, args, symbols, ImmutableArray<Location>.Empty);
|
|
Add((DiagnosticInfo?)(object)cSDiagnosticInfo, location);
|
|
return cSDiagnosticInfo;
|
|
}
|
|
|
|
internal void Add(DiagnosticInfo? info, Location location)
|
|
{
|
|
if (info != null)
|
|
{
|
|
((BindingDiagnosticBag)this).DiagnosticBag?.Add(info, location);
|
|
}
|
|
}
|
|
}
|