Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,7 @@ dist

# Heft
.heft

# IntelliJ IDEA
.idea
*.iml
23 changes: 23 additions & 0 deletions apps/api-extractor/src/collector/Collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export class Collector {
AstEntity,
CollectorEntity
>();
private readonly _entitiesBySymbol: Map<ts.Symbol, CollectorEntity> = new Map<ts.Symbol, CollectorEntity>();

private readonly _starExportedExternalModulePaths: string[] = [];

Expand Down Expand Up @@ -301,6 +302,23 @@ export class Collector {
return this._entitiesByAstEntity.get(astEntity);
}

/**
* Returns the name to emit for the given `symbol`.
* This is usually the `name` of that `symbol`.
* Only if this `symbol` has a `CollectorEntity`, the `nameForEmit` of that entity is used.
* @param symbol the symbol to compute the name to emit for
* @returns the name to emit for the given `symbol`
*/
public getEmitName(symbol: ts.Symbol): string {
const collectorEntity: CollectorEntity | undefined = this._entitiesBySymbol.get(symbol);
return collectorEntity?.nameForEmit ?? symbol.name;
}

public getNamespacePath(symbol: ts.Symbol): string[] {
const collectorEntity: CollectorEntity | undefined = this._entitiesBySymbol.get(symbol);
return collectorEntity ? collectorEntity.getParentPath() : [];
}

public fetchSymbolMetadata(astSymbol: AstSymbol): SymbolMetadata {
if (astSymbol.symbolMetadata === undefined) {
this._fetchSymbolMetadata(astSymbol);
Expand Down Expand Up @@ -420,6 +438,11 @@ export class Collector {
entity = new CollectorEntity(astEntity);

this._entitiesByAstEntity.set(astEntity, entity);
if (astEntity instanceof AstSymbol) {
this._entitiesBySymbol.set(astEntity.followedSymbol, entity);
} else if (astEntity instanceof AstNamespaceImport) {
this._entitiesBySymbol.set((astEntity.declaration as unknown as ts.Type).symbol, entity);
}
this._entities.push(entity);
this._collectReferenceDirectives(astEntity);
}
Expand Down
21 changes: 21 additions & 0 deletions apps/api-extractor/src/collector/CollectorEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,27 @@ export class CollectorEntity {
return this._localExportNamesByParent.size > 0;
}

public getParentPath(): string[] {
let current: CollectorEntity | undefined = this;
const result: string[] = [];
while (current) {
current = current._getFirstParent();
if (current) {
result.unshift(current.nameForEmit ?? current.singleExportName!);
}
}
return result;
}

private _getFirstParent(): CollectorEntity | undefined {
for (const [parent, localExportNames] of this._localExportNamesByParent) {
if (parent.consumable && localExportNames.size > 0) {
return parent;
}
}
return undefined;
}

/**
* Adds a new export name to the entity.
*/
Expand Down
20 changes: 18 additions & 2 deletions apps/api-extractor/src/generators/DeclarationReferenceGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export class DeclarationReferenceGenerator {
return undefined;
}

let localName: string = followedSymbol.name;
let localName: string = this._collector.getEmitName(followedSymbol);
if (followedSymbol.escapedName === ts.InternalSymbolName.Constructor) {
localName = 'constructor';
} else {
Expand Down Expand Up @@ -271,11 +271,17 @@ export class DeclarationReferenceGenerator {
// First, try to find a parent symbol via the symbol tree.
const parentSymbol: ts.Symbol | undefined = TypeScriptInternals.getSymbolParent(symbol);
if (parentSymbol) {
return this._symbolToDeclarationReference(
const parentRef: DeclarationReference | undefined = this._symbolToDeclarationReference(
parentSymbol,
parentSymbol.flags,
/*includeModuleSymbols*/ true
);
if (parentRef) {
return DeclarationReferenceGenerator._addNavigationSteps(
parentRef,
this._collector.getNamespacePath(symbol)
);
}
}

// If that doesn't work, try to find a parent symbol via the node tree. As far as we can tell,
Expand Down Expand Up @@ -342,4 +348,14 @@ export class DeclarationReferenceGenerator {
}
return GlobalSource.instance;
}

private static _addNavigationSteps(
declaration: DeclarationReference,
components: string[]
): DeclarationReference {
return components.reduce(
(declaration, component) => declaration.addNavigationStep(Navigation.Exports, component),
declaration
);
}
}
2 changes: 2 additions & 0 deletions build-tests/api-extractor-scenarios/config/build-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"docReferences",
"docReferences2",
"docReferences3",
"docReferencesAlias",
"docReferencesNamespaceAlias",
"dynamicImportType",
"dynamicImportType2",
"dynamicImportType3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@
{
"kind": "Reference",
"text": "MyPromise",
"canonicalReference": "api-extractor-scenarios!~Promise:class"
"canonicalReference": "api-extractor-scenarios!~Promise_2:class"
},
{
"kind": "Content",
Expand Down
Loading