@microsoft/api-extractor 7.29.5 → 7.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/rollup.d.ts +26 -2
  2. package/lib/api/ExtractorConfig.d.ts +4 -0
  3. package/lib/api/ExtractorConfig.d.ts.map +1 -1
  4. package/lib/api/ExtractorConfig.js +8 -0
  5. package/lib/api/ExtractorConfig.js.map +1 -1
  6. package/lib/api/ExtractorMessageId.d.ts +1 -1
  7. package/lib/api/ExtractorMessageId.js.map +1 -1
  8. package/lib/api/IConfigFile.d.ts +21 -1
  9. package/lib/api/IConfigFile.d.ts.map +1 -1
  10. package/lib/api/IConfigFile.js.map +1 -1
  11. package/lib/collector/Collector.d.ts +1 -1
  12. package/lib/collector/Collector.d.ts.map +1 -1
  13. package/lib/collector/Collector.js +43 -32
  14. package/lib/collector/Collector.js.map +1 -1
  15. package/lib/collector/CollectorEntity.d.ts +70 -28
  16. package/lib/collector/CollectorEntity.d.ts.map +1 -1
  17. package/lib/collector/CollectorEntity.js +95 -30
  18. package/lib/collector/CollectorEntity.js.map +1 -1
  19. package/lib/enhancers/DocCommentEnhancer.d.ts.map +1 -1
  20. package/lib/enhancers/DocCommentEnhancer.js +3 -1
  21. package/lib/enhancers/DocCommentEnhancer.js.map +1 -1
  22. package/lib/enhancers/ValidationEnhancer.d.ts.map +1 -1
  23. package/lib/enhancers/ValidationEnhancer.js +7 -5
  24. package/lib/enhancers/ValidationEnhancer.js.map +1 -1
  25. package/lib/generators/ApiModelGenerator.d.ts +2 -1
  26. package/lib/generators/ApiModelGenerator.d.ts.map +1 -1
  27. package/lib/generators/ApiModelGenerator.js +41 -17
  28. package/lib/generators/ApiModelGenerator.js.map +1 -1
  29. package/lib/generators/ApiReportGenerator.js +2 -2
  30. package/lib/generators/ApiReportGenerator.js.map +1 -1
  31. package/lib/generators/DeclarationReferenceGenerator.d.ts +4 -8
  32. package/lib/generators/DeclarationReferenceGenerator.d.ts.map +1 -1
  33. package/lib/generators/DeclarationReferenceGenerator.js +50 -67
  34. package/lib/generators/DeclarationReferenceGenerator.js.map +1 -1
  35. package/lib/schemas/api-extractor-defaults.json +4 -2
  36. package/lib/schemas/api-extractor-template.json +24 -5
  37. package/lib/schemas/api-extractor.schema.json +11 -1
  38. package/package.json +3 -4
@@ -1,5 +1,4 @@
1
1
  import { AstEntity } from '../analyzer/AstEntity';
2
- import { AstNamespaceImport } from '../analyzer/AstNamespaceImport';
3
2
  /**
4
3
  * This is a data structure used by the Collector to track an AstEntity that may be emitted in the *.d.ts file.
5
4
  *
@@ -17,19 +16,19 @@ export declare class CollectorEntity {
17
16
  private _exportNames;
18
17
  private _exportNamesSorted;
19
18
  private _singleExportName;
19
+ private _localExportNamesByParent;
20
20
  private _nameForEmit;
21
21
  private _sortKey;
22
- private _astNamespaceImports;
23
22
  constructor(astEntity: AstEntity);
24
23
  /**
25
- * The declaration name that will be emitted in a .d.ts rollup. For non-exported declarations,
26
- * Collector._makeUniqueNames() may need to rename the declaration to avoid conflicts with other declarations
27
- * in that module.
24
+ * The declaration name that will be emitted in the .d.ts rollup, .api.md, and .api.json files. Generated by
25
+ * `Collector._makeUniqueNames`. Be aware that the declaration may be renamed to avoid conflicts with (1)
26
+ * global names (e.g. `Promise`) and (2) if local, other local names across different files.
28
27
  */
29
28
  get nameForEmit(): string | undefined;
30
29
  set nameForEmit(value: string | undefined);
31
30
  /**
32
- * If this symbol is exported from the entry point, the list of export names.
31
+ * The list of export names if this symbol is exported from the entry point.
33
32
  *
34
33
  * @remarks
35
34
  * Note that a given symbol may be exported more than once:
@@ -51,49 +50,92 @@ export declare class CollectorEntity {
51
50
  */
52
51
  get shouldInlineExport(): boolean;
53
52
  /**
54
- * Returns true if this symbol is an export for the entry point being analyzed.
53
+ * Indicates that this entity is exported from its parent module (i.e. either the package entry point or
54
+ * a local namespace). Compare to `CollectorEntity.consumable`.
55
+ *
56
+ * @remarks
57
+ * In the example below:
58
+ *
59
+ * ```ts
60
+ * declare function add(): void;
61
+ * declare namespace calculator {
62
+ * export {
63
+ * add
64
+ * }
65
+ * }
66
+ * ```
67
+ *
68
+ * Namespace `calculator` is neither exported nor consumable, function `add` is exported (from `calculator`)
69
+ * but not consumable.
55
70
  */
56
71
  get exported(): boolean;
57
72
  /**
58
- * Indicates that it is possible for a consumer of the API to access this declaration, either by importing
59
- * it directly, or via some other alias such as a member of a namespace. If a collector entity is not consumable,
60
- * then API Extractor will report a ExtractorMessageId.ForgottenExport warning.
73
+ * Indicates that it is possible for a consumer of the API to "consume" this entity, either by importing
74
+ * it directly or via a namespace. If an entity is not consumable, then API Extractor will report an
75
+ * `ae-forgotten-export` warning. Compare to `CollectorEntity.exported`.
61
76
  *
62
77
  * @remarks
63
- * Generally speaking, an API item is consumable if:
78
+ * An API item is consumable if:
64
79
  *
65
- * - The collector encounters it while crawling the entry point, and it is a root symbol
66
- * (i.e. there is a corresponding a CollectorEntity)
80
+ * 1. It is exported from the top-level entry point OR
81
+ * 2. It is exported from a consumable parent entity.
67
82
  *
68
- * - AND it is exported by the entry point
69
- *
70
- * However a special case occurs with `AstNamespaceImport` which produces a rollup like this:
83
+ * For an example of #2, consider how `AstNamespaceImport` entities are processed. A generated rollup.d.ts
84
+ * might look like this:
71
85
  *
72
86
  * ```ts
73
- * declare interface IForgottenExport { }
74
- *
75
- * declare function member(): IForgottenExport;
76
- *
77
- * declare namespace ns {
87
+ * declare function add(): void;
88
+ * declare namespace calculator {
78
89
  * export {
79
- * member
90
+ * add
80
91
  * }
81
92
  * }
82
- * export { ns }
93
+ * export { calculator }
83
94
  * ```
84
95
  *
85
- * In this example, `IForgottenExport` is not consumable. Whereas `member()` is consumable as `ns.member()`
86
- * even though `member()` itself is not exported.
96
+ * In this example, `add` is exported via the consumable `calculator` namespace.
87
97
  */
88
98
  get consumable(): boolean;
89
99
  /**
90
- * Associates this entity with a `AstNamespaceImport`.
100
+ * Whether the entity has any parent entities.
101
+ *
102
+ * @remarks
103
+ * In the example below:
104
+ *
105
+ * ```ts
106
+ * declare function add(): void;
107
+ * declare namespace calculator {
108
+ * export {
109
+ * add
110
+ * }
111
+ * }
112
+ * ```
113
+ *
114
+ * The `CollectorEntity` for `calculator` is the parent of the `CollectorEntity` for `add`.
91
115
  */
92
- addAstNamespaceImports(astNamespaceImport: AstNamespaceImport): void;
116
+ get hasParents(): boolean;
93
117
  /**
94
- * Adds a new exportName to the exportNames set.
118
+ * Adds a new export name to the entity.
95
119
  */
96
120
  addExportName(exportName: string): void;
121
+ /**
122
+ * Adds a new local export name to the entity.
123
+ *
124
+ * @remarks
125
+ * In the example below:
126
+ *
127
+ * ```ts
128
+ * declare function add(): void;
129
+ * declare namespace calculator {
130
+ * export {
131
+ * add
132
+ * }
133
+ * }
134
+ * ```
135
+ *
136
+ * `add` is the local export name for the `CollectorEntity` for `add`.
137
+ */
138
+ addLocalExportName(localExportName: string, parent: CollectorEntity): void;
97
139
  /**
98
140
  * A sorting key used by DtsRollupGenerator._makeUniqueNames()
99
141
  */
