using System.IO; namespace Semmle.Extraction { /// /// An abstract symbol, which encapsulates a data type (such as a C# symbol). /// /// The type of the symbol. public abstract class CachedEntity : ICachedEntity { public CachedEntity(Context context, Initializer init) { Context = context; symbol = init; } public Label Label { get; set; } public abstract Microsoft.CodeAnalysis.Location ReportingLocation { get; } public override string ToString() => Label.ToString(); public abstract void Populate(TextWriter trapFile); /// /// For debugging. /// public string DebugContents { get { using (var trap = new StringWriter()) { Populate(trap); return trap.ToString(); } } } public Context Context { get; private set; } public Initializer symbol { get; private set; } object ICachedEntity.UnderlyingObject => symbol; public Initializer UnderlyingObject => symbol; public abstract void WriteId(System.IO.TextWriter trapFile); public void WriteQuotedId(TextWriter trapFile) { trapFile.Write("@\""); WriteId(trapFile); trapFile.Write('\"'); } public abstract bool NeedsPopulation { get; } /// /// Runs the given action , guarding for trap duplication /// based on the ID an location of this entity. /// protected void WithDuplicationGuard(System.Action a, IEntity location) { var key = new Key(this, location); Context.WithDuplicationGuard(key, a); } public override int GetHashCode() => symbol.GetHashCode(); public override bool Equals(object obj) { var other = obj as CachedEntity; return other?.GetType() == GetType() && Equals(other.symbol, symbol); } public abstract TrapStackBehaviour TrapStackBehaviour { get; } } }