Skip to content
15 changes: 1 addition & 14 deletions apps/api-extractor/src/analyzer/AstImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,7 @@ export enum AstImportKind {
/**
* An import statement such as `import x = require("y");`.
*/
EqualsImport,

/**
* An import statement such as `interface foo { foo: import("bar").a.b.c }`.
*/
ImportType
EqualsImport
}

/**
Expand Down Expand Up @@ -150,14 +145,6 @@ export class AstImport extends AstSyntheticEntity {
return `${options.modulePath}:*`;
case AstImportKind.EqualsImport:
return `${options.modulePath}:=`;
case AstImportKind.ImportType: {
const subKey: string = !options.exportName
? '*' // Equivalent to StarImport
: options.exportName.includes('.') // Equivalent to a named export
? options.exportName.split('.')[0]
: options.exportName;
return `${options.modulePath}:${subKey}`;
}
default:
throw new InternalError('Unknown AstImportKind');
}
Expand Down
9 changes: 1 addition & 8 deletions apps/api-extractor/src/analyzer/AstNamespaceImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export interface IAstNamespaceImportOptions {
readonly astModule: AstModule;
readonly namespaceName: string;
readonly declaration: ts.Declaration;
readonly symbol: ts.Symbol;
}

/**
Expand Down Expand Up @@ -64,21 +63,15 @@ export class AstNamespaceImport extends AstSyntheticEntity {
public readonly namespaceName: string;

/**
* The original `ts.SyntaxKind.NamespaceImport` which can be used as a location for error messages.
* The (first) original `ts.SyntaxKind.NamespaceImport` (or `ts.SyntaxKind.SourceFile` if import declaration doesn't exist) which can be used as a location for error messages.
*/
public readonly declaration: ts.Declaration;

/**
* The original `ts.SymbolFlags.Namespace` symbol.
*/
public readonly symbol: ts.Symbol;

public constructor(options: IAstNamespaceImportOptions) {
super();
this.astModule = options.astModule;
this.namespaceName = options.namespaceName;
this.declaration = options.declaration;
this.symbol = options.symbol;
}

/** {@inheritdoc} */
Expand Down
61 changes: 61 additions & 0 deletions apps/api-extractor/src/analyzer/AstSubPathImport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import { InternalError } from '@rushstack/node-core-library';
import { type AstEntity, AstSyntheticEntity } from './AstEntity';

export interface IAstSubPathImportOptions {
readonly astEntity: AstEntity;
readonly exportPath: string[];
}

/**
* `AstSubPathImport` represents a sub-path import, such as `import("foo").X.Y.Z` will import Y.Z from X of "foo".
*
* @remarks
*
* The base AstEntity can be either local or external entity.
*
* ```ts
* // import from AstImport (NamedImport, modulePath="foo", exportName="X"), with exportPath ["Y", "Z"]
* const bar: import("foo").X.Y.Z;
*
* // import from AstImport (DefaultImport, modulePath="foo"), with exportPath ["X", "Y", "Z"]
* const bar: import("foo").default.X.Y.Z;
*
* // import from AstEntity of X, with exportPath ["Y", "Z"]
* const bar: import("./foo").X.Y.Z;
* ```
*/
export class AstSubPathImport extends AstSyntheticEntity {
/**
* The AstEntity that is imported from.
*
* @remarks
*
* The AstEntity can be either local or external entity.
*/
public readonly baseAstEntity: AstEntity;

/**
* The path to the entity within the `baseAstEntity`.
*/
public readonly exportPath: string[];

public constructor(options: IAstSubPathImportOptions) {
super();

if (options.exportPath.length === 0) {
throw new InternalError('AstSubPathImport.exportPath cannot be empty');
}

this.baseAstEntity = options.astEntity;
this.exportPath = options.exportPath;
}

/** {@inheritdoc} */
public get localName(): string {
// abstract
return this.exportPath[this.exportPath.length - 1];
}
}
31 changes: 20 additions & 11 deletions apps/api-extractor/src/analyzer/AstSymbolTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { MessageRouter } from '../collector/MessageRouter';
import { TypeScriptInternals, type IGlobalVariableAnalyzer } from './TypeScriptInternals';
import { SyntaxHelpers } from './SyntaxHelpers';
import { SourceFileLocationFormatter } from './SourceFileLocationFormatter';
import { AstSubPathImport } from './AstSubPathImport';

/**
* Options for `AstSymbolTable._fetchAstSymbol()`
Expand Down Expand Up @@ -318,21 +319,29 @@ export class AstSymbolTable {
// If this symbol is non-external (i.e. it belongs to the working package), then we also analyze any
// referencedAstSymbols that are non-external. For example, this ensures that forgotten exports
// get analyzed.
rootAstSymbol.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {
for (const referencedAstEntity of astDeclaration.referencedAstEntities) {
// Walk up to the root of the tree, looking for any imports along the way
if (referencedAstEntity instanceof AstSymbol) {
if (!referencedAstEntity.isExternal) {
this._analyzeAstSymbol(referencedAstEntity);
}
const analyzeReferencedLocalAstEntity = (referencedAstEntity: AstEntity): void => {
if (referencedAstEntity instanceof AstSymbol) {
if (!referencedAstEntity.isExternal) {
this._analyzeAstSymbol(referencedAstEntity);
}
}

if (referencedAstEntity instanceof AstNamespaceImport) {
if (!referencedAstEntity.astModule.isExternal) {
this._analyzeAstNamespaceImport(referencedAstEntity);
}
if (referencedAstEntity instanceof AstNamespaceImport) {
if (!referencedAstEntity.astModule.isExternal) {
this._analyzeAstNamespaceImport(referencedAstEntity);
}
}

if (referencedAstEntity instanceof AstSubPathImport) {
analyzeReferencedLocalAstEntity(referencedAstEntity.baseAstEntity);
}
};

rootAstSymbol.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {
for (const referencedAstEntity of astDeclaration.referencedAstEntities) {
// Walk up to the root of the tree, looking for any imports along the way
analyzeReferencedLocalAstEntity(referencedAstEntity);
}
});
}
}
Expand Down
Loading
Loading