fix(api-extractor): links including entrypoints (#10924)

This commit is contained in:
Qjuh
2025-06-07 13:17:29 +02:00
committed by GitHub
parent db8c1d3edb
commit 9708717204
3 changed files with 100 additions and 57 deletions

View File

@@ -56,6 +56,7 @@ import type { ApiItemMetadata } from '../collector/ApiItemMetadata.js';
import type { Collector } from '../collector/Collector.js';
import type { DeclarationMetadata } from '../collector/DeclarationMetadata.js';
import type { ISourceLocation } from '../collector/SourceMapper.js';
import type { IWorkingPackageEntryPoint } from '../collector/WorkingPackage.js';
import { DeclarationReferenceGenerator } from './DeclarationReferenceGenerator.js';
import { ExcerptBuilder, type IExcerptBuilderNodeToCapture } from './ExcerptBuilder.js';
@@ -205,6 +206,7 @@ export interface DocgenJson {
typedefs: DocgenTypedefJson[];
}
interface IProcessAstEntityContext {
entryPoint: IWorkingPackageEntryPoint;
isExported: boolean;
name: string;
parentApiItem: ApiItemContainerMixin;
@@ -305,6 +307,7 @@ export class ApiModelGenerator {
// we are including forgotten exports, then process everything.
if (entity.exportedFromEntryPoint || this._collector.extractorConfig.docModelIncludeForgottenExports) {
this._processAstEntity(entity.astEntity, {
entryPoint,
name: entity.nameForEmit!,
isExported: entity.exportedFromEntryPoint,
parentApiItem: apiEntryPoint,
@@ -352,7 +355,7 @@ export class ApiModelGenerator {
private _processAstNamespaceImport(astNamespaceImport: AstNamespaceImport, context: IProcessAstEntityContext): void {
const astModule: AstModule = astNamespaceImport.astModule;
const { name, isExported, parentApiItem } = context;
const { entryPoint, name, isExported, parentApiItem } = context;
const containerKey: string = ApiNamespace.getContainerKey(name);
const sourceLocation: ISourceLocation = this._getSourceLocation(astNamespaceImport.declaration);
@@ -375,6 +378,7 @@ export class ApiModelGenerator {
// eslint-disable-next-line unicorn/no-array-for-each
astModule.astModuleExportInfo!.exportedLocalEntities.forEach((exportedEntity: AstEntity, exportedName: string) => {
this._processAstEntity(exportedEntity, {
entryPoint,
name: exportedName,
isExported: true,
parentApiItem: apiNamespace!,
@@ -533,7 +537,7 @@ export class ApiModelGenerator {
}
private _processApiCallSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { parentApiItem } = context;
const { entryPoint, parentApiItem } = context;
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
const containerKey: string = ApiCallSignature.getContainerKey(overloadIndex);
@@ -556,7 +560,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, callSignature.parameters);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = apiItemMetadata.tsdocComment;
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
@@ -580,7 +584,7 @@ export class ApiModelGenerator {
}
private _processApiConstructor(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { parentApiItem } = context;
const { entryPoint, parentApiItem } = context;
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
const containerKey: string = ApiConstructor.getContainerKey(overloadIndex);
@@ -597,7 +601,7 @@ export class ApiModelGenerator {
constructorDeclaration.parameters,
);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = parent?.construct
? this._tsDocParser.parseString(
@@ -629,7 +633,7 @@ export class ApiModelGenerator {
}
private _processApiClass(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { name, isExported, parentApiItem } = context;
const { entryPoint, name, isExported, parentApiItem } = context;
const containerKey: string = ApiClass.getContainerKey(name);
let apiClass: ApiClass | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiClass;
@@ -683,7 +687,7 @@ export class ApiModelGenerator {
}
}
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
@@ -732,7 +736,7 @@ export class ApiModelGenerator {
}
private _processApiConstructSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { parentApiItem } = context;
const { entryPoint, parentApiItem } = context;
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
const containerKey: string = ApiConstructSignature.getContainerKey(overloadIndex);
@@ -757,7 +761,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, constructSignature.parameters);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = parent?.construct
? this._tsDocParser.parseString(
@@ -789,13 +793,13 @@ export class ApiModelGenerator {
}
private _processApiEnum(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { name, isExported, parentApiItem } = context;
const { entryPoint, name, isExported, parentApiItem } = context;
const containerKey: string = ApiEnum.getContainerKey(name);
let apiEnum: ApiEnum | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiEnum;
if (apiEnum === undefined) {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, []);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, [], entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = apiItemMetadata.tsdocComment;
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
@@ -823,7 +827,7 @@ export class ApiModelGenerator {
}
private _processApiEnumMember(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { name, parentApiItem } = context;
const { entryPoint, name, parentApiItem } = context;
const containerKey: string = ApiEnumMember.getContainerKey(name);
let apiEnumMember: ApiEnumMember | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiEnumMember;
@@ -839,7 +843,7 @@ export class ApiModelGenerator {
nodesToCapture.push({ node: enumMember.initializer, tokenRange: initializerTokenRange });
}
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = apiItemMetadata.tsdocComment;
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
@@ -865,7 +869,7 @@ export class ApiModelGenerator {
context: IProcessAstEntityContext,
altFunctionDeclaration?: ts.FunctionDeclaration,
): void {
const { name, isExported, parentApiItem } = context;
const { entryPoint, name, isExported, parentApiItem } = context;
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
const containerKey: string = ApiFunction.getContainerKey(name, overloadIndex);
@@ -894,7 +898,7 @@ export class ApiModelGenerator {
jsDoc?.params,
);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
@@ -938,7 +942,7 @@ export class ApiModelGenerator {
}
private _processApiIndexSignature(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { parentApiItem } = context;
const { entryPoint, parentApiItem } = context;
const overloadIndex: number = this._collector.getOverloadIndex(astDeclaration);
const containerKey: string = ApiIndexSignature.getContainerKey(overloadIndex);
@@ -956,7 +960,7 @@ export class ApiModelGenerator {
const parameters: IApiParameterOptions[] = this._captureParameters(nodesToCapture, indexSignature.parameters);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = apiItemMetadata.tsdocComment;
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
@@ -981,7 +985,7 @@ export class ApiModelGenerator {
}
private _processApiInterface(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { name, isExported, parentApiItem } = context;
const { entryPoint, name, isExported, parentApiItem } = context;
const containerKey: string = ApiInterface.getContainerKey(name);
let apiInterface: ApiInterface | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiInterface;
@@ -1022,7 +1026,7 @@ export class ApiModelGenerator {
}
}
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
@@ -1064,7 +1068,7 @@ export class ApiModelGenerator {
}
private _processApiMethod(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
const { name, parentApiItem } = context;
const { entryPoint, name, parentApiItem } = context;
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | undefined;
const jsDoc = parent?.methods?.find((method) => method.name === name);
const isStatic: boolean = astDeclaration
@@ -1095,7 +1099,7 @@ export class ApiModelGenerator {
jsDoc?.params,
);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
@@ -1163,7 +1167,7 @@ export class ApiModelGenerator {
}
private _processApiMethodSignature(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
const { name, parentApiItem } = context;
const { entryPoint, name, parentApiItem } = context;
const overloadIndex: number = astDeclaration ? this._collector.getOverloadIndex(astDeclaration) : 1;
const containerKey: string = ApiMethodSignature.getContainerKey(name, overloadIndex);
@@ -1193,7 +1197,7 @@ export class ApiModelGenerator {
jsDoc?.params,
);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
@@ -1241,13 +1245,13 @@ export class ApiModelGenerator {
}
private _processApiNamespace(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { name, isExported, parentApiItem } = context;
const { entryPoint, name, isExported, parentApiItem } = context;
const containerKey: string = ApiNamespace.getContainerKey(name);
let apiNamespace: ApiNamespace | undefined = parentApiItem.tryGetMemberByKey(containerKey) as ApiNamespace;
if (apiNamespace === undefined) {
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, []);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, [], entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = apiItemMetadata.tsdocComment;
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
@@ -1273,7 +1277,7 @@ export class ApiModelGenerator {
}
private _processApiProperty(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
const { name, parentApiItem } = context;
const { entryPoint, name, parentApiItem } = context;
const parent = context.parentDocgenJson as DocgenClassJson | DocgenInterfaceJson | DocgenTypedefJson | undefined;
const jsDoc = parent?.props?.find((prop) => prop.name === name);
const isStatic: boolean = astDeclaration
@@ -1314,7 +1318,7 @@ export class ApiModelGenerator {
nodesToCapture.push({ node: declaration.initializer, tokenRange: initializerTokenRange });
}
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
@@ -1371,7 +1375,7 @@ export class ApiModelGenerator {
}
private _processApiPropertySignature(astDeclaration: AstDeclaration | null, context: IProcessAstEntityContext): void {
const { name, parentApiItem } = context;
const { entryPoint, name, parentApiItem } = context;
const containerKey: string = ApiPropertySignature.getContainerKey(name);
let apiPropertySignature: ApiPropertySignature | undefined = parentApiItem.tryGetMemberByKey(
@@ -1392,7 +1396,7 @@ export class ApiModelGenerator {
const propertyTypeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
nodesToCapture.push({ node: propertySignature.type, tokenRange: propertyTypeTokenRange });
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
@@ -1440,7 +1444,7 @@ export class ApiModelGenerator {
}
private _processApiTypeAlias(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { name, isExported, parentApiItem } = context;
const { entryPoint, name, isExported, parentApiItem } = context;
const containerKey: string = ApiTypeAlias.getContainerKey(name);
@@ -1464,7 +1468,7 @@ export class ApiModelGenerator {
const typeTokenRange: IExcerptTokenRange = ExcerptBuilder.createEmptyTokenRange();
nodesToCapture.push({ node: typeAliasDeclaration.type, tokenRange: typeTokenRange });
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
@@ -1506,7 +1510,7 @@ export class ApiModelGenerator {
}
private _processApiVariable(astDeclaration: AstDeclaration, context: IProcessAstEntityContext): void {
const { name, isExported, parentApiItem } = context;
const { entryPoint, name, isExported, parentApiItem } = context;
const containerKey: string = ApiVariable.getContainerKey(name);
@@ -1526,7 +1530,7 @@ export class ApiModelGenerator {
nodesToCapture.push({ node: variableDeclaration.initializer, tokenRange: initializerTokenRange });
}
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture);
const excerptTokens: IExcerptToken[] = this._buildExcerptTokens(astDeclaration, nodesToCapture, entryPoint);
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = apiItemMetadata.tsdocComment;
const releaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;
@@ -1652,18 +1656,25 @@ export class ApiModelGenerator {
private _buildExcerptTokens(
astDeclaration: AstDeclaration,
nodesToCapture: IExcerptBuilderNodeToCapture[],
entryPoint: IWorkingPackageEntryPoint,
): IExcerptToken[] {
const excerptTokens: IExcerptToken[] = [];
// Build the main declaration
ExcerptBuilder.addDeclaration(excerptTokens, astDeclaration, nodesToCapture, this._referenceGenerator);
ExcerptBuilder.addDeclaration(excerptTokens, astDeclaration, nodesToCapture, this._referenceGenerator, entryPoint);
const declarationMetadata: DeclarationMetadata = this._collector.fetchDeclarationMetadata(astDeclaration);
// Add any ancillary declarations
for (const ancillaryDeclaration of declarationMetadata.ancillaryDeclarations) {
ExcerptBuilder.addBlankLine(excerptTokens);
ExcerptBuilder.addDeclaration(excerptTokens, ancillaryDeclaration, nodesToCapture, this._referenceGenerator);
ExcerptBuilder.addDeclaration(
excerptTokens,
ancillaryDeclaration,
nodesToCapture,
this._referenceGenerator,
entryPoint,
);
}
return excerptTokens;

View File

@@ -15,6 +15,7 @@ import { TypeScriptHelpers } from '../analyzer/TypeScriptHelpers.js';
import { TypeScriptInternals } from '../analyzer/TypeScriptInternals.js';
import type { Collector } from '../collector/Collector.js';
import type { CollectorEntity } from '../collector/CollectorEntity.js';
import type { IWorkingPackageEntryPoint } from '../collector/WorkingPackage.js';
export class DeclarationReferenceGenerator {
public static readonly unknownReference: string = '?';
@@ -28,14 +29,25 @@ export class DeclarationReferenceGenerator {
/**
* Gets the UID for a TypeScript Identifier that references a type.
*/
public getDeclarationReferenceForIdentifier(node: ts.Identifier): DeclarationReference | undefined {
public getDeclarationReferenceForIdentifier(
node: ts.Identifier,
entryPoint: IWorkingPackageEntryPoint,
): DeclarationReference | undefined {
const symbol: ts.Symbol | undefined = this._collector.typeChecker.getSymbolAtLocation(node);
if (symbol !== undefined) {
const isExpression: boolean = DeclarationReferenceGenerator._isInExpressionContext(node);
return (
this.getDeclarationReferenceForSymbol(symbol, isExpression ? ts.SymbolFlags.Value : ts.SymbolFlags.Type) ??
this.getDeclarationReferenceForSymbol(symbol, isExpression ? ts.SymbolFlags.Type : ts.SymbolFlags.Value) ??
this.getDeclarationReferenceForSymbol(symbol, ts.SymbolFlags.Namespace)
this.getDeclarationReferenceForSymbol(
symbol,
isExpression ? ts.SymbolFlags.Value : ts.SymbolFlags.Type,
entryPoint,
) ??
this.getDeclarationReferenceForSymbol(
symbol,
isExpression ? ts.SymbolFlags.Type : ts.SymbolFlags.Value,
entryPoint,
) ??
this.getDeclarationReferenceForSymbol(symbol, ts.SymbolFlags.Namespace, entryPoint)
);
}
@@ -48,8 +60,9 @@ export class DeclarationReferenceGenerator {
public getDeclarationReferenceForSymbol(
symbol: ts.Symbol,
meaning: ts.SymbolFlags,
entryPoint: IWorkingPackageEntryPoint,
): DeclarationReference | undefined {
return this._symbolToDeclarationReference(symbol, meaning, /* includeModuleSymbols*/ false);
return this._symbolToDeclarationReference(symbol, meaning, /* includeModuleSymbols*/ false, entryPoint);
}
private static _isInExpressionContext(node: ts.Node): boolean {
@@ -197,6 +210,7 @@ export class DeclarationReferenceGenerator {
symbol: ts.Symbol,
meaning: ts.SymbolFlags,
includeModuleSymbols: boolean,
entryPoint: IWorkingPackageEntryPoint,
): DeclarationReference | undefined {
const declaration: ts.Node | undefined = TypeScriptHelpers.tryGetADeclaration(symbol);
const sourceFile: ts.SourceFile | undefined = declaration?.getSourceFile();
@@ -221,7 +235,7 @@ export class DeclarationReferenceGenerator {
return undefined;
}
return new DeclarationReference(this._sourceFileToModuleSource(sourceFile));
return new DeclarationReference(this._sourceFileToModuleSource(sourceFile, entryPoint));
}
// Do not generate a declaration reference for a type parameter.
@@ -229,7 +243,7 @@ export class DeclarationReferenceGenerator {
return undefined;
}
let parentRef: DeclarationReference | undefined = this._getParentReference(followedSymbol);
let parentRef: DeclarationReference | undefined = this._getParentReference(followedSymbol, entryPoint);
if (!parentRef) {
return undefined;
}
@@ -276,7 +290,10 @@ export class DeclarationReferenceGenerator {
.withMeaning(DeclarationReferenceGenerator._getMeaningOfSymbol(followedSymbol, meaning) as any);
}
private _getParentReference(symbol: ts.Symbol): DeclarationReference | undefined {
private _getParentReference(
symbol: ts.Symbol,
entryPoint: IWorkingPackageEntryPoint,
): DeclarationReference | undefined {
const declaration: ts.Node | undefined = TypeScriptHelpers.tryGetADeclaration(symbol);
const sourceFile: ts.SourceFile | undefined = declaration?.getSourceFile();
@@ -286,7 +303,7 @@ export class DeclarationReferenceGenerator {
const entity: CollectorEntity | undefined = this._collector.tryGetEntityForSymbol(symbol);
if (entity) {
if (entity.exportedFromEntryPoint) {
return new DeclarationReference(this._sourceFileToModuleSource(sourceFile));
return new DeclarationReference(this._sourceFileToModuleSource(sourceFile, entryPoint));
}
const firstExportingConsumableParent: CollectorEntity | undefined = entity.getFirstExportingConsumableParent();
@@ -296,7 +313,12 @@ export class DeclarationReferenceGenerator {
this._collector.typeChecker,
);
if (parentSymbol) {
return this._symbolToDeclarationReference(parentSymbol, parentSymbol.flags, /* includeModuleSymbols*/ true);
return this._symbolToDeclarationReference(
parentSymbol,
parentSymbol.flags,
/* includeModuleSymbols*/ true,
entryPoint,
);
}
}
}
@@ -304,7 +326,12 @@ export class DeclarationReferenceGenerator {
// Next, try to find a parent symbol via the symbol tree.
const parentSymbol: ts.Symbol | undefined = TypeScriptInternals.getSymbolParent(symbol);
if (parentSymbol) {
return this._symbolToDeclarationReference(parentSymbol, parentSymbol.flags, /* includeModuleSymbols*/ true);
return this._symbolToDeclarationReference(
parentSymbol,
parentSymbol.flags,
/* includeModuleSymbols*/ true,
entryPoint,
);
}
// If that doesn't work, try to find a parent symbol via the node tree. As far as we can tell,
@@ -330,20 +357,22 @@ export class DeclarationReferenceGenerator {
grandParentSymbol,
grandParentSymbol.flags,
/* includeModuleSymbols*/ true,
entryPoint,
);
}
}
// At this point, we have a local symbol in a module.
if (sourceFile && ts.isExternalModule(sourceFile)) {
return new DeclarationReference(this._sourceFileToModuleSource(sourceFile));
return new DeclarationReference(this._sourceFileToModuleSource(sourceFile, entryPoint));
} else {
return new DeclarationReference(GlobalSource.instance);
}
}
private _getEntryPointName(sourceFile: ts.SourceFile): string {
private _getEntryPointName(sourceFile: ts.SourceFile, entry: IWorkingPackageEntryPoint): string {
if (this._collector.program.isSourceFileFromExternalLibrary(sourceFile)) {
console.log(sourceFile.fileName, 'is external!');
const packageJson: INodePackageJson | undefined = this._collector.packageJsonLookup.tryLoadNodePackageJsonFor(
sourceFile.fileName,
);
@@ -365,19 +394,17 @@ export class DeclarationReferenceGenerator {
return DeclarationReferenceGenerator.unknownReference;
}
let modulePath = '';
for (const entryPoint of this._collector.workingPackage.entryPoints) {
if (entryPoint.sourceFile === sourceFile) {
modulePath = entryPoint.modulePath;
}
}
const modulePath = entry.modulePath;
return `${this._collector.workingPackage.name}${modulePath ? `/${modulePath}` : ''}`;
}
private _sourceFileToModuleSource(sourceFile: ts.SourceFile | undefined): GlobalSource | ModuleSource {
private _sourceFileToModuleSource(
sourceFile: ts.SourceFile | undefined,
entryPoint: IWorkingPackageEntryPoint,
): GlobalSource | ModuleSource {
if (sourceFile && ts.isExternalModule(sourceFile)) {
const packageName: string = this._getEntryPointName(sourceFile);
const packageName: string = this._getEntryPointName(sourceFile, entryPoint);
if (this._collector.bundledPackageNames.has(packageName)) {
// The api-extractor.json config file has a "bundledPackages" setting, which causes imports from

View File

@@ -11,6 +11,7 @@ import type { DeclarationReference } from '@microsoft/tsdoc/lib-commonjs/beta/De
import * as ts from 'typescript';
import type { AstDeclaration } from '../analyzer/AstDeclaration.js';
import { Span } from '../analyzer/Span.js';
import type { IWorkingPackageEntryPoint } from '../collector/WorkingPackage.js';
import type { DeclarationReferenceGenerator } from './DeclarationReferenceGenerator.js';
/**
@@ -32,6 +33,8 @@ export interface IExcerptBuilderNodeToCapture {
* Internal state for ExcerptBuilder
*/
interface IBuildSpanState {
entryPoint: IWorkingPackageEntryPoint;
/**
* Tracks whether the last appended token was a separator. If so, and we're in the middle of
* capturing a token range, then omit the separator from the range.
@@ -90,6 +93,7 @@ export class ExcerptBuilder {
astDeclaration: AstDeclaration,
nodesToCapture: IExcerptBuilderNodeToCapture[],
referenceGenerator: DeclarationReferenceGenerator,
entryPoint: IWorkingPackageEntryPoint,
): void {
let stopBeforeChildKind: ts.SyntaxKind | undefined;
@@ -118,6 +122,7 @@ export class ExcerptBuilder {
}
ExcerptBuilder._buildSpan(excerptTokens, span, {
entryPoint,
referenceGenerator,
startingNode: span.node,
stopBeforeChildKind,
@@ -185,7 +190,7 @@ export class ExcerptBuilder {
if (ts.isIdentifier(span.node)) {
const name: ts.Identifier = span.node;
canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name);
canonicalReference = state.referenceGenerator.getDeclarationReferenceForIdentifier(name, state.entryPoint);
}
if (canonicalReference) {