Skip to content

[api-extractor] Add support for export namespace syntax #4698

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 55 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
7d0fb05
Add support to export namespace syntax
nirshar May 12, 2024
7776ce8
commit api.md and api.jsons for test cases
nirshar May 12, 2024
b9b2446
commit rush change created files
nirshar May 12, 2024
6043938
add header and type to AstNamespaceExport
nirshar May 12, 2024
8404d9c
Remove PerformValidation step from publishing pipelines; this step ha…
octogonz May 8, 2024
86ad170
Fix spelling error
octogonz May 8, 2024
ce52299
rush change
octogonz May 8, 2024
fc9d4d4
Improve pnpm-sync error message formatting and fix an issue where err…
octogonz May 8, 2024
58f524d
Fix a bug where OperationExecutionManager was incorrectly printing th…
octogonz May 8, 2024
4aa5b50
waiting for long periods of time causes GC build up
aramissennyeydd May 8, 2024
206881a
add changeset
aramissennyeydd May 8, 2024
5154bd7
fix: a issue where rush install/update when pnpm-sync version changes
g-chao May 8, 2024
6a0efe8
chore: rush change
g-chao May 8, 2024
2458192
Update changelogs [skip ci]
rushbot May 8, 2024
4e798e1
Bump versions [skip ci]
rushbot May 8, 2024
df4b144
Update changelogs [skip ci]
rushbot May 8, 2024
fbe9cd3
Bump versions [skip ci]
rushbot May 8, 2024
561bc7c
chore: fix a edge in _disallowInsecureSha1
g-chao May 9, 2024
229edc6
chore: rush change
g-chao May 9, 2024
def25cd
Prepare to publish a PATCH release of Rush
octogonz May 10, 2024
ef73097
fix weighting
aramissennyeydd May 8, 2024
cc7eaf2
adjustments
aramissennyeydd May 8, 2024
90f2dda
fixed the initial implementation
aramissennyeydd May 8, 2024
93c23c8
reentry fix
aramissennyeydd May 8, 2024
b93f98d
cleanup
aramissennyeydd May 8, 2024
545fd61
remove unnecessary test case
aramissennyeydd May 8, 2024
6a318b3
adjust comment
aramissennyeydd May 8, 2024
86815a1
fix cobuilds with operation weighting
aramissennyeydd May 8, 2024
4af268c
add changeset
aramissennyeydd May 8, 2024
287aa0d
Update common/changes/@microsoft/rush/sennyeya-weighted-operation-ree…
iclanton May 10, 2024
35f27e5
Update common/changes/@rushstack/node-core-library/sennyeya-weighted-…
iclanton May 10, 2024
26246b3
fix: fix additionalProjectsToInclude field didn't work in rush deploy
EscapeB May 10, 2024
75fd847
Remove extraneous parameters from FlagFile.ts
octogonz May 10, 2024
6e61df8
Fix some typos encountered while preparing the website docs
octogonz May 10, 2024
0b80ff1
Add "subspaceName" docs to rush.json init template
octogonz May 10, 2024
233fcfd
Show an error message if useWorkspaces=false when trying to use subsp…
octogonz May 10, 2024
10c7b8b
rush change
octogonz May 10, 2024
6c2a4c0
rush change
octogonz May 10, 2024
fe47180
Improve changelog
octogonz May 10, 2024
ffb06f7
Update changelogs [skip ci]
rushbot May 10, 2024
4e5628c
Bump versions [skip ci]
rushbot May 10, 2024
414264a
Update changelogs [skip ci]
rushbot May 10, 2024
5599509
Bump versions [skip ci]
rushbot May 10, 2024
d11a20e
Improve change log
octogonz May 10, 2024
0dde46e
Update changelogs [skip ci]
rushbot May 10, 2024
91a929f
Bump versions [skip ci]
rushbot May 10, 2024
c3df803
Fix #4691.
iclanton May 10, 2024
b6fe630
Update changelogs [skip ci]
rushbot May 11, 2024
867278d
Bump versions [skip ci]
rushbot May 11, 2024
cdc3801
resolve conflicts
nirshar May 13, 2024
a854c5d
remove unused variable
nirshar May 13, 2024
aa32046
Merge branch 'main' into api-extractor-export-namespace-fix
nirshar May 13, 2024
40f3e2a
Merge remote-tracking branch 'remotes/origin/main' into api-extractor…
octogonz Jun 3, 2024
c70a365
Improve change log
octogonz Jun 3, 2024
31e5aff
Revert spurious change
octogonz Jun 3, 2024
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
42 changes: 42 additions & 0 deletions apps/api-extractor/src/analyzer/AstNamespaceExport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import { AstNamespaceImport, type IAstNamespaceImportOptions } from './AstNamespaceImport';

export interface IAstNamespaceExportOptions extends IAstNamespaceImportOptions {}

