import { TraitInfo } from "./TraitInfo"; import { Info } from "./Info"; import { IndentingWriter } from "../../../base/utilities"; import { Multiname } from "./Multiname"; import { RuntimeTraits } from "./RuntimeTraits"; import { Namespace } from "./Namespace"; import { Scope } from "../../run/Scope"; /** * The Traits class represents the collection of compile-time traits associated with a type. * It's not used for runtime name resolution on instances; instead, the combined traits for * a type and all its super types is resolved and translated to an instance of RuntimeTraits. */ export declare class Traits { traits: TraitInfo[]; private _resolved; constructor(traits: TraitInfo[]); resolve(): void; attachHolder(holder: Info): void; trace(writer?: IndentingWriter): void; /** * Searches for a trait with the specified name. */ private indexOf; private multinames; getTrait(mn: Multiname): TraitInfo; /** * Turns a list of compile-time traits into runtime traits with resolved bindings. * * Runtime traits are stored in 2-dimensional maps. The outer dimension is keyed on the * trait's local name. The inner dimension is a map of mangled namespace names to traits. * * Lookups are thus O(n) in the number of namespaces present in the query, instead of O(n+m) * in the number of traits (n) on the type times the number of namespaces present in the * query (m). * * Negative result note: an implementation with ECMAScript Maps with Namespace objects as * keys was tried and found to be much slower than the Object-based one implemented here. * Mostly, the difference was in how well accesses are optimized in JS engines, with Maps * being new-ish and less well-optimized. * * Additionally, all protected traits get added to a map with their unqualified name as key. * That map is created with the super type's map on its prototype chain. If a type overrides * a protected trait, it gets set as that type's value for the unqualified name. Additionally, * its name is canonicalized to use the namespace used in the initially introducing type. * During name lookup, we first check for a hit in that map and (after verifying that the mn * has a correct protected name in its namespaces set) return the most recent trait. That way, * all lookups always get the most recent trait, even if they originate from a super class. */ resolveRuntimeTraits(superTraits: RuntimeTraits, protectedNs: Namespace, scope: Scope): RuntimeTraits; }