using System.IO; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.CSharp.Util; namespace Semmle.Extraction.CSharp.Entities { internal class Event : CachedSymbol { private Event(Context cx, IEventSymbol init) : base(cx, init) { } public override void WriteId(EscapingTextWriter trapFile) { trapFile.WriteSubId(ContainingType!); trapFile.Write('.'); Method.AddExplicitInterfaceQualifierToId(Context, trapFile, Symbol.ExplicitInterfaceImplementations); trapFile.Write(Symbol.Name); trapFile.Write(";event"); } public override void Populate(TextWriter trapFile) { PopulateNullability(trapFile, Symbol.GetAnnotatedType()); var type = Type.Create(Context, Symbol.Type); trapFile.events(this, Symbol.GetName(), ContainingType!, type.TypeRef, Create(Context, Symbol.OriginalDefinition)); var adder = Symbol.AddMethod; var remover = Symbol.RemoveMethod; if (!(adder is null)) Method.Create(Context, adder); if (!(remover is null)) Method.Create(Context, remover); PopulateModifiers(trapFile); BindComments(); var declSyntaxReferences = IsSourceDeclaration ? Symbol.DeclaringSyntaxReferences.Select(d => d.GetSyntax()).ToArray() : Enumerable.Empty(); foreach (var explicitInterface in Symbol.ExplicitInterfaceImplementations.Select(impl => Type.Create(Context, impl.ContainingType))) { trapFile.explicitly_implements(this, explicitInterface.TypeRef); foreach (var syntax in declSyntaxReferences.OfType()) TypeMention.Create(Context, syntax.ExplicitInterfaceSpecifier!.Name, this, explicitInterface); } if (Context.ExtractLocation(Symbol)) { WriteLocationsToTrap(trapFile.event_location, this, Locations); } foreach (var syntaxType in declSyntaxReferences .OfType() .Select(d => d.Parent) .OfType() .Select(syntax => syntax.Type)) { TypeMention.Create(Context, syntaxType, this, type); } } public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntityFromSymbol(cx, symbol); private class EventFactory : CachedEntityFactory { public static EventFactory Instance { get; } = new EventFactory(); public override Event Create(Context cx, IEventSymbol init) => new Event(cx, init); } } }