/**
* `AstNamespaceExport` represents a namespace that is created implicitly and exported by a statement
* such as `export * as example from "./file";`
*
* @remarks
*
* A typical input looks like this:
* ```ts
* // Suppose that example.ts exports two functions f1() and f2().
* export * as example from "./file";
* ```
*
* API Extractor's .d.ts rollup will transform it into an explicit namespace, like this:
* ```ts
* declare f1(): void;
* declare f2(): void;
*
* export declare namespace example {
* export {
* f1,
* f2
* }
* }
* ```
*
* The current implementation does not attempt to relocate f1()/f2() to be inside the `namespace`
* because other type signatures may reference them directly (without using the namespace qualifier).
* The AstNamespaceExports behaves the same as AstNamespaceImport, it just also has the inline export for the craeted namespace.
*/

export class AstNamespaceExport extends AstNamespaceImport {
public constructor(options: IAstNamespaceExportOptions) {
super(options);
}
}
60 changes: 43 additions & 17 deletions apps/api-extractor/src/analyzer/ExportAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { IFetchAstSymbolOptions } from './AstSymbolTable';
import type { AstEntity } from './AstEntity';
import { AstNamespaceImport } from './AstNamespaceImport';
import { SyntaxHelpers } from './SyntaxHelpers';
import { AstNamespaceExport } from './AstNamespaceExport';

/**
* Exposes the minimal APIs from AstSymbolTable that are needed by ExportAnalyzer.
Expand Down Expand Up @@ -562,11 +563,9 @@ export class ExportAnalyzer {
// SemicolonToken: pre=[;]

// Issue tracking this feature: https://github.com/microsoft/rushstack/issues/2780
throw new Error(
`The "export * as ___" syntax is not supported yet; as a workaround,` +
` use "import * as ___" with a separate "export { ___ }" declaration\n` +
SourceFileLocationFormatter.formatDeclaration(declaration)
);

const astModule: AstModule = this._fetchSpecifierAstModule(exportDeclaration, declarationSymbol);
return this._getAstNamespaceExport(astModule, declarationSymbol, declaration);
} else {
throw new InternalError(
`Unimplemented export declaration kind: ${declaration.getText()}\n` +
Expand Down Expand Up @@ -594,6 +593,25 @@ export class ExportAnalyzer {
return undefined;
}

private _getAstNamespaceExport(
astModule: AstModule,
declarationSymbol: ts.Symbol,
declaration: ts.Declaration
): AstNamespaceExport {
const imoprtNamespace: AstNamespaceImport = this._getAstNamespaceImport(
astModule,
declarationSymbol,
declaration
);

return new AstNamespaceExport({
namespaceName: imoprtNamespace.localName,
astModule: astModule,
declaration,
symbol: declarationSymbol
});
}

private _tryMatchImportDeclaration(
declaration: ts.Declaration,
declarationSymbol: ts.Symbol
Expand Down Expand Up @@ -621,18 +639,7 @@ export class ExportAnalyzer {

if (externalModulePath === undefined) {
const astModule: AstModule = this._fetchSpecifierAstModule(importDeclaration, declarationSymbol);
let namespaceImport: AstNamespaceImport | undefined =
this._astNamespaceImportByModule.get(astModule);
if (namespaceImport === undefined) {
namespaceImport = new AstNamespaceImport({
namespaceName: declarationSymbol.name,
astModule: astModule,
declaration: declaration,
symbol: declarationSymbol
});
this._astNamespaceImportByModule.set(astModule, namespaceImport);
}
return namespaceImport;
return this._getAstNamespaceImport(astModule, declarationSymbol, declaration);
}

// Here importSymbol=undefined because {@inheritDoc} and such are not going to work correctly for
Expand Down Expand Up @@ -759,6 +766,25 @@ export class ExportAnalyzer {
return undefined;
}

private _getAstNamespaceImport(
astModule: AstModule,
declarationSymbol: ts.Symbol,
declaration: ts.Declaration
): AstNamespaceImport {
let namespaceImport: AstNamespaceImport | undefined = this._astNamespaceImportByModule.get(astModule);
if (namespaceImport === undefined) {
namespaceImport = new AstNamespaceImport({
namespaceName: declarationSymbol.name,
astModule: astModule,
declaration: declaration,
symbol: declarationSymbol
});
this._astNamespaceImportByModule.set(astModule, namespaceImport);
}

return namespaceImport;
}

private static _getIsTypeOnly(importDeclaration: ts.ImportDeclaration): boolean {
if (importDeclaration.importClause) {
return !!importDeclaration.importClause.isTypeOnly;
Expand Down
6 changes: 6 additions & 0 deletions apps/api-extractor/src/collector/CollectorEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AstSymbol } from '../analyzer/AstSymbol';
import { Collector } from './Collector';
import { Sort } from '@rushstack/node-core-library';
import type { AstEntity } from '../analyzer/AstEntity';
import { AstNamespaceExport } from '../analyzer/AstNamespaceExport';

/**
* This is a data structure used by the Collector to track an AstEntity that may be emitted in the *.d.ts file.
Expand Down Expand Up @@ -82,6 +83,11 @@ export class CollectorEntity {
* such as "export class X { }" instead of "export { X }".
*/
public get shouldInlineExport(): boolean {
// We export the namespace directly
if (this.astEntity instanceof AstNamespaceExport) {
return true;
}

// We don't inline an AstImport
if (this.astEntity instanceof AstSymbol) {
// We don't inline a symbol with more than one exported name
Expand Down
Loading
Loading