11// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22// See LICENSE in the project root for license information.s
33
4- import { ApiItem , ApiItem_onParentChanged , IApiItemJson , IApiItemOptions , IApiItemConstructor } from '../items/ApiItem' ;
4+ import {
5+ ApiItem ,
6+ ApiItem_onParentChanged ,
7+ IApiItemJson ,
8+ IApiItemOptions ,
9+ IApiItemConstructor ,
10+ ApiItemKind
11+ } from '../items/ApiItem' ;
512import { ApiNameMixin } from './ApiNameMixin' ;
613import { DeserializerContext } from '../model/DeserializerContext' ;
14+ import { InternalError } from '@microsoft/node-core-library' ;
715
816/**
917 * Constructor options for {@link (ApiItemContainerMixin:interface)}.
@@ -21,6 +29,7 @@ const _members: unique symbol = Symbol('ApiItemContainerMixin._members');
2129const _membersSorted : unique symbol = Symbol ( 'ApiItemContainerMixin._membersSorted' ) ;
2230const _membersByContainerKey : unique symbol = Symbol ( 'ApiItemContainerMixin._membersByContainerKey' ) ;
2331const _membersByName : unique symbol = Symbol ( 'ApiItemContainerMixin._membersByName' ) ;
32+ const _membersByKind : unique symbol = Symbol ( 'ApiItemContainerMixin._membersByKind' ) ;
2433
2534/**
2635 * The mixin base class for API items that act as containers for other child items.
@@ -73,6 +82,12 @@ export interface ApiItemContainerMixin extends ApiItem {
7382 */
7483 findMembersByName ( name : string ) : ReadonlyArray < ApiItem > ;
7584
85+ /**
86+ * For a given member of this container, return its `ApiItem.getMergedSiblings()` list.
87+ * @internal
88+ */
89+ _getMergedSiblingsForMember ( memberApiItem : ApiItem ) : ReadonlyArray < ApiItem > ;
90+
7691 /** @override */
7792 serializeInto ( jsonObject : Partial < IApiItemJson > ) : void ;
7893}
@@ -92,8 +107,15 @@ export function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(ba
92107 public readonly [ _members ] : ApiItem [ ] ;
93108 public [ _membersSorted ] : boolean ;
94109 public [ _membersByContainerKey ] : Map < string , ApiItem > ;
110+
111+ // For members of this container that extend ApiNameMixin, this stores the list of members with a given name.
112+ // Examples include merged declarations, overloaded functions, etc.
95113 public [ _membersByName ] : Map < string , ApiItem [ ] > | undefined ;
96114
115+ // For members of this container that do NOT extend ApiNameMixin, this stores the list of members
116+ // that share a common ApiItemKind. Examples include overloaded constructors or index signatures.
117+ public [ _membersByKind ] : Map < string , ApiItem [ ] > | undefined ; // key is ApiItemKind
118+
97119 /** @override */
98120 public static onDeserializeInto ( options : Partial < IApiItemContainerMixinOptions > ,
99121 context : DeserializerContext , jsonObject : IApiItemContainerJson ) : void {
@@ -142,6 +164,7 @@ export function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(ba
142164
143165 this [ _members ] . push ( member ) ;
144166 this [ _membersByName ] = undefined ; // invalidate the lookup
167+ this [ _membersByKind ] = undefined ; // invalidate the lookup
145168 this [ _membersSorted ] = false ;
146169 this [ _membersByContainerKey ] . set ( member . containerKey , member ) ;
147170
@@ -153,25 +176,55 @@ export function ApiItemContainerMixin<TBaseClass extends IApiItemConstructor>(ba
153176 }
154177
155178 public findMembersByName ( name : string ) : ReadonlyArray < ApiItem > {
156- // Build the lookup on demand
179+ this . _ensureMemberMaps ( ) ;
180+ return this [ _membersByName ] ! . get ( name ) || [ ] ;
181+ }
182+
183+ /** @internal */
184+ public _getMergedSiblingsForMember ( memberApiItem : ApiItem ) : ReadonlyArray < ApiItem > {
185+ this . _ensureMemberMaps ( ) ;
186+ let result : ApiItem [ ] | undefined ;
187+ if ( ApiNameMixin . isBaseClassOf ( memberApiItem ) ) {
188+ result = this [ _membersByName ] ! . get ( memberApiItem . name ) ;
189+ } else {
190+ result = this [ _membersByKind ] ! . get ( memberApiItem . kind ) ;
191+ }
192+ if ( ! result ) {
193+ throw new InternalError ( 'Item was not found in the _membersByName/_membersByKind lookup' ) ;
194+ }
195+ return result ;
196+ }
197+
198+ /** @internal */
199+ public _ensureMemberMaps ( ) : void {
200+ // Build the _membersByName and _membersByKind tables if they don't already exist
157201 if ( this [ _membersByName ] === undefined ) {
158- const map : Map < string , ApiItem [ ] > = new Map < string , ApiItem [ ] > ( ) ;
202+ const membersByName : Map < string , ApiItem [ ] > = new Map < string , ApiItem [ ] > ( ) ;
203+ const membersByKind : Map < string , ApiItem [ ] > = new Map < string , ApiItem [ ] > ( ) ;
159204
160205 for ( const member of this [ _members ] ) {
206+ let map : Map < string , ApiItem [ ] > | Map < ApiItemKind , ApiItem [ ] > ;
207+ let key : string | ApiItemKind ;
208+
161209 if ( ApiNameMixin . isBaseClassOf ( member ) ) {
162- let list : ApiItem [ ] | undefined = map . get ( member . name ) ;
163- if ( list === undefined ) {
164- list = [ ] ;
165- map . set ( member . name , list ) ;
166- }
167- list . push ( member ) ;
210+ map = membersByName ;
211+ key = member . name ;
212+ } else {
213+ map = membersByKind ;
214+ key = member . kind ;
168215 }
216+
217+ let list : ApiItem [ ] | undefined = map . get ( key ) ;
218+ if ( list === undefined ) {
219+ list = [ ] ;
220+ map . set ( key , list ) ;
221+ }
222+ list . push ( member ) ;
169223 }
170224
171- this [ _membersByName ] = map ;
225+ this [ _membersByName ] = membersByName ;
226+ this [ _membersByKind ] = membersByKind ;
172227 }
173-
174- return this [ _membersByName ] ! . get ( name ) || [ ] ;
175228 }
176229
177230 /** @override */
0 commit comments