From 5d6eef206d4c842a47818d7b72c332d018f50e31 Mon Sep 17 00:00:00 2001 From: Kamil Sobol Date: Wed, 28 Aug 2024 07:27:17 -0700 Subject: [PATCH] Handle aliased symbols in namespaces in api check (#1926) * handle aliased symbols in namespaces * handle aliased symbols in namespaces * Update scripts/components/api-changes-validator/api_usage_generator.ts Co-authored-by: Amplifiyer <51211245+Amplifiyer@users.noreply.github.com> --------- Co-authored-by: Amplifiyer <51211245+Amplifiyer@users.noreply.github.com> --- .../api_usage_generator.ts | 18 ++++++++++++++++-- .../project-with-namespace/API.md | 10 ++++++++++ .../project-with-namespace/src/index.ts | 3 ++- .../src/some_namespace.ts | 7 ++----- .../src/some_namespace_with_same_type.ts | 3 +++ .../project-with-namespace/src/types.ts | 3 +++ .../components/api-changes-validator/types.ts | 1 + .../usage_statemets_renderer.ts | 8 +++++++- 8 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/some_namespace_with_same_type.ts create mode 100644 scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/types.ts diff --git a/scripts/components/api-changes-validator/api_usage_generator.ts b/scripts/components/api-changes-validator/api_usage_generator.ts index 52944b7b26..3e69d7c7bf 100644 --- a/scripts/components/api-changes-validator/api_usage_generator.ts +++ b/scripts/components/api-changes-validator/api_usage_generator.ts @@ -99,6 +99,7 @@ export class ApiUsageGenerator { namespaceBySymbol: new Map(), namespaceNames: new Set(), topLevelNamespaces: new Set(), + aliasedSymbols: new Map(), }; for (const statement of this.apiReportAST.statements) { if (statement.kind === ts.SyntaxKind.ModuleDeclaration) { @@ -118,9 +119,22 @@ export class ApiUsageGenerator { const namedExports = exportDeclaration.exportClause as ts.NamedExports; for (const namedExport of namedExports.elements) { - const symbolName = namedExport.name.getText(); + let symbolNameInApiView: string; + if (namedExport.propertyName) { + // If property name is present this means that + // API Extractor aliased type definition to avoid duplicate + // and exported from namespace as 'SomeType_2 as SomeType' + symbolNameInApiView = namedExport.propertyName.getText(); + const exportedSymbolName = namedExport.name.getText(); + namespaceDefinitions.aliasedSymbols.set( + symbolNameInApiView, + exportedSymbolName + ); + } else { + symbolNameInApiView = namedExport.name.getText(); + } namespaceDefinitions.namespaceBySymbol.set( - symbolName, + symbolNameInApiView, namespaceName ); } diff --git a/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/API.md b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/API.md index 8ab474ee15..d5abda803d 100644 --- a/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/API.md +++ b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/API.md @@ -4,6 +4,10 @@ export type SomeTypeUnderNamespace = { someProperty: string; } +export type SomeTypeUnderNamespace_2 = { + someProperty: string; +} + type SomeTypeUnderSubNamespace = { someOtherProperty: string; } @@ -26,6 +30,12 @@ declare namespace someNamespace { } } +declare namespace someNamespaceWithSameType { + export { + SomeTypeUnderNamespace_2 as SomeTypeUnderNamespace, + } +} + type SomeTypeUnderOtherEntryPoint = { somePropertyUnderOtherEntryPoint: string; } diff --git a/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/index.ts b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/index.ts index cccb359bb1..e9ec0830e7 100644 --- a/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/index.ts +++ b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/index.ts @@ -1,3 +1,4 @@ import * as someNamespace from './some_namespace.js'; +import * as someNamespaceWithSameType from './some_namespace_with_same_type.js'; -export { someNamespace }; +export { someNamespace, someNamespaceWithSameType }; diff --git a/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/some_namespace.ts b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/some_namespace.ts index 7de91cf9ac..24be0c1e89 100644 --- a/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/some_namespace.ts +++ b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/some_namespace.ts @@ -1,10 +1,7 @@ import * as someSubNamespace from './some_sub_namespace.js'; +import { SomeTypeUnderNamespace } from './types.js'; -export type SomeTypeUnderNamespace = { - someProperty: string; -}; - -export { someSubNamespace }; +export { someSubNamespace, SomeTypeUnderNamespace }; export const functionUsingTypes1 = ( props: SomeTypeUnderNamespace diff --git a/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/some_namespace_with_same_type.ts b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/some_namespace_with_same_type.ts new file mode 100644 index 0000000000..4b60ba1ee3 --- /dev/null +++ b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/some_namespace_with_same_type.ts @@ -0,0 +1,3 @@ +import { SomeTypeUnderNamespace } from './types.js'; + +export { SomeTypeUnderNamespace }; diff --git a/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/types.ts b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/types.ts new file mode 100644 index 0000000000..ccba36375a --- /dev/null +++ b/scripts/components/api-changes-validator/test-resources/test-projects/without-breaks/project-with-namespace/src/types.ts @@ -0,0 +1,3 @@ +export type SomeTypeUnderNamespace = { + someProperty: string; +}; diff --git a/scripts/components/api-changes-validator/types.ts b/scripts/components/api-changes-validator/types.ts index b62a0bf052..f18ac08a6a 100644 --- a/scripts/components/api-changes-validator/types.ts +++ b/scripts/components/api-changes-validator/types.ts @@ -25,4 +25,5 @@ export type NamespaceDefinitions = { topLevelNamespaces: Set; namespaceNames: Set; namespaceBySymbol: Map; + aliasedSymbols: Map; }; diff --git a/scripts/components/api-changes-validator/usage_statemets_renderer.ts b/scripts/components/api-changes-validator/usage_statemets_renderer.ts index 5f769fce09..66e3365c66 100644 --- a/scripts/components/api-changes-validator/usage_statemets_renderer.ts +++ b/scripts/components/api-changes-validator/usage_statemets_renderer.ts @@ -57,9 +57,15 @@ export class UsageStatementsRenderer { namespaceHierarchy.unshift(currentSymbolName); } } while (currentSymbolName); + const symbolAlias = + this.namespaceDefinitions.aliasedSymbols.get(symbolName); + let actualSymbolName = symbolName; + if (symbolAlias) { + actualSymbolName = symbolAlias; + } const symbolWithNamespace = `${namespaceHierarchy.join( '.' - )}.${symbolName}`; + )}.${actualSymbolName}`; // characters that can be found before or after symbol // this is to prevent partial matches in case one symbol's characters are subset of longer one