@@ -1 +1 @@
1
- {"version":3,"file":"CollectorEntity.d.ts","sourceRoot":"","sources":["../../src/collector/CollectorEntity.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,SAAgB,SAAS,EAAE,SAAS,CAAC;IAErC,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,iBAAiB,CAAiC;IAE1D,OAAO,CAAC,YAAY,CAAiC;IAErD,OAAO,CAAC,QAAQ,CAAiC;IAEjD,OAAO,CAAC,oBAAoB,CAAsC;gBAE/C,SAAS,EAAE,SAAS;IAIvC;;;;OAIG;IACH,IAAW,WAAW,IAAI,MAAM,GAAG,SAAS,CAE3C;IAED,IAAW,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAG/C;IAED;;;;;;;;;;OAUG;IACH,IAAW,WAAW,IAAI,WAAW,CAAC,MAAM,CAAC,CAM5C;IAED;;;OAGG;IACH,IAAW,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAEhD;IAED;;;OAGG;IACH,IAAW,kBAAkB,IAAI,OAAO,CAYvC;IAED;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED;;OAEG;IACI,sBAAsB,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI;IAI3E;;OAEG;IACI,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAa9C;;OAEG;IACI,UAAU,IAAI,MAAM;CAM5B"}
1
+ {"version":3,"file":"CollectorEntity.d.ts","sourceRoot":"","sources":["../../src/collector/CollectorEntity.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACH,SAAgB,SAAS,EAAE,SAAS,CAAC;IAErC,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,yBAAyB,CAAgD;IAEjF,OAAO,CAAC,YAAY,CAAiC;IAErD,OAAO,CAAC,QAAQ,CAAiC;gBAE9B,SAAS,EAAE,SAAS;IAIvC;;;;OAIG;IACH,IAAW,WAAW,IAAI,MAAM,GAAG,SAAS,CAE3C;IAED,IAAW,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAG/C;IAED;;;;;;;;;;OAUG;IACH,IAAW,WAAW,IAAI,WAAW,CAAC,MAAM,CAAC,CAM5C;IAED;;;OAGG;IACH,IAAW,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAEhD;IAED;;;OAGG;IACH,IAAW,kBAAkB,IAAI,OAAO,CAYvC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAW,QAAQ,IAAI,OAAO,CAY7B;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,IAAW,UAAU,IAAI,OAAO,CAY/B;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED;;OAEG;IACI,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAa9C;;;;;;;;;;;;;;;;OAgBG;IACI,kBAAkB,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;IAOjF;;OAEG;IACI,UAAU,IAAI,MAAM;CAM5B"}
@@ -44,15 +44,15 @@ class CollectorEntity {
44
44
  this._exportNames = new Set();
45
45
  this._exportNamesSorted = false;
46
46
  this._singleExportName = undefined;
47
+ this._localExportNamesByParent = new Map();
47
48
  this._nameForEmit = undefined;
48
49
  this._sortKey = undefined;
49
- this._astNamespaceImports = new Set();
50
50
  this.astEntity = astEntity;
51
51
  }
52
52
  /**
53
- * The declaration name that will be emitted in a .d.ts rollup. For non-exported declarations,
54
- * Collector._makeUniqueNames() may need to rename the declaration to avoid conflicts with other declarations
55
- * in that module.
53
+ * The declaration name that will be emitted in the .d.ts rollup, .api.md, and .api.json files. Generated by
54
+ * `Collector._makeUniqueNames`. Be aware that the declaration may be renamed to avoid conflicts with (1)
55
+ * global names (e.g. `Promise`) and (2) if local, other local names across different files.
56
56
  */
57
57
  get nameForEmit() {
58
58
  return this._nameForEmit;
@@ -62,7 +62,7 @@ class CollectorEntity {
62
62
  this._sortKey = undefined; // invalidate the cached value
63
63
  }
64
64
  /**
65
- * If this symbol is exported from the entry point, the list of export names.
65
+ * The list of export names if this symbol is exported from the entry point.
66
66
  *
67
67
  * @remarks
68
68
  * Note that a given symbol may be exported more than once:
@@ -104,53 +104,96 @@ class CollectorEntity {
104
104
  return false;
105
105
  }
106
106
  /**
107
- * Returns true if this symbol is an export for the entry point being analyzed.
107
+ * Indicates that this entity is exported from its parent module (i.e. either the package entry point or
108
+ * a local namespace). Compare to `CollectorEntity.consumable`.
109
+ *
110
+ * @remarks
111
+ * In the example below:
112
+ *
113
+ * ```ts
114
+ * declare function add(): void;
115
+ * declare namespace calculator {
116
+ * export {
117
+ * add
118
+ * }
119
+ * }
120
+ * ```
121
+ *
122
+ * Namespace `calculator` is neither exported nor consumable, function `add` is exported (from `calculator`)
123
+ * but not consumable.
108
124
  */
109
125
  get exported() {
110
- return this.exportNames.size > 0;
126
+ // Exported from top-level?
127
+ if (this.exportNames.size > 0)
128
+ return true;
129
+ // Exported from parent?
130
+ for (const localExportNames of this._localExportNamesByParent.values()) {
131
+ if (localExportNames.size > 0) {
132
+ return true;
133
+ }
134
+ }
135
+ return false;
111
136
  }
112
137
  /**
113
- * Indicates that it is possible for a consumer of the API to access this declaration, either by importing
114
- * it directly, or via some other alias such as a member of a namespace. If a collector entity is not consumable,
115
- * then API Extractor will report a ExtractorMessageId.ForgottenExport warning.
138
+ * Indicates that it is possible for a consumer of the API to "consume" this entity, either by importing
139
+ * it directly or via a namespace. If an entity is not consumable, then API Extractor will report an
140
+ * `ae-forgotten-export` warning. Compare to `CollectorEntity.exported`.
116
141
  *
117
142
  * @remarks
118
- * Generally speaking, an API item is consumable if:
119
- *
120
- * - The collector encounters it while crawling the entry point, and it is a root symbol
121
- * (i.e. there is a corresponding a CollectorEntity)
143
+ * An API item is consumable if:
122
144
  *
123
- * - AND it is exported by the entry point
145
+ * 1. It is exported from the top-level entry point OR
146
+ * 2. It is exported from a consumable parent entity.
124
147
  *
125
- * However a special case occurs with `AstNamespaceImport` which produces a rollup like this:
148
+ * For an example of #2, consider how `AstNamespaceImport` entities are processed. A generated rollup.d.ts
149
+ * might look like this:
126
150
  *
127
151
  * ```ts
128
- * declare interface IForgottenExport { }
129
- *
130
- * declare function member(): IForgottenExport;
131
- *
132
- * declare namespace ns {
152
+ * declare function add(): void;
153
+ * declare namespace calculator {
133
154
  * export {
134
- * member
155
+ * add
135
156
  * }
136
157
  * }
137
- * export { ns }
158
+ * export { calculator }
138
159
  * ```
139
160
  *
140
- * In this example, `IForgottenExport` is not consumable. Whereas `member()` is consumable as `ns.member()`
141
- * even though `member()` itself is not exported.
161
+ * In this example, `add` is exported via the consumable `calculator` namespace.
142
162
  */
143
163
  get consumable() {
144
- return this.exported || this._astNamespaceImports.size > 0;
164
+ // Exported from top-level?
165
+ if (this.exportNames.size > 0)
166
+ return true;
167
+ // Exported from consumable parent?
168
+ for (const [parent, localExportNames] of this._localExportNamesByParent) {
169
+ if (localExportNames.size > 0 && parent.consumable) {
170
+ return true;
171
+ }
172
+ }
173
+ return false;
145
174
  }
146
175
  /**
147
- * Associates this entity with a `AstNamespaceImport`.
176
+ * Whether the entity has any parent entities.
177
+ *
178
+ * @remarks
179
+ * In the example below:
180
+ *
181
+ * ```ts
182
+ * declare function add(): void;
183
+ * declare namespace calculator {
184
+ * export {
185
+ * add
186
+ * }
187
+ * }
188
+ * ```
189
+ *
190
+ * The `CollectorEntity` for `calculator` is the parent of the `CollectorEntity` for `add`.
148
191
  */
149
- addAstNamespaceImports(astNamespaceImport) {
150
- this._astNamespaceImports.add(astNamespaceImport);
192
+ get hasParents() {
193
+ return this._localExportNamesByParent.size > 0;
151
194
  }
152
195
  /**
153
- * Adds a new exportName to the exportNames set.
196
+ * Adds a new export name to the entity.
154
197
  */
155
198
  addExportName(exportName) {
156
199
  if (!this._exportNames.has(exportName)) {
@@ -164,6 +207,28 @@ class CollectorEntity {
164
207
  }
165
208
  }
166
209
  }
210
+ /**
211
+ * Adds a new local export name to the entity.
212
+ *
213
+ * @remarks
214
+ * In the example below:
215
+ *
216
+ * ```ts
217
+ * declare function add(): void;
218
+ * declare namespace calculator {
219
+ * export {
220
+ * add
221
+ * }
222
+ * }
223
+ * ```
224
+ *
225
+ * `add` is the local export name for the `CollectorEntity` for `add`.
226
+ */
227
+ addLocalExportName(localExportName, parent) {
228
+ const localExportNames = this._localExportNamesByParent.get(parent) || new Set();
229
+ localExportNames.add(localExportName);
230
+ this._localExportNamesByParent.set(parent, localExportNames);
231
+ }
167
232
  /**
168
233
  * A sorting key used by DtsRollupGenerator._makeUniqueNames()
169
234
  */
@@ -1 +1 @@
1
- {"version":3,"file":"CollectorEntity.js","sourceRoot":"","sources":["../../src/collector/CollectorEntity.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as ts from 'typescript';\n\nimport { AstSymbol } from '../analyzer/AstSymbol';\nimport { Collector } from './Collector';\nimport { Sort } from '@rushstack/node-core-library';\nimport { AstEntity } from '../analyzer/AstEntity';\nimport { AstNamespaceImport } from '../analyzer/AstNamespaceImport';\n\n/**\n * This is a data structure used by the Collector to track an AstEntity that may be emitted in the *.d.ts file.\n *\n * @remarks\n * The additional contextual state beyond AstSymbol is:\n * - Whether it's an export of this entry point or not\n * - The nameForEmit, which may get renamed by DtsRollupGenerator._makeUniqueNames()\n * - The export name (or names, if the same symbol is exported multiple times)\n */\nexport class CollectorEntity {\n /**\n * The AstEntity that this entry represents.\n */\n public readonly astEntity: AstEntity;\n\n private _exportNames: Set<string> = new Set();\n private _exportNamesSorted: boolean = false;\n private _singleExportName: string | undefined = undefined;\n\n private _nameForEmit: string | undefined = undefined;\n\n private _sortKey: string | undefined = undefined;\n\n private _astNamespaceImports: Set<AstNamespaceImport> = new Set();\n\n public constructor(astEntity: AstEntity) {\n this.astEntity = astEntity;\n }\n\n /**\n * The declaration name that will be emitted in a .d.ts rollup. For non-exported declarations,\n * Collector._makeUniqueNames() may need to rename the declaration to avoid conflicts with other declarations\n * in that module.\n */\n public get nameForEmit(): string | undefined {\n return this._nameForEmit;\n }\n\n public set nameForEmit(value: string | undefined) {\n this._nameForEmit = value;\n this._sortKey = undefined; // invalidate the cached value\n }\n\n /**\n * If this symbol is exported from the entry point, the list of export names.\n *\n * @remarks\n * Note that a given symbol may be exported more than once:\n * ```\n * class X { }\n * export { X }\n * export { X as Y }\n * ```\n */\n public get exportNames(): ReadonlySet<string> {\n if (!this._exportNamesSorted) {\n Sort.sortSet(this._exportNames);\n this._exportNamesSorted = true;\n }\n return this._exportNames;\n }\n\n /**\n * If exportNames contains only one string, then singleExportName is that string.\n * In all other cases, it is undefined.\n */\n public get singleExportName(): string | undefined {\n return this._singleExportName;\n }\n\n /**\n * This is true if exportNames contains only one string, and the declaration can be exported using the inline syntax\n * such as \"export class X { }\" instead of \"export { X }\".\n */\n public get shouldInlineExport(): boolean {\n // We don't inline an AstImport\n if (this.astEntity instanceof AstSymbol) {\n // We don't inline a symbol with more than one exported name\n if (this._singleExportName !== undefined && this._singleExportName !== ts.InternalSymbolName.Default) {\n // We can't inline a symbol whose emitted name is different from the export name\n if (this._nameForEmit === undefined || this._nameForEmit === this._singleExportName) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Returns true if this symbol is an export for the entry point being analyzed.\n */\n public get exported(): boolean {\n return this.exportNames.size > 0;\n }\n\n /**\n * Indicates that it is possible for a consumer of the API to access this declaration, either by importing\n * it directly, or via some other alias such as a member of a namespace. If a collector entity is not consumable,\n * then API Extractor will report a ExtractorMessageId.ForgottenExport warning.\n *\n * @remarks\n * Generally speaking, an API item is consumable if:\n *\n * - The collector encounters it while crawling the entry point, and it is a root symbol\n * (i.e. there is a corresponding a CollectorEntity)\n *\n * - AND it is exported by the entry point\n *\n * However a special case occurs with `AstNamespaceImport` which produces a rollup like this:\n *\n * ```ts\n * declare interface IForgottenExport { }\n *\n * declare function member(): IForgottenExport;\n *\n * declare namespace ns {\n * export {\n * member\n * }\n * }\n * export { ns }\n * ```\n *\n * In this example, `IForgottenExport` is not consumable. Whereas `member()` is consumable as `ns.member()`\n * even though `member()` itself is not exported.\n */\n public get consumable(): boolean {\n return this.exported || this._astNamespaceImports.size > 0;\n }\n\n /**\n * Associates this entity with a `AstNamespaceImport`.\n */\n public addAstNamespaceImports(astNamespaceImport: AstNamespaceImport): void {\n this._astNamespaceImports.add(astNamespaceImport);\n }\n\n /**\n * Adds a new exportName to the exportNames set.\n */\n public addExportName(exportName: string): void {\n if (!this._exportNames.has(exportName)) {\n this._exportNamesSorted = false;\n this._exportNames.add(exportName);\n\n if (this._exportNames.size === 1) {\n this._singleExportName = exportName;\n } else {\n this._singleExportName = undefined;\n }\n }\n }\n\n /**\n * A sorting key used by DtsRollupGenerator._makeUniqueNames()\n */\n public getSortKey(): string {\n if (!this._sortKey) {\n this._sortKey = Collector.getSortKeyIgnoringUnderscore(this.nameForEmit || this.astEntity.localName);\n }\n return this._sortKey;\n }\n}\n"]}
1
+ {"version":3,"file":"CollectorEntity.js","sourceRoot":"","sources":["../../src/collector/CollectorEntity.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as ts from 'typescript';\n\nimport { AstSymbol } from '../analyzer/AstSymbol';\nimport { Collector } from './Collector';\nimport { Sort } from '@rushstack/node-core-library';\nimport { AstEntity } from '../analyzer/AstEntity';\n\n/**\n * This is a data structure used by the Collector to track an AstEntity that may be emitted in the *.d.ts file.\n *\n * @remarks\n * The additional contextual state beyond AstSymbol is:\n * - Whether it's an export of this entry point or not\n * - The nameForEmit, which may get renamed by DtsRollupGenerator._makeUniqueNames()\n * - The export name (or names, if the same symbol is exported multiple times)\n */\nexport class CollectorEntity {\n /**\n * The AstEntity that this entry represents.\n */\n public readonly astEntity: AstEntity;\n\n private _exportNames: Set<string> = new Set();\n private _exportNamesSorted: boolean = false;\n private _singleExportName: string | undefined = undefined;\n private _localExportNamesByParent: Map<CollectorEntity, Set<string>> = new Map();\n\n private _nameForEmit: string | undefined = undefined;\n\n private _sortKey: string | undefined = undefined;\n\n public constructor(astEntity: AstEntity) {\n this.astEntity = astEntity;\n }\n\n /**\n * The declaration name that will be emitted in the .d.ts rollup, .api.md, and .api.json files. Generated by\n * `Collector._makeUniqueNames`. Be aware that the declaration may be renamed to avoid conflicts with (1)\n * global names (e.g. `Promise`) and (2) if local, other local names across different files.\n */\n public get nameForEmit(): string | undefined {\n return this._nameForEmit;\n }\n\n public set nameForEmit(value: string | undefined) {\n this._nameForEmit = value;\n this._sortKey = undefined; // invalidate the cached value\n }\n\n /**\n * The list of export names if this symbol is exported from the entry point.\n *\n * @remarks\n * Note that a given symbol may be exported more than once:\n * ```\n * class X { }\n * export { X }\n * export { X as Y }\n * ```\n */\n public get exportNames(): ReadonlySet<string> {\n if (!this._exportNamesSorted) {\n Sort.sortSet(this._exportNames);\n this._exportNamesSorted = true;\n }\n return this._exportNames;\n }\n\n /**\n * If exportNames contains only one string, then singleExportName is that string.\n * In all other cases, it is undefined.\n */\n public get singleExportName(): string | undefined {\n return this._singleExportName;\n }\n\n /**\n * This is true if exportNames contains only one string, and the declaration can be exported using the inline syntax\n * such as \"export class X { }\" instead of \"export { X }\".\n */\n public get shouldInlineExport(): boolean {\n // We don't inline an AstImport\n if (this.astEntity instanceof AstSymbol) {\n // We don't inline a symbol with more than one exported name\n if (this._singleExportName !== undefined && this._singleExportName !== ts.InternalSymbolName.Default) {\n // We can't inline a symbol whose emitted name is different from the export name\n if (this._nameForEmit === undefined || this._nameForEmit === this._singleExportName) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Indicates that this entity is exported from its parent module (i.e. either the package entry point or\n * a local namespace). Compare to `CollectorEntity.consumable`.\n *\n * @remarks\n * In the example below:\n *\n * ```ts\n * declare function add(): void;\n * declare namespace calculator {\n * export {\n * add\n * }\n * }\n * ```\n *\n * Namespace `calculator` is neither exported nor consumable, function `add` is exported (from `calculator`)\n * but not consumable.\n */\n public get exported(): boolean {\n // Exported from top-level?\n if (this.exportNames.size > 0) return true;\n\n // Exported from parent?\n for (const localExportNames of this._localExportNamesByParent.values()) {\n if (localExportNames.size > 0) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Indicates that it is possible for a consumer of the API to \"consume\" this entity, either by importing\n * it directly or via a namespace. If an entity is not consumable, then API Extractor will report an\n * `ae-forgotten-export` warning. Compare to `CollectorEntity.exported`.\n *\n * @remarks\n * An API item is consumable if:\n *\n * 1. It is exported from the top-level entry point OR\n * 2. It is exported from a consumable parent entity.\n *\n * For an example of #2, consider how `AstNamespaceImport` entities are processed. A generated rollup.d.ts\n * might look like this:\n *\n * ```ts\n * declare function add(): void;\n * declare namespace calculator {\n * export {\n * add\n * }\n * }\n * export { calculator }\n * ```\n *\n * In this example, `add` is exported via the consumable `calculator` namespace.\n */\n public get consumable(): boolean {\n // Exported from top-level?\n if (this.exportNames.size > 0) return true;\n\n // Exported from consumable parent?\n for (const [parent, localExportNames] of this._localExportNamesByParent) {\n if (localExportNames.size > 0 && parent.consumable) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Whether the entity has any parent entities.\n *\n * @remarks\n * In the example below:\n *\n * ```ts\n * declare function add(): void;\n * declare namespace calculator {\n * export {\n * add\n * }\n * }\n * ```\n *\n * The `CollectorEntity` for `calculator` is the parent of the `CollectorEntity` for `add`.\n */\n public get hasParents(): boolean {\n return this._localExportNamesByParent.size > 0;\n }\n\n /**\n * Adds a new export name to the entity.\n */\n public addExportName(exportName: string): void {\n if (!this._exportNames.has(exportName)) {\n this._exportNamesSorted = false;\n this._exportNames.add(exportName);\n\n if (this._exportNames.size === 1) {\n this._singleExportName = exportName;\n } else {\n this._singleExportName = undefined;\n }\n }\n }\n\n /**\n * Adds a new local export name to the entity.\n *\n * @remarks\n * In the example below:\n *\n * ```ts\n * declare function add(): void;\n * declare namespace calculator {\n * export {\n * add\n * }\n * }\n * ```\n *\n * `add` is the local export name for the `CollectorEntity` for `add`.\n */\n public addLocalExportName(localExportName: string, parent: CollectorEntity): void {\n const localExportNames: Set<string> = this._localExportNamesByParent.get(parent) || new Set();\n localExportNames.add(localExportName);\n\n this._localExportNamesByParent.set(parent, localExportNames);\n }\n\n /**\n * A sorting key used by DtsRollupGenerator._makeUniqueNames()\n */\n public getSortKey(): string {\n if (!this._sortKey) {\n this._sortKey = Collector.getSortKeyIgnoringUnderscore(this.nameForEmit || this.astEntity.localName);\n }\n return this._sortKey;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DocCommentEnhancer.d.ts","sourceRoot":"","sources":["../../src/enhancers/DocCommentEnhancer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AASnD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;gBAEpB,SAAS,EAAE,SAAS;WAIzB,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAK1C,OAAO,IAAI,IAAI;IAYtB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,0BAA0B;IA4ElC,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,6BAA6B;IA4BrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiDxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAe3B"}
1
+ {"version":3,"file":"DocCommentEnhancer.d.ts","sourceRoot":"","sources":["../../src/enhancers/DocCommentEnhancer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AASnD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;gBAEpB,SAAS,EAAE,SAAS;WAIzB,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAK1C,OAAO,IAAI,IAAI;IAgBtB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,0BAA0B;IA4ElC,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,6BAA6B;IA4BrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiDxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAe3B"}
@@ -43,7 +43,9 @@ class DocCommentEnhancer {
43
43
  analyze() {
44
44
  for (const entity of this._collector.entities) {
45
45
  if (entity.astEntity instanceof AstSymbol_1.AstSymbol) {
46
- if (entity.consumable) {
46
+ if (entity.consumable ||
47
+ this._collector.extractorConfig.apiReportIncludeForgottenExports ||
48
+ this._collector.extractorConfig.docModelIncludeForgottenExports) {
47
49
  entity.astEntity.forEachDeclarationRecursive((astDeclaration) => {
48
50
  this._analyzeApiItem(astDeclaration);
49
51
  });
@@ -1 +1 @@
1
- {"version":3,"file":"DocCommentEnhancer.js","sourceRoot":"","sources":["../../src/enhancers/DocCommentEnhancer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as ts from 'typescript';\nimport * as tsdoc from '@microsoft/tsdoc';\n\nimport { Collector } from '../collector/Collector';\nimport { AstSymbol } from '../analyzer/AstSymbol';\nimport { AstDeclaration } from '../analyzer/AstDeclaration';\nimport { ApiItemMetadata } from '../collector/ApiItemMetadata';\nimport { ReleaseTag } from '@microsoft/api-extractor-model';\nimport { ExtractorMessageId } from '../api/ExtractorMessageId';\nimport { VisitorState } from '../collector/VisitorState';\nimport { ResolverFailure } from '../analyzer/AstReferenceResolver';\n\nexport class DocCommentEnhancer {\n private readonly _collector: Collector;\n\n public constructor(collector: Collector) {\n this._collector = collector;\n }\n\n public static analyze(collector: Collector): void {\n const docCommentEnhancer: DocCommentEnhancer = new DocCommentEnhancer(collector);\n docCommentEnhancer.analyze();\n }\n\n public analyze(): void {\n for (const entity of this._collector.entities) {\n if (entity.astEntity instanceof AstSymbol) {\n if (entity.consumable) {\n entity.astEntity.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {\n this._analyzeApiItem(astDeclaration);\n });\n }\n }\n }\n }\n\n private _analyzeApiItem(astDeclaration: AstDeclaration): void {\n const metadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);\n if (metadata.docCommentEnhancerVisitorState === VisitorState.Visited) {\n return;\n }\n\n if (metadata.docCommentEnhancerVisitorState === VisitorState.Visiting) {\n this._collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.CyclicInheritDoc,\n `The @inheritDoc tag for \"${astDeclaration.astSymbol.localName}\" refers to its own declaration`,\n astDeclaration\n );\n return;\n }\n metadata.docCommentEnhancerVisitorState = VisitorState.Visiting;\n\n if (metadata.tsdocComment && metadata.tsdocComment.inheritDocTag) {\n this._applyInheritDoc(astDeclaration, metadata.tsdocComment, metadata.tsdocComment.inheritDocTag);\n }\n\n this._analyzeNeedsDocumentation(astDeclaration, metadata);\n\n this._checkForBrokenLinks(astDeclaration, metadata);\n\n metadata.docCommentEnhancerVisitorState = VisitorState.Visited;\n }\n\n private _analyzeNeedsDocumentation(astDeclaration: AstDeclaration, metadata: ApiItemMetadata): void {\n if (astDeclaration.declaration.kind === ts.SyntaxKind.Constructor) {\n // Constructors always do pretty much the same thing, so it's annoying to require people to write\n // descriptions for them. Instead, if the constructor lacks a TSDoc summary, then API Extractor\n // will auto-generate one.\n metadata.needsDocumentation = false;\n\n // The class that contains this constructor\n const classDeclaration: AstDeclaration = astDeclaration.parent!;\n\n const configuration: tsdoc.TSDocConfiguration = this._collector.extractorConfig.tsdocConfiguration;\n\n if (!metadata.tsdocComment) {\n metadata.tsdocComment = new tsdoc.DocComment({ configuration });\n }\n\n if (!tsdoc.PlainTextEmitter.hasAnyTextContent(metadata.tsdocComment.summarySection)) {\n metadata.tsdocComment.summarySection.appendNodesInParagraph([\n new tsdoc.DocPlainText({ configuration, text: 'Constructs a new instance of the ' }),\n new tsdoc.DocCodeSpan({\n configuration,\n code: classDeclaration.astSymbol.localName\n }),\n new tsdoc.DocPlainText({ configuration, text: ' class' })\n ]);\n }\n\n const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);\n if (apiItemMetadata.effectiveReleaseTag === ReleaseTag.Internal) {\n // If the constructor is marked as internal, then add a boilerplate notice for the containing class\n const classMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(classDeclaration);\n\n if (!classMetadata.tsdocComment) {\n classMetadata.tsdocComment = new tsdoc.DocComment({ configuration });\n }\n\n if (classMetadata.tsdocComment.remarksBlock === undefined) {\n classMetadata.tsdocComment.remarksBlock = new tsdoc.DocBlock({\n configuration,\n blockTag: new tsdoc.DocBlockTag({\n configuration,\n tagName: tsdoc.StandardTags.remarks.tagName\n })\n });\n }\n\n classMetadata.tsdocComment.remarksBlock.content.appendNode(\n new tsdoc.DocParagraph({ configuration }, [\n new tsdoc.DocPlainText({\n configuration,\n text:\n `The constructor for this class is marked as internal. Third-party code should not` +\n ` call the constructor directly or create subclasses that extend the `\n }),\n new tsdoc.DocCodeSpan({\n configuration,\n code: classDeclaration.astSymbol.localName\n }),\n new tsdoc.DocPlainText({ configuration, text: ' class.' })\n ])\n );\n }\n return;\n }\n\n if (metadata.tsdocComment) {\n // Require the summary to contain at least 10 non-spacing characters\n metadata.needsDocumentation = !tsdoc.PlainTextEmitter.hasAnyTextContent(\n metadata.tsdocComment.summarySection,\n 10\n );\n } else {\n metadata.needsDocumentation = true;\n }\n }\n\n private _checkForBrokenLinks(astDeclaration: AstDeclaration, metadata: ApiItemMetadata): void {\n if (!metadata.tsdocComment) {\n return;\n }\n this._checkForBrokenLinksRecursive(astDeclaration, metadata.tsdocComment);\n }\n\n private _checkForBrokenLinksRecursive(astDeclaration: AstDeclaration, node: tsdoc.DocNode): void {\n if (node instanceof tsdoc.DocLinkTag) {\n if (node.codeDestination) {\n // Is it referring to the working package? If not, we don't do any link validation, because\n // AstReferenceResolver doesn't support it yet (but ModelReferenceResolver does of course).\n // Tracked by: https://github.com/microsoft/rushstack/issues/1195\n if (\n node.codeDestination.packageName === undefined ||\n node.codeDestination.packageName === this._collector.workingPackage.name\n ) {\n const referencedAstDeclaration: AstDeclaration | ResolverFailure =\n this._collector.astReferenceResolver.resolve(node.codeDestination);\n\n if (referencedAstDeclaration instanceof ResolverFailure) {\n this._collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.UnresolvedLink,\n 'The @link reference could not be resolved: ' + referencedAstDeclaration.reason,\n astDeclaration\n );\n }\n }\n }\n }\n for (const childNode of node.getChildNodes()) {\n this._checkForBrokenLinksRecursive(astDeclaration, childNode);\n }\n }\n\n /**\n * Follow an `{@inheritDoc ___}` reference and copy the content that we find in the referenced comment.\n */\n private _applyInheritDoc(\n astDeclaration: AstDeclaration,\n docComment: tsdoc.DocComment,\n inheritDocTag: tsdoc.DocInheritDocTag\n ): void {\n if (!inheritDocTag.declarationReference) {\n this._collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.UnresolvedInheritDocBase,\n 'The @inheritDoc tag needs a TSDoc declaration reference; signature matching is not supported yet',\n astDeclaration\n );\n return;\n }\n\n // Is it referring to the working package?\n if (\n !(\n inheritDocTag.declarationReference.packageName === undefined ||\n inheritDocTag.declarationReference.packageName === this._collector.workingPackage.name\n )\n ) {\n // It's referencing an external package, so skip this inheritDoc tag, since AstReferenceResolver doesn't\n // support it yet. As a workaround, this tag will get handled later by api-documenter.\n // Tracked by: https://github.com/microsoft/rushstack/issues/1195\n return;\n }\n\n const referencedAstDeclaration: AstDeclaration | ResolverFailure =\n this._collector.astReferenceResolver.resolve(inheritDocTag.declarationReference);\n\n if (referencedAstDeclaration instanceof ResolverFailure) {\n this._collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.UnresolvedInheritDocReference,\n 'The @inheritDoc reference could not be resolved: ' + referencedAstDeclaration.reason,\n astDeclaration\n );\n return;\n }\n\n this._analyzeApiItem(referencedAstDeclaration);\n\n const referencedMetadata: ApiItemMetadata =\n this._collector.fetchApiItemMetadata(referencedAstDeclaration);\n\n if (referencedMetadata.tsdocComment) {\n this._copyInheritedDocs(docComment, referencedMetadata.tsdocComment);\n }\n }\n\n /**\n * Copy the content from `sourceDocComment` to `targetDocComment`.\n */\n private _copyInheritedDocs(targetDocComment: tsdoc.DocComment, sourceDocComment: tsdoc.DocComment): void {\n targetDocComment.summarySection = sourceDocComment.summarySection;\n targetDocComment.remarksBlock = sourceDocComment.remarksBlock;\n\n targetDocComment.params.clear();\n for (const param of sourceDocComment.params) {\n targetDocComment.params.add(param);\n }\n for (const typeParam of sourceDocComment.typeParams) {\n targetDocComment.typeParams.add(typeParam);\n }\n targetDocComment.returnsBlock = sourceDocComment.returnsBlock;\n\n targetDocComment.inheritDocTag = undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"DocCommentEnhancer.js","sourceRoot":"","sources":["../../src/enhancers/DocCommentEnhancer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as ts from 'typescript';\nimport * as tsdoc from '@microsoft/tsdoc';\n\nimport { Collector } from '../collector/Collector';\nimport { AstSymbol } from '../analyzer/AstSymbol';\nimport { AstDeclaration } from '../analyzer/AstDeclaration';\nimport { ApiItemMetadata } from '../collector/ApiItemMetadata';\nimport { ReleaseTag } from '@microsoft/api-extractor-model';\nimport { ExtractorMessageId } from '../api/ExtractorMessageId';\nimport { VisitorState } from '../collector/VisitorState';\nimport { ResolverFailure } from '../analyzer/AstReferenceResolver';\n\nexport class DocCommentEnhancer {\n private readonly _collector: Collector;\n\n public constructor(collector: Collector) {\n this._collector = collector;\n }\n\n public static analyze(collector: Collector): void {\n const docCommentEnhancer: DocCommentEnhancer = new DocCommentEnhancer(collector);\n docCommentEnhancer.analyze();\n }\n\n public analyze(): void {\n for (const entity of this._collector.entities) {\n if (entity.astEntity instanceof AstSymbol) {\n if (\n entity.consumable ||\n this._collector.extractorConfig.apiReportIncludeForgottenExports ||\n this._collector.extractorConfig.docModelIncludeForgottenExports\n ) {\n entity.astEntity.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {\n this._analyzeApiItem(astDeclaration);\n });\n }\n }\n }\n }\n\n private _analyzeApiItem(astDeclaration: AstDeclaration): void {\n const metadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);\n if (metadata.docCommentEnhancerVisitorState === VisitorState.Visited) {\n return;\n }\n\n if (metadata.docCommentEnhancerVisitorState === VisitorState.Visiting) {\n this._collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.CyclicInheritDoc,\n `The @inheritDoc tag for \"${astDeclaration.astSymbol.localName}\" refers to its own declaration`,\n astDeclaration\n );\n return;\n }\n metadata.docCommentEnhancerVisitorState = VisitorState.Visiting;\n\n if (metadata.tsdocComment && metadata.tsdocComment.inheritDocTag) {\n this._applyInheritDoc(astDeclaration, metadata.tsdocComment, metadata.tsdocComment.inheritDocTag);\n }\n\n this._analyzeNeedsDocumentation(astDeclaration, metadata);\n\n this._checkForBrokenLinks(astDeclaration, metadata);\n\n metadata.docCommentEnhancerVisitorState = VisitorState.Visited;\n }\n\n private _analyzeNeedsDocumentation(astDeclaration: AstDeclaration, metadata: ApiItemMetadata): void {\n if (astDeclaration.declaration.kind === ts.SyntaxKind.Constructor) {\n // Constructors always do pretty much the same thing, so it's annoying to require people to write\n // descriptions for them. Instead, if the constructor lacks a TSDoc summary, then API Extractor\n // will auto-generate one.\n metadata.needsDocumentation = false;\n\n // The class that contains this constructor\n const classDeclaration: AstDeclaration = astDeclaration.parent!;\n\n const configuration: tsdoc.TSDocConfiguration = this._collector.extractorConfig.tsdocConfiguration;\n\n if (!metadata.tsdocComment) {\n metadata.tsdocComment = new tsdoc.DocComment({ configuration });\n }\n\n if (!tsdoc.PlainTextEmitter.hasAnyTextContent(metadata.tsdocComment.summarySection)) {\n metadata.tsdocComment.summarySection.appendNodesInParagraph([\n new tsdoc.DocPlainText({ configuration, text: 'Constructs a new instance of the ' }),\n new tsdoc.DocCodeSpan({\n configuration,\n code: classDeclaration.astSymbol.localName\n }),\n new tsdoc.DocPlainText({ configuration, text: ' class' })\n ]);\n }\n\n const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);\n if (apiItemMetadata.effectiveReleaseTag === ReleaseTag.Internal) {\n // If the constructor is marked as internal, then add a boilerplate notice for the containing class\n const classMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(classDeclaration);\n\n if (!classMetadata.tsdocComment) {\n classMetadata.tsdocComment = new tsdoc.DocComment({ configuration });\n }\n\n if (classMetadata.tsdocComment.remarksBlock === undefined) {\n classMetadata.tsdocComment.remarksBlock = new tsdoc.DocBlock({\n configuration,\n blockTag: new tsdoc.DocBlockTag({\n configuration,\n tagName: tsdoc.StandardTags.remarks.tagName\n })\n });\n }\n\n classMetadata.tsdocComment.remarksBlock.content.appendNode(\n new tsdoc.DocParagraph({ configuration }, [\n new tsdoc.DocPlainText({\n configuration,\n text:\n `The constructor for this class is marked as internal. Third-party code should not` +\n ` call the constructor directly or create subclasses that extend the `\n }),\n new tsdoc.DocCodeSpan({\n configuration,\n code: classDeclaration.astSymbol.localName\n }),\n new tsdoc.DocPlainText({ configuration, text: ' class.' })\n ])\n );\n }\n return;\n }\n\n if (metadata.tsdocComment) {\n // Require the summary to contain at least 10 non-spacing characters\n metadata.needsDocumentation = !tsdoc.PlainTextEmitter.hasAnyTextContent(\n metadata.tsdocComment.summarySection,\n 10\n );\n } else {\n metadata.needsDocumentation = true;\n }\n }\n\n private _checkForBrokenLinks(astDeclaration: AstDeclaration, metadata: ApiItemMetadata): void {\n if (!metadata.tsdocComment) {\n return;\n }\n this._checkForBrokenLinksRecursive(astDeclaration, metadata.tsdocComment);\n }\n\n private _checkForBrokenLinksRecursive(astDeclaration: AstDeclaration, node: tsdoc.DocNode): void {\n if (node instanceof tsdoc.DocLinkTag) {\n if (node.codeDestination) {\n // Is it referring to the working package? If not, we don't do any link validation, because\n // AstReferenceResolver doesn't support it yet (but ModelReferenceResolver does of course).\n // Tracked by: https://github.com/microsoft/rushstack/issues/1195\n if (\n node.codeDestination.packageName === undefined ||\n node.codeDestination.packageName === this._collector.workingPackage.name\n ) {\n const referencedAstDeclaration: AstDeclaration | ResolverFailure =\n this._collector.astReferenceResolver.resolve(node.codeDestination);\n\n if (referencedAstDeclaration instanceof ResolverFailure) {\n this._collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.UnresolvedLink,\n 'The @link reference could not be resolved: ' + referencedAstDeclaration.reason,\n astDeclaration\n );\n }\n }\n }\n }\n for (const childNode of node.getChildNodes()) {\n this._checkForBrokenLinksRecursive(astDeclaration, childNode);\n }\n }\n\n /**\n * Follow an `{@inheritDoc ___}` reference and copy the content that we find in the referenced comment.\n */\n private _applyInheritDoc(\n astDeclaration: AstDeclaration,\n docComment: tsdoc.DocComment,\n inheritDocTag: tsdoc.DocInheritDocTag\n ): void {\n if (!inheritDocTag.declarationReference) {\n this._collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.UnresolvedInheritDocBase,\n 'The @inheritDoc tag needs a TSDoc declaration reference; signature matching is not supported yet',\n astDeclaration\n );\n return;\n }\n\n // Is it referring to the working package?\n if (\n !(\n inheritDocTag.declarationReference.packageName === undefined ||\n inheritDocTag.declarationReference.packageName === this._collector.workingPackage.name\n )\n ) {\n // It's referencing an external package, so skip this inheritDoc tag, since AstReferenceResolver doesn't\n // support it yet. As a workaround, this tag will get handled later by api-documenter.\n // Tracked by: https://github.com/microsoft/rushstack/issues/1195\n return;\n }\n\n const referencedAstDeclaration: AstDeclaration | ResolverFailure =\n this._collector.astReferenceResolver.resolve(inheritDocTag.declarationReference);\n\n if (referencedAstDeclaration instanceof ResolverFailure) {\n this._collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.UnresolvedInheritDocReference,\n 'The @inheritDoc reference could not be resolved: ' + referencedAstDeclaration.reason,\n astDeclaration\n );\n return;\n }\n\n this._analyzeApiItem(referencedAstDeclaration);\n\n const referencedMetadata: ApiItemMetadata =\n this._collector.fetchApiItemMetadata(referencedAstDeclaration);\n\n if (referencedMetadata.tsdocComment) {\n this._copyInheritedDocs(docComment, referencedMetadata.tsdocComment);\n }\n }\n\n /**\n * Copy the content from `sourceDocComment` to `targetDocComment`.\n */\n private _copyInheritedDocs(targetDocComment: tsdoc.DocComment, sourceDocComment: tsdoc.DocComment): void {\n targetDocComment.summarySection = sourceDocComment.summarySection;\n targetDocComment.remarksBlock = sourceDocComment.remarksBlock;\n\n targetDocComment.params.clear();\n for (const param of sourceDocComment.params) {\n targetDocComment.params.add(param);\n }\n for (const typeParam of sourceDocComment.typeParams) {\n targetDocComment.typeParams.add(typeParam);\n }\n targetDocComment.returnsBlock = sourceDocComment.returnsBlock;\n\n targetDocComment.inheritDocTag = undefined;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ValidationEnhancer.d.ts","sourceRoot":"","sources":["../../src/enhancers/ValidationEnhancer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAYnD,qBAAa,kBAAkB;WACf,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IA8CjD,OAAO,CAAC,MAAM,CAAC,2BAA2B;IA0D1C,OAAO,CAAC,MAAM,CAAC,gCAAgC;IAiE/C,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAiF/B,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA2BnC"}
1
+ {"version":3,"file":"ValidationEnhancer.d.ts","sourceRoot":"","sources":["../../src/enhancers/ValidationEnhancer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAYnD,qBAAa,kBAAkB;WACf,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAoDjD,OAAO,CAAC,MAAM,CAAC,2BAA2B;IA0D1C,OAAO,CAAC,MAAM,CAAC,gCAAgC;IAiE/C,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAgF/B,OAAO,CAAC,MAAM,CAAC,mBAAmB;CA2BnC"}
@@ -35,7 +35,9 @@ class ValidationEnhancer {
35
35
  static analyze(collector) {
36
36
  const alreadyWarnedEntities = new Set();
37
37
  for (const entity of collector.entities) {
38
- if (!entity.consumable) {
38
+ if (!(entity.consumable ||
39
+ collector.extractorConfig.apiReportIncludeForgottenExports ||
40
+ collector.extractorConfig.docModelIncludeForgottenExports)) {
39
41
  continue;
40
42
  }
41
43
  if (entity.astEntity instanceof AstSymbol_1.AstSymbol) {
@@ -70,7 +72,7 @@ class ValidationEnhancer {
70
72
  let needsUnderscore = false;
71
73
  if (symbolMetadata.maxEffectiveReleaseTag === api_extractor_model_1.ReleaseTag.Internal) {
72
74
  if (!astSymbol.parentAstSymbol) {
73
- // If it's marked as @internal and has no parent, then it needs and underscore.
75
+ // If it's marked as @internal and has no parent, then it needs an underscore.
74
76
  // We use maxEffectiveReleaseTag because a merged declaration would NOT need an underscore in a case like this:
75
77
  //
76
78
  // /** @public */
@@ -170,8 +172,8 @@ class ValidationEnhancer {
170
172
  if (rootSymbol.isExternal) {
171
173
  continue;
172
174
  }
173
- localName = rootSymbol.localName;
174
175
  collectorEntity = collector.tryGetCollectorEntity(rootSymbol);
176
+ localName = (collectorEntity === null || collectorEntity === void 0 ? void 0 : collectorEntity.nameForEmit) || rootSymbol.localName;
175
177
  const referencedMetadata = collector.fetchSymbolMetadata(referencedEntity);
176
178
  referencedReleaseTag = referencedMetadata.maxEffectiveReleaseTag;
177
179
  }
@@ -179,7 +181,7 @@ class ValidationEnhancer {
179
181
  collectorEntity = collector.tryGetCollectorEntity(referencedEntity);
180
182
  // TODO: Currently the "import * as ___ from ___" syntax does not yet support doc comments
181
183
  referencedReleaseTag = api_extractor_model_1.ReleaseTag.Public;
182
- localName = referencedEntity.localName;
184
+ localName = (collectorEntity === null || collectorEntity === void 0 ? void 0 : collectorEntity.nameForEmit) || referencedEntity.localName;
183
185
  }
184
186
  else {
185
187
  continue;
@@ -188,7 +190,7 @@ class ValidationEnhancer {
188
190
  if (api_extractor_model_1.ReleaseTag.compare(declarationReleaseTag, referencedReleaseTag) > 0) {
189
191
  collector.messageRouter.addAnalyzerIssue("ae-incompatible-release-tags" /* ExtractorMessageId.IncompatibleReleaseTags */, `The symbol "${astDeclaration.astSymbol.localName}"` +
190
192
  ` is marked as ${api_extractor_model_1.ReleaseTag.getTagName(declarationReleaseTag)},` +
191
- ` but its signature references "${referencedEntity.localName}"` +
193
+ ` but its signature references "${localName}"` +
192
194
  ` which is marked as ${api_extractor_model_1.ReleaseTag.getTagName(referencedReleaseTag)}`, astDeclaration);
193
195
  }
194
196
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ValidationEnhancer.js","sourceRoot":"","sources":["../../src/enhancers/ValidationEnhancer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as path from 'path';\nimport * as ts from 'typescript';\n\nimport { Collector } from '../collector/Collector';\nimport { AstSymbol } from '../analyzer/AstSymbol';\nimport { AstDeclaration } from '../analyzer/AstDeclaration';\nimport { ApiItemMetadata } from '../collector/ApiItemMetadata';\nimport { SymbolMetadata } from '../collector/SymbolMetadata';\nimport { CollectorEntity } from '../collector/CollectorEntity';\nimport { ExtractorMessageId } from '../api/ExtractorMessageId';\nimport { ReleaseTag } from '@microsoft/api-extractor-model';\nimport { AstNamespaceImport } from '../analyzer/AstNamespaceImport';\nimport { AstModuleExportInfo } from '../analyzer/AstModule';\nimport { AstEntity } from '../analyzer/AstEntity';\n\nexport class ValidationEnhancer {\n public static analyze(collector: Collector): void {\n const alreadyWarnedEntities: Set<AstEntity> = new Set<AstEntity>();\n\n for (const entity of collector.entities) {\n if (!entity.consumable) {\n continue;\n }\n\n if (entity.astEntity instanceof AstSymbol) {\n // A regular exported AstSymbol\n\n const astSymbol: AstSymbol = entity.astEntity;\n\n astSymbol.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {\n ValidationEnhancer._checkReferences(collector, astDeclaration, alreadyWarnedEntities);\n });\n\n const symbolMetadata: SymbolMetadata = collector.fetchSymbolMetadata(astSymbol);\n ValidationEnhancer._checkForInternalUnderscore(collector, entity, astSymbol, symbolMetadata);\n ValidationEnhancer._checkForInconsistentReleaseTags(collector, astSymbol, symbolMetadata);\n } else if (entity.astEntity instanceof AstNamespaceImport) {\n // A namespace created using \"import * as ___ from ___\"\n const astNamespaceImport: AstNamespaceImport = entity.astEntity;\n\n const astModuleExportInfo: AstModuleExportInfo =\n astNamespaceImport.fetchAstModuleExportInfo(collector);\n\n for (const namespaceMemberAstEntity of astModuleExportInfo.exportedLocalEntities.values()) {\n if (namespaceMemberAstEntity instanceof AstSymbol) {\n const astSymbol: AstSymbol = namespaceMemberAstEntity;\n\n astSymbol.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {\n ValidationEnhancer._checkReferences(collector, astDeclaration, alreadyWarnedEntities);\n });\n\n const symbolMetadata: SymbolMetadata = collector.fetchSymbolMetadata(astSymbol);\n\n // (Don't apply ValidationEnhancer._checkForInternalUnderscore() for AstNamespaceImport members)\n\n ValidationEnhancer._checkForInconsistentReleaseTags(collector, astSymbol, symbolMetadata);\n }\n }\n }\n }\n }\n\n private static _checkForInternalUnderscore(\n collector: Collector,\n collectorEntity: CollectorEntity,\n astSymbol: AstSymbol,\n symbolMetadata: SymbolMetadata\n ): void {\n let needsUnderscore: boolean = false;\n\n if (symbolMetadata.maxEffectiveReleaseTag === ReleaseTag.Internal) {\n if (!astSymbol.parentAstSymbol) {\n // If it's marked as @internal and has no parent, then it needs and underscore.\n // We use maxEffectiveReleaseTag because a merged declaration would NOT need an underscore in a case like this:\n //\n // /** @public */\n // export enum X { }\n //\n // /** @internal */\n // export namespace X { }\n //\n // (The above normally reports an error \"ae-different-release-tags\", but that may be suppressed.)\n needsUnderscore = true;\n } else {\n // If it's marked as @internal and the parent isn't obviously already @internal, then it needs an underscore.\n //\n // For example, we WOULD need an underscore for a merged declaration like this:\n //\n // /** @internal */\n // export namespace X {\n // export interface _Y { }\n // }\n //\n // /** @public */\n // export class X {\n // /** @internal */\n // public static _Y(): void { } // <==== different from parent\n // }\n const parentSymbolMetadata: SymbolMetadata = collector.fetchSymbolMetadata(astSymbol);\n if (parentSymbolMetadata.maxEffectiveReleaseTag > ReleaseTag.Internal) {\n needsUnderscore = true;\n }\n }\n }\n\n if (needsUnderscore) {\n for (const exportName of collectorEntity.exportNames) {\n if (exportName[0] !== '_') {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.InternalMissingUnderscore,\n `The name \"${exportName}\" should be prefixed with an underscore` +\n ` because the declaration is marked as @internal`,\n astSymbol,\n { exportName }\n );\n }\n }\n }\n }\n\n private static _checkForInconsistentReleaseTags(\n collector: Collector,\n astSymbol: AstSymbol,\n symbolMetadata: SymbolMetadata\n ): void {\n if (astSymbol.isExternal) {\n // For now, don't report errors for external code. If the developer cares about it, they should run\n // API Extractor separately on the external project\n return;\n }\n\n // Normally we will expect all release tags to be the same. Arbitrarily we choose the maxEffectiveReleaseTag\n // as the thing they should all match.\n const expectedEffectiveReleaseTag: ReleaseTag = symbolMetadata.maxEffectiveReleaseTag;\n\n // This is set to true if we find a declaration whose release tag is different from expectedEffectiveReleaseTag\n let mixedReleaseTags: boolean = false;\n\n // This is set to false if we find a declaration that is not a function/method overload\n let onlyFunctionOverloads: boolean = true;\n\n // This is set to true if we find a declaration that is @internal\n let anyInternalReleaseTags: boolean = false;\n\n for (const astDeclaration of astSymbol.astDeclarations) {\n const apiItemMetadata: ApiItemMetadata = collector.fetchApiItemMetadata(astDeclaration);\n const effectiveReleaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;\n\n switch (astDeclaration.declaration.kind) {\n case ts.SyntaxKind.FunctionDeclaration:\n case ts.SyntaxKind.MethodDeclaration:\n break;\n default:\n onlyFunctionOverloads = false;\n }\n\n if (effectiveReleaseTag !== expectedEffectiveReleaseTag) {\n mixedReleaseTags = true;\n }\n\n if (effectiveReleaseTag === ReleaseTag.Internal) {\n anyInternalReleaseTags = true;\n }\n }\n\n if (mixedReleaseTags) {\n if (!onlyFunctionOverloads) {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.DifferentReleaseTags,\n 'This symbol has another declaration with a different release tag',\n astSymbol\n );\n }\n\n if (anyInternalReleaseTags) {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.InternalMixedReleaseTag,\n `Mixed release tags are not allowed for \"${astSymbol.localName}\" because one of its declarations` +\n ` is marked as @internal`,\n astSymbol\n );\n }\n }\n }\n\n private static _checkReferences(\n collector: Collector,\n astDeclaration: AstDeclaration,\n alreadyWarnedEntities: Set<AstEntity>\n ): void {\n const apiItemMetadata: ApiItemMetadata = collector.fetchApiItemMetadata(astDeclaration);\n const declarationReleaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;\n\n for (const referencedEntity of astDeclaration.referencedAstEntities) {\n let collectorEntity: CollectorEntity | undefined;\n let referencedReleaseTag: ReleaseTag;\n let localName: string;\n\n if (referencedEntity instanceof AstSymbol) {\n // If this is e.g. a member of a namespace, then we need to be checking the top-level scope to see\n // whether it's exported.\n //\n // TODO: Technically we should also check each of the nested scopes along the way.\n const rootSymbol: AstSymbol = referencedEntity.rootAstSymbol;\n\n if (rootSymbol.isExternal) {\n continue;\n }\n\n localName = rootSymbol.localName;\n\n collectorEntity = collector.tryGetCollectorEntity(rootSymbol);\n\n const referencedMetadata: SymbolMetadata = collector.fetchSymbolMetadata(referencedEntity);\n referencedReleaseTag = referencedMetadata.maxEffectiveReleaseTag;\n } else if (referencedEntity instanceof AstNamespaceImport) {\n collectorEntity = collector.tryGetCollectorEntity(referencedEntity);\n\n // TODO: Currently the \"import * as ___ from ___\" syntax does not yet support doc comments\n referencedReleaseTag = ReleaseTag.Public;\n\n localName = referencedEntity.localName;\n } else {\n continue;\n }\n\n if (collectorEntity && collectorEntity.consumable) {\n if (ReleaseTag.compare(declarationReleaseTag, referencedReleaseTag) > 0) {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.IncompatibleReleaseTags,\n `The symbol \"${astDeclaration.astSymbol.localName}\"` +\n ` is marked as ${ReleaseTag.getTagName(declarationReleaseTag)},` +\n ` but its signature references \"${referencedEntity.localName}\"` +\n ` which is marked as ${ReleaseTag.getTagName(referencedReleaseTag)}`,\n astDeclaration\n );\n }\n } else {\n const entryPointFilename: string = path.basename(\n collector.workingPackage.entryPointSourceFile.fileName\n );\n\n if (!alreadyWarnedEntities.has(referencedEntity)) {\n alreadyWarnedEntities.add(referencedEntity);\n\n if (\n referencedEntity instanceof AstSymbol &&\n ValidationEnhancer._isEcmaScriptSymbol(referencedEntity)\n ) {\n // The main usage scenario for ECMAScript symbols is to attach private data to a JavaScript object,\n // so as a special case, we do NOT report them as forgotten exports.\n } else {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.ForgottenExport,\n `The symbol \"${localName}\" needs to be exported by the entry point ${entryPointFilename}`,\n astDeclaration\n );\n }\n }\n }\n }\n }\n\n // Detect an AstSymbol that refers to an ECMAScript symbol declaration such as:\n //\n // const mySymbol: unique symbol = Symbol('mySymbol');\n private static _isEcmaScriptSymbol(astSymbol: AstSymbol): boolean {\n if (astSymbol.astDeclarations.length !== 1) {\n return false;\n }\n\n // We are matching a form like this:\n //\n // - VariableDeclaration:\n // - Identifier: pre=[mySymbol]\n // - ColonToken: pre=[:] sep=[ ]\n // - TypeOperator:\n // - UniqueKeyword: pre=[unique] sep=[ ]\n // - SymbolKeyword: pre=[symbol]\n const astDeclaration: AstDeclaration = astSymbol.astDeclarations[0];\n if (ts.isVariableDeclaration(astDeclaration.declaration)) {\n const variableTypeNode: ts.TypeNode | undefined = astDeclaration.declaration.type;\n if (variableTypeNode) {\n for (const token of variableTypeNode.getChildren()) {\n if (token.kind === ts.SyntaxKind.SymbolKeyword) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"ValidationEnhancer.js","sourceRoot":"","sources":["../../src/enhancers/ValidationEnhancer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as path from 'path';\nimport * as ts from 'typescript';\n\nimport { Collector } from '../collector/Collector';\nimport { AstSymbol } from '../analyzer/AstSymbol';\nimport { AstDeclaration } from '../analyzer/AstDeclaration';\nimport { ApiItemMetadata } from '../collector/ApiItemMetadata';\nimport { SymbolMetadata } from '../collector/SymbolMetadata';\nimport { CollectorEntity } from '../collector/CollectorEntity';\nimport { ExtractorMessageId } from '../api/ExtractorMessageId';\nimport { ReleaseTag } from '@microsoft/api-extractor-model';\nimport { AstNamespaceImport } from '../analyzer/AstNamespaceImport';\nimport { AstModuleExportInfo } from '../analyzer/AstModule';\nimport { AstEntity } from '../analyzer/AstEntity';\n\nexport class ValidationEnhancer {\n public static analyze(collector: Collector): void {\n const alreadyWarnedEntities: Set<AstEntity> = new Set<AstEntity>();\n\n for (const entity of collector.entities) {\n if (\n !(\n entity.consumable ||\n collector.extractorConfig.apiReportIncludeForgottenExports ||\n collector.extractorConfig.docModelIncludeForgottenExports\n )\n ) {\n continue;\n }\n\n if (entity.astEntity instanceof AstSymbol) {\n // A regular exported AstSymbol\n\n const astSymbol: AstSymbol = entity.astEntity;\n\n astSymbol.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {\n ValidationEnhancer._checkReferences(collector, astDeclaration, alreadyWarnedEntities);\n });\n\n const symbolMetadata: SymbolMetadata = collector.fetchSymbolMetadata(astSymbol);\n ValidationEnhancer._checkForInternalUnderscore(collector, entity, astSymbol, symbolMetadata);\n ValidationEnhancer._checkForInconsistentReleaseTags(collector, astSymbol, symbolMetadata);\n } else if (entity.astEntity instanceof AstNamespaceImport) {\n // A namespace created using \"import * as ___ from ___\"\n const astNamespaceImport: AstNamespaceImport = entity.astEntity;\n\n const astModuleExportInfo: AstModuleExportInfo =\n astNamespaceImport.fetchAstModuleExportInfo(collector);\n\n for (const namespaceMemberAstEntity of astModuleExportInfo.exportedLocalEntities.values()) {\n if (namespaceMemberAstEntity instanceof AstSymbol) {\n const astSymbol: AstSymbol = namespaceMemberAstEntity;\n\n astSymbol.forEachDeclarationRecursive((astDeclaration: AstDeclaration) => {\n ValidationEnhancer._checkReferences(collector, astDeclaration, alreadyWarnedEntities);\n });\n\n const symbolMetadata: SymbolMetadata = collector.fetchSymbolMetadata(astSymbol);\n\n // (Don't apply ValidationEnhancer._checkForInternalUnderscore() for AstNamespaceImport members)\n\n ValidationEnhancer._checkForInconsistentReleaseTags(collector, astSymbol, symbolMetadata);\n }\n }\n }\n }\n }\n\n private static _checkForInternalUnderscore(\n collector: Collector,\n collectorEntity: CollectorEntity,\n astSymbol: AstSymbol,\n symbolMetadata: SymbolMetadata\n ): void {\n let needsUnderscore: boolean = false;\n\n if (symbolMetadata.maxEffectiveReleaseTag === ReleaseTag.Internal) {\n if (!astSymbol.parentAstSymbol) {\n // If it's marked as @internal and has no parent, then it needs an underscore.\n // We use maxEffectiveReleaseTag because a merged declaration would NOT need an underscore in a case like this:\n //\n // /** @public */\n // export enum X { }\n //\n // /** @internal */\n // export namespace X { }\n //\n // (The above normally reports an error \"ae-different-release-tags\", but that may be suppressed.)\n needsUnderscore = true;\n } else {\n // If it's marked as @internal and the parent isn't obviously already @internal, then it needs an underscore.\n //\n // For example, we WOULD need an underscore for a merged declaration like this:\n //\n // /** @internal */\n // export namespace X {\n // export interface _Y { }\n // }\n //\n // /** @public */\n // export class X {\n // /** @internal */\n // public static _Y(): void { } // <==== different from parent\n // }\n const parentSymbolMetadata: SymbolMetadata = collector.fetchSymbolMetadata(astSymbol);\n if (parentSymbolMetadata.maxEffectiveReleaseTag > ReleaseTag.Internal) {\n needsUnderscore = true;\n }\n }\n }\n\n if (needsUnderscore) {\n for (const exportName of collectorEntity.exportNames) {\n if (exportName[0] !== '_') {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.InternalMissingUnderscore,\n `The name \"${exportName}\" should be prefixed with an underscore` +\n ` because the declaration is marked as @internal`,\n astSymbol,\n { exportName }\n );\n }\n }\n }\n }\n\n private static _checkForInconsistentReleaseTags(\n collector: Collector,\n astSymbol: AstSymbol,\n symbolMetadata: SymbolMetadata\n ): void {\n if (astSymbol.isExternal) {\n // For now, don't report errors for external code. If the developer cares about it, they should run\n // API Extractor separately on the external project\n return;\n }\n\n // Normally we will expect all release tags to be the same. Arbitrarily we choose the maxEffectiveReleaseTag\n // as the thing they should all match.\n const expectedEffectiveReleaseTag: ReleaseTag = symbolMetadata.maxEffectiveReleaseTag;\n\n // This is set to true if we find a declaration whose release tag is different from expectedEffectiveReleaseTag\n let mixedReleaseTags: boolean = false;\n\n // This is set to false if we find a declaration that is not a function/method overload\n let onlyFunctionOverloads: boolean = true;\n\n // This is set to true if we find a declaration that is @internal\n let anyInternalReleaseTags: boolean = false;\n\n for (const astDeclaration of astSymbol.astDeclarations) {\n const apiItemMetadata: ApiItemMetadata = collector.fetchApiItemMetadata(astDeclaration);\n const effectiveReleaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;\n\n switch (astDeclaration.declaration.kind) {\n case ts.SyntaxKind.FunctionDeclaration:\n case ts.SyntaxKind.MethodDeclaration:\n break;\n default:\n onlyFunctionOverloads = false;\n }\n\n if (effectiveReleaseTag !== expectedEffectiveReleaseTag) {\n mixedReleaseTags = true;\n }\n\n if (effectiveReleaseTag === ReleaseTag.Internal) {\n anyInternalReleaseTags = true;\n }\n }\n\n if (mixedReleaseTags) {\n if (!onlyFunctionOverloads) {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.DifferentReleaseTags,\n 'This symbol has another declaration with a different release tag',\n astSymbol\n );\n }\n\n if (anyInternalReleaseTags) {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.InternalMixedReleaseTag,\n `Mixed release tags are not allowed for \"${astSymbol.localName}\" because one of its declarations` +\n ` is marked as @internal`,\n astSymbol\n );\n }\n }\n }\n\n private static _checkReferences(\n collector: Collector,\n astDeclaration: AstDeclaration,\n alreadyWarnedEntities: Set<AstEntity>\n ): void {\n const apiItemMetadata: ApiItemMetadata = collector.fetchApiItemMetadata(astDeclaration);\n const declarationReleaseTag: ReleaseTag = apiItemMetadata.effectiveReleaseTag;\n\n for (const referencedEntity of astDeclaration.referencedAstEntities) {\n let collectorEntity: CollectorEntity | undefined;\n let referencedReleaseTag: ReleaseTag;\n let localName: string;\n\n if (referencedEntity instanceof AstSymbol) {\n // If this is e.g. a member of a namespace, then we need to be checking the top-level scope to see\n // whether it's exported.\n //\n // TODO: Technically we should also check each of the nested scopes along the way.\n const rootSymbol: AstSymbol = referencedEntity.rootAstSymbol;\n\n if (rootSymbol.isExternal) {\n continue;\n }\n\n collectorEntity = collector.tryGetCollectorEntity(rootSymbol);\n localName = collectorEntity?.nameForEmit || rootSymbol.localName;\n\n const referencedMetadata: SymbolMetadata = collector.fetchSymbolMetadata(referencedEntity);\n referencedReleaseTag = referencedMetadata.maxEffectiveReleaseTag;\n } else if (referencedEntity instanceof AstNamespaceImport) {\n collectorEntity = collector.tryGetCollectorEntity(referencedEntity);\n\n // TODO: Currently the \"import * as ___ from ___\" syntax does not yet support doc comments\n referencedReleaseTag = ReleaseTag.Public;\n\n localName = collectorEntity?.nameForEmit || referencedEntity.localName;\n } else {\n continue;\n }\n\n if (collectorEntity && collectorEntity.consumable) {\n if (ReleaseTag.compare(declarationReleaseTag, referencedReleaseTag) > 0) {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.IncompatibleReleaseTags,\n `The symbol \"${astDeclaration.astSymbol.localName}\"` +\n ` is marked as ${ReleaseTag.getTagName(declarationReleaseTag)},` +\n ` but its signature references \"${localName}\"` +\n ` which is marked as ${ReleaseTag.getTagName(referencedReleaseTag)}`,\n astDeclaration\n );\n }\n } else {\n const entryPointFilename: string = path.basename(\n collector.workingPackage.entryPointSourceFile.fileName\n );\n\n if (!alreadyWarnedEntities.has(referencedEntity)) {\n alreadyWarnedEntities.add(referencedEntity);\n\n if (\n referencedEntity instanceof AstSymbol &&\n ValidationEnhancer._isEcmaScriptSymbol(referencedEntity)\n ) {\n // The main usage scenario for ECMAScript symbols is to attach private data to a JavaScript object,\n // so as a special case, we do NOT report them as forgotten exports.\n } else {\n collector.messageRouter.addAnalyzerIssue(\n ExtractorMessageId.ForgottenExport,\n `The symbol \"${localName}\" needs to be exported by the entry point ${entryPointFilename}`,\n astDeclaration\n );\n }\n }\n }\n }\n }\n\n // Detect an AstSymbol that refers to an ECMAScript symbol declaration such as:\n //\n // const mySymbol: unique symbol = Symbol('mySymbol');\n private static _isEcmaScriptSymbol(astSymbol: AstSymbol): boolean {\n if (astSymbol.astDeclarations.length !== 1) {\n return false;\n }\n\n // We are matching a form like this:\n //\n // - VariableDeclaration:\n // - Identifier: pre=[mySymbol]\n // - ColonToken: pre=[:] sep=[ ]\n // - TypeOperator:\n // - UniqueKeyword: pre=[unique] sep=[ ]\n // - SymbolKeyword: pre=[symbol]\n const astDeclaration: AstDeclaration = astSymbol.astDeclarations[0];\n if (ts.isVariableDeclaration(astDeclaration.declaration)) {\n const variableTypeNode: ts.TypeNode | undefined = astDeclaration.declaration.type;\n if (variableTypeNode) {\n for (const token of variableTypeNode.getChildren()) {\n if (token.kind === ts.SyntaxKind.SymbolKeyword) {\n return true;\n }\n }\n }\n }\n\n return false;\n }\n}\n"]}