using System; using System.Collections.Generic; using System.IO; using Semmle.Extraction.Entities; namespace Semmle.Extraction.CIL.Entities { /// /// A namespace. /// interface INamespace : ITypeContainer { } /// /// A namespace. /// public sealed class Namespace : TypeContainer, INamespace { public Namespace ParentNamespace; public readonly string Name; public bool IsGlobalNamespace => ParentNamespace == null; public override string IdSuffix => ";namespace"; public override void WriteId(TextWriter trapFile) { if (ParentNamespace != null && !ParentNamespace.IsGlobalNamespace) { ParentNamespace.WriteId(trapFile); trapFile.Write('.'); } trapFile.Write(Name); } public override bool Equals(object obj) { if (obj is Namespace ns && Name == ns.Name) { if (ParentNamespace is null) return ns.ParentNamespace is null; if (!(ns.ParentNamespace is null)) return ParentNamespace.Equals(ns.ParentNamespace); } return false; } public override int GetHashCode() { int h = ParentNamespace is null ? 19 : ParentNamespace.GetHashCode(); return 13 * h + Name.GetHashCode(); } public override IEnumerable TypeParameters => throw new NotImplementedException(); public override IEnumerable MethodParameters => throw new NotImplementedException(); static string parseNamespaceName(string fqn) { var i = fqn.LastIndexOf('.'); return i == -1 ? fqn : fqn.Substring(i + 1); } static Namespace createParentNamespace(Context cx, string fqn) { if (fqn == "") return null; var i = fqn.LastIndexOf('.'); return i == -1 ? cx.GlobalNamespace : cx.Populate(new Namespace(cx, fqn.Substring(0, i))); } public Namespace(Context cx, string fqn) : this(cx, parseNamespaceName(fqn), createParentNamespace(cx, fqn)) { } public Namespace(Context cx, string name, Namespace parent) : base(cx) { Name = name; ParentNamespace = parent; } public override IEnumerable Contents { get { yield return Tuples.namespaces(this, Name); if (!IsGlobalNamespace) yield return Tuples.parent_namespace(this, ParentNamespace); } } } }