@microsoft/api-extractor 7.29.5 → 7.31.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.
- package/dist/rollup.d.ts +26 -2
- package/lib/analyzer/AstNamespaceImport.d.ts +5 -0
- package/lib/analyzer/AstNamespaceImport.d.ts.map +1 -1
- package/lib/analyzer/AstNamespaceImport.js +1 -0
- package/lib/analyzer/AstNamespaceImport.js.map +1 -1
- package/lib/analyzer/ExportAnalyzer.d.ts.map +1 -1
- package/lib/analyzer/ExportAnalyzer.js +2 -1
- package/lib/analyzer/ExportAnalyzer.js.map +1 -1
- package/lib/api/ExtractorConfig.d.ts +4 -0
- package/lib/api/ExtractorConfig.d.ts.map +1 -1
- package/lib/api/ExtractorConfig.js +8 -0
- package/lib/api/ExtractorConfig.js.map +1 -1
- package/lib/api/ExtractorMessageId.d.ts +1 -1
- package/lib/api/ExtractorMessageId.js.map +1 -1
- package/lib/api/IConfigFile.d.ts +21 -1
- package/lib/api/IConfigFile.d.ts.map +1 -1
- package/lib/api/IConfigFile.js.map +1 -1
- package/lib/collector/Collector.d.ts +7 -1
- package/lib/collector/Collector.d.ts.map +1 -1
- package/lib/collector/Collector.js +57 -32
- package/lib/collector/Collector.js.map +1 -1
- package/lib/collector/CollectorEntity.d.ts +60 -27
- package/lib/collector/CollectorEntity.d.ts.map +1 -1
- package/lib/collector/CollectorEntity.js +91 -28
- package/lib/collector/CollectorEntity.js.map +1 -1
- package/lib/enhancers/DocCommentEnhancer.d.ts.map +1 -1
- package/lib/enhancers/DocCommentEnhancer.js +3 -1
- package/lib/enhancers/DocCommentEnhancer.js.map +1 -1
- package/lib/enhancers/ValidationEnhancer.d.ts.map +1 -1
- package/lib/enhancers/ValidationEnhancer.js +7 -5
- package/lib/enhancers/ValidationEnhancer.js.map +1 -1
- package/lib/generators/ApiModelGenerator.d.ts +1 -1
- package/lib/generators/ApiModelGenerator.d.ts.map +1 -1
- package/lib/generators/ApiModelGenerator.js +100 -75
- package/lib/generators/ApiModelGenerator.js.map +1 -1
- package/lib/generators/ApiReportGenerator.js +2 -2
- package/lib/generators/ApiReportGenerator.js.map +1 -1
- package/lib/generators/DeclarationReferenceGenerator.d.ts +4 -8
- package/lib/generators/DeclarationReferenceGenerator.d.ts.map +1 -1
- package/lib/generators/DeclarationReferenceGenerator.js +77 -70
- package/lib/generators/DeclarationReferenceGenerator.js.map +1 -1
- package/lib/schemas/api-extractor-defaults.json +4 -2
- package/lib/schemas/api-extractor-template.json +24 -5
- package/lib/schemas/api-extractor.schema.json +11 -1
- package/package.json +3 -4
|
@@ -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
|
|
54
|
-
* Collector._makeUniqueNames
|
|
55
|
-
*
|
|
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
|
-
*
|
|
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,94 @@ class CollectorEntity {
|
|
|
104
104
|
return false;
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
107
|
-
*
|
|
107
|
+
* Indicates that this entity is exported from the package entry point. Compare to `CollectorEntity.exported`.
|
|
108
108
|
*/
|
|
109
|
-
get
|
|
109
|
+
get exportedFromEntryPoint() {
|
|
110
110
|
return this.exportNames.size > 0;
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
|
-
* Indicates that
|
|
114
|
-
*
|
|
115
|
-
* then API Extractor will report a ExtractorMessageId.ForgottenExport warning.
|
|
113
|
+
* Indicates that this entity is exported from its parent module (i.e. either the package entry point or
|
|
114
|
+
* a local namespace). Compare to `CollectorEntity.consumable`.
|
|
116
115
|
*
|
|
117
116
|
* @remarks
|
|
118
|
-
*
|
|
117
|
+
* In the example below:
|
|
119
118
|
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
119
|
+
* ```ts
|
|
120
|
+
* declare function add(): void;
|
|
121
|
+
* declare namespace calculator {
|
|
122
|
+
* export {
|
|
123
|
+
* add
|
|
124
|
+
* }
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
122
127
|
*
|
|
123
|
-
*
|
|
128
|
+
* Namespace `calculator` is neither exported nor consumable, function `add` is exported (from `calculator`)
|
|
129
|
+
* but not consumable.
|
|
130
|
+
*/
|
|
131
|
+
get exported() {
|
|
132
|
+
// Exported from top-level?
|
|
133
|
+
if (this.exportedFromEntryPoint)
|
|
134
|
+
return true;
|
|
135
|
+
// Exported from parent?
|
|
136
|
+
for (const localExportNames of this._localExportNamesByParent.values()) {
|
|
137
|
+
if (localExportNames.size > 0) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Indicates that it is possible for a consumer of the API to "consume" this entity, either by importing
|
|
145
|
+
* it directly or via a namespace. If an entity is not consumable, then API Extractor will report an
|
|
146
|
+
* `ae-forgotten-export` warning. Compare to `CollectorEntity.exported`.
|
|
124
147
|
*
|
|
125
|
-
*
|
|
148
|
+
* @remarks
|
|
149
|
+
* An API item is consumable if:
|
|
126
150
|
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
151
|
+
* 1. It is exported from the top-level entry point OR
|
|
152
|
+
* 2. It is exported from a consumable parent entity.
|
|
129
153
|
*
|
|
130
|
-
*
|
|
154
|
+
* For an example of #2, consider how `AstNamespaceImport` entities are processed. A generated rollup.d.ts
|
|
155
|
+
* might look like this:
|
|
131
156
|
*
|
|
132
|
-
*
|
|
157
|
+
* ```ts
|
|
158
|
+
* declare function add(): void;
|
|
159
|
+
* declare namespace calculator {
|
|
133
160
|
* export {
|
|
134
|
-
*
|
|
161
|
+
* add
|
|
135
162
|
* }
|
|
136
163
|
* }
|
|
137
|
-
* export {
|
|
164
|
+
* export { calculator }
|
|
138
165
|
* ```
|
|
139
166
|
*
|
|
140
|
-
* In this example, `
|
|
141
|
-
* even though `member()` itself is not exported.
|
|
167
|
+
* In this example, `add` is exported via the consumable `calculator` namespace.
|
|
142
168
|
*/
|
|
143
169
|
get consumable() {
|
|
144
|
-
|
|
170
|
+
// Exported from top-level?
|
|
171
|
+
if (this.exportedFromEntryPoint)
|
|
172
|
+
return true;
|
|
173
|
+
// Exported from consumable parent?
|
|
174
|
+
for (const [parent, localExportNames] of this._localExportNamesByParent) {
|
|
175
|
+
if (localExportNames.size > 0 && parent.consumable) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return false;
|
|
145
180
|
}
|
|
146
181
|
/**
|
|
147
|
-
*
|
|
182
|
+
* Return the first consumable parent that exports this entity. If there is none, returns
|
|
183
|
+
* `undefined`.
|
|
148
184
|
*/
|
|
149
|
-
|
|
150
|
-
this.
|
|
185
|
+
getFirstExportingConsumableParent() {
|
|
186
|
+
for (const [parent, localExportNames] of this._localExportNamesByParent) {
|
|
187
|
+
if (parent.consumable && localExportNames.size > 0) {
|
|
188
|
+
return parent;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return undefined;
|
|
151
192
|
}
|
|
152
193
|
/**
|
|
153
|
-
* Adds a new
|
|
194
|
+
* Adds a new export name to the entity.
|
|
154
195
|
*/
|
|
155
196
|
addExportName(exportName) {
|
|
156
197
|
if (!this._exportNames.has(exportName)) {
|
|
@@ -164,6 +205,28 @@ class CollectorEntity {
|
|
|
164
205
|
}
|
|
165
206
|
}
|
|
166
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Adds a new local export name to the entity.
|
|
210
|
+
*
|
|
211
|
+
* @remarks
|
|
212
|
+
* In the example below:
|
|
213
|
+
*
|
|
214
|
+
* ```ts
|
|
215
|
+
* declare function add(): void;
|
|
216
|
+
* declare namespace calculator {
|
|
217
|
+
* export {
|
|
218
|
+
* add
|
|
219
|
+
* }
|
|
220
|
+
* }
|
|
221
|
+
* ```
|
|
222
|
+
*
|
|
223
|
+
* `add` is the local export name for the `CollectorEntity` for `add`.
|
|
224
|
+
*/
|
|
225
|
+
addLocalExportName(localExportName, parent) {
|
|
226
|
+
const localExportNames = this._localExportNamesByParent.get(parent) || new Set();
|
|
227
|
+
localExportNames.add(localExportName);
|
|
228
|
+
this._localExportNamesByParent.set(parent, localExportNames);
|
|
229
|
+
}
|
|
167
230
|
/**
|
|
168
231
|
* A sorting key used by DtsRollupGenerator._makeUniqueNames()
|
|
169
232
|
*/
|
|
@@ -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 the package entry point. Compare to `CollectorEntity.exported`.\n */\n public get exportedFromEntryPoint(): boolean {\n return this.exportNames.size > 0;\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.exportedFromEntryPoint) 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.exportedFromEntryPoint) 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 * Return the first consumable parent that exports this entity. If there is none, returns\n * `undefined`.\n */\n public getFirstExportingConsumableParent(): CollectorEntity | undefined {\n for (const [parent, localExportNames] of this._localExportNamesByParent) {\n if (parent.consumable && localExportNames.size > 0) {\n return parent;\n }\n }\n return undefined;\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;
|
|
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;
|
|
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
|
|
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 "${
|
|
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":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D,2CAA6B;AAC7B,+CAAiC;AAGjC,qDAAkD;AAMlD,wEAA4D;AAC5D,uEAAoE;AAIpE,MAAa,kBAAkB;IACtB,MAAM,CAAC,OAAO,CAAC,SAAoB;QACxC,MAAM,qBAAqB,GAAmB,IAAI,GAAG,EAAa,CAAC;QAEnE,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,QAAQ,EAAE;YACvC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;gBACtB,SAAS;aACV;YAED,IAAI,MAAM,CAAC,SAAS,YAAY,qBAAS,EAAE;gBACzC,+BAA+B;gBAE/B,MAAM,SAAS,GAAc,MAAM,CAAC,SAAS,CAAC;gBAE9C,SAAS,CAAC,2BAA2B,CAAC,CAAC,cAA8B,EAAE,EAAE;oBACvE,kBAAkB,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,qBAAqB,CAAC,CAAC;gBACxF,CAAC,CAAC,CAAC;gBAEH,MAAM,cAAc,GAAmB,SAAS,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;gBAChF,kBAAkB,CAAC,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;gBAC7F,kBAAkB,CAAC,gCAAgC,CAAC,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;aAC3F;iBAAM,IAAI,MAAM,CAAC,SAAS,YAAY,uCAAkB,EAAE;gBACzD,uDAAuD;gBACvD,MAAM,kBAAkB,GAAuB,MAAM,CAAC,SAAS,CAAC;gBAEhE,MAAM,mBAAmB,GACvB,kBAAkB,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;gBAEzD,KAAK,MAAM,wBAAwB,IAAI,mBAAmB,CAAC,qBAAqB,CAAC,MAAM,EAAE,EAAE;oBACzF,IAAI,wBAAwB,YAAY,qBAAS,EAAE;wBACjD,MAAM,SAAS,GAAc,wBAAwB,CAAC;wBAEtD,SAAS,CAAC,2BAA2B,CAAC,CAAC,cAA8B,EAAE,EAAE;4BACvE,kBAAkB,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,qBAAqB,CAAC,CAAC;wBACxF,CAAC,CAAC,CAAC;wBAEH,MAAM,cAAc,GAAmB,SAAS,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;wBAEhF,gGAAgG;wBAEhG,kBAAkB,CAAC,gCAAgC,CAAC,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;qBAC3F;iBACF;aACF;SACF;IACH,CAAC;IAEO,MAAM,CAAC,2BAA2B,CACxC,SAAoB,EACpB,eAAgC,EAChC,SAAoB,EACpB,cAA8B;QAE9B,IAAI,eAAe,GAAY,KAAK,CAAC;QAErC,IAAI,cAAc,CAAC,sBAAsB,KAAK,gCAAU,CAAC,QAAQ,EAAE;YACjE,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE;gBAC9B,+EAA+E;gBAC/E,+GAA+G;gBAC/G,EAAE;gBACF,mBAAmB;gBACnB,sBAAsB;gBACtB,EAAE;gBACF,qBAAqB;gBACrB,2BAA2B;gBAC3B,EAAE;gBACF,iGAAiG;gBACjG,eAAe,GAAG,IAAI,CAAC;aACxB;iBAAM;gBACL,6GAA6G;gBAC7G,EAAE;gBACF,+EAA+E;gBAC/E,EAAE;gBACF,qBAAqB;gBACrB,yBAAyB;gBACzB,8BAA8B;gBAC9B,MAAM;gBACN,EAAE;gBACF,mBAAmB;gBACnB,qBAAqB;gBACrB,uBAAuB;gBACvB,oEAAoE;gBACpE,MAAM;gBACN,MAAM,oBAAoB,GAAmB,SAAS,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;gBACtF,IAAI,oBAAoB,CAAC,sBAAsB,GAAG,gCAAU,CAAC,QAAQ,EAAE;oBACrE,eAAe,GAAG,IAAI,CAAC;iBACxB;aACF;SACF;QAED,IAAI,eAAe,EAAE;YACnB,KAAK,MAAM,UAAU,IAAI,eAAe,CAAC,WAAW,EAAE;gBACpD,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;oBACzB,SAAS,CAAC,aAAa,CAAC,gBAAgB,sFAEtC,aAAa,UAAU,yCAAyC;wBAC9D,iDAAiD,EACnD,SAAS,EACT,EAAE,UAAU,EAAE,CACf,CAAC;iBACH;aACF;SACF;IACH,CAAC;IAEO,MAAM,CAAC,gCAAgC,CAC7C,SAAoB,EACpB,SAAoB,EACpB,cAA8B;QAE9B,IAAI,SAAS,CAAC,UAAU,EAAE;YACxB,oGAAoG;YACpG,mDAAmD;YACnD,OAAO;SACR;QAED,6GAA6G;QAC7G,sCAAsC;QACtC,MAAM,2BAA2B,GAAe,cAAc,CAAC,sBAAsB,CAAC;QAEtF,+GAA+G;QAC/G,IAAI,gBAAgB,GAAY,KAAK,CAAC;QAEtC,uFAAuF;QACvF,IAAI,qBAAqB,GAAY,IAAI,CAAC;QAE1C,iEAAiE;QACjE,IAAI,sBAAsB,GAAY,KAAK,CAAC;QAE5C,KAAK,MAAM,cAAc,IAAI,SAAS,CAAC,eAAe,EAAE;YACtD,MAAM,eAAe,GAAoB,SAAS,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;YACxF,MAAM,mBAAmB,GAAe,eAAe,CAAC,mBAAmB,CAAC;YAE5E,QAAQ,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE;gBACvC,KAAK,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC;gBACvC,KAAK,EAAE,CAAC,UAAU,CAAC,iBAAiB;oBAClC,MAAM;gBACR;oBACE,qBAAqB,GAAG,KAAK,CAAC;aACjC;YAED,IAAI,mBAAmB,KAAK,2BAA2B,EAAE;gBACvD,gBAAgB,GAAG,IAAI,CAAC;aACzB;YAED,IAAI,mBAAmB,KAAK,gCAAU,CAAC,QAAQ,EAAE;gBAC/C,sBAAsB,GAAG,IAAI,CAAC;aAC/B;SACF;QAED,IAAI,gBAAgB,EAAE;YACpB,IAAI,CAAC,qBAAqB,EAAE;gBAC1B,SAAS,CAAC,aAAa,CAAC,gBAAgB,4EAEtC,kEAAkE,EAClE,SAAS,CACV,CAAC;aACH;YAED,IAAI,sBAAsB,EAAE;gBAC1B,SAAS,CAAC,aAAa,CAAC,gBAAgB,mFAEtC,2CAA2C,SAAS,CAAC,SAAS,mCAAmC;oBAC/F,yBAAyB,EAC3B,SAAS,CACV,CAAC;aACH;SACF;IACH,CAAC;IAEO,MAAM,CAAC,gBAAgB,CAC7B,SAAoB,EACpB,cAA8B,EAC9B,qBAAqC;QAErC,MAAM,eAAe,GAAoB,SAAS,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACxF,MAAM,qBAAqB,GAAe,eAAe,CAAC,mBAAmB,CAAC;QAE9E,KAAK,MAAM,gBAAgB,IAAI,cAAc,CAAC,qBAAqB,EAAE;YACnE,IAAI,eAA4C,CAAC;YACjD,IAAI,oBAAgC,CAAC;YACrC,IAAI,SAAiB,CAAC;YAEtB,IAAI,gBAAgB,YAAY,qBAAS,EAAE;gBACzC,kGAAkG;gBAClG,yBAAyB;gBACzB,EAAE;gBACF,kFAAkF;gBAClF,MAAM,UAAU,GAAc,gBAAgB,CAAC,aAAa,CAAC;gBAE7D,IAAI,UAAU,CAAC,UAAU,EAAE;oBACzB,SAAS;iBACV;gBAED,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC;gBAEjC,eAAe,GAAG,SAAS,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;gBAE9D,MAAM,kBAAkB,GAAmB,SAAS,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;gBAC3F,oBAAoB,GAAG,kBAAkB,CAAC,sBAAsB,CAAC;aAClE;iBAAM,IAAI,gBAAgB,YAAY,uCAAkB,EAAE;gBACzD,eAAe,GAAG,SAAS,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;gBAEpE,0FAA0F;gBAC1F,oBAAoB,GAAG,gCAAU,CAAC,MAAM,CAAC;gBAEzC,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC;aACxC;iBAAM;gBACL,SAAS;aACV;YAED,IAAI,eAAe,IAAI,eAAe,CAAC,UAAU,EAAE;gBACjD,IAAI,gCAAU,CAAC,OAAO,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,GAAG,CAAC,EAAE;oBACvE,SAAS,CAAC,aAAa,CAAC,gBAAgB,kFAEtC,eAAe,cAAc,CAAC,SAAS,CAAC,SAAS,GAAG;wBAClD,iBAAiB,gCAAU,CAAC,UAAU,CAAC,qBAAqB,CAAC,GAAG;wBAChE,kCAAkC,gBAAgB,CAAC,SAAS,GAAG;wBAC/D,uBAAuB,gCAAU,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,EACtE,cAAc,CACf,CAAC;iBACH;aACF;iBAAM;gBACL,MAAM,kBAAkB,GAAW,IAAI,CAAC,QAAQ,CAC9C,SAAS,CAAC,cAAc,CAAC,oBAAoB,CAAC,QAAQ,CACvD,CAAC;gBAEF,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE;oBAChD,qBAAqB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;oBAE5C,IACE,gBAAgB,YAAY,qBAAS;wBACrC,kBAAkB,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EACxD;wBACA,mGAAmG;wBACnG,oEAAoE;qBACrE;yBAAM;wBACL,SAAS,CAAC,aAAa,CAAC,gBAAgB,iEAEtC,eAAe,SAAS,6CAA6C,kBAAkB,EAAE,EACzF,cAAc,CACf,CAAC;qBACH;iBACF;aACF;SACF;IACH,CAAC;IAED,+EAA+E;IAC/E,EAAE;IACF,sDAAsD;IAC9C,MAAM,CAAC,mBAAmB,CAAC,SAAoB;QACrD,IAAI,SAAS,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;YAC1C,OAAO,KAAK,CAAC;SACd;QAED,oCAAoC;QACpC,EAAE;QACF,yBAAyB;QACzB,kCAAkC;QAClC,mCAAmC;QACnC,oBAAoB;QACpB,6CAA6C;QAC7C,qCAAqC;QACrC,MAAM,cAAc,GAAmB,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACpE,IAAI,EAAE,CAAC,qBAAqB,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE;YACxD,MAAM,gBAAgB,GAA4B,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC;YAClF,IAAI,gBAAgB,EAAE;gBACpB,KAAK,MAAM,KAAK,IAAI,gBAAgB,CAAC,WAAW,EAAE,EAAE;oBAClD,IAAI,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE;wBAC9C,OAAO,IAAI,CAAC;qBACb;iBACF;aACF;SACF;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAtRD,gDAsRC","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"]}
|
|
@@ -8,7 +8,7 @@ export declare class ApiModelGenerator {
|
|
|
8
8
|
get apiModel(): ApiModel;
|
|
9
9
|
buildApiPackage(): ApiPackage;
|
|
10
10
|
private _processAstEntity;
|
|
11
|
-
private
|
|
11
|
+
private _processAstNamespaceImport;
|
|
12
12
|
private _processDeclaration;
|
|
13
13
|
private _processChildDeclarations;
|
|
14
14
|
private _processApiCallSignature;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiModelGenerator.d.ts","sourceRoot":"","sources":["../../src/generators/ApiModelGenerator.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,QAAQ,EAER,UAAU,EAwBX,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"ApiModelGenerator.d.ts","sourceRoot":"","sources":["../../src/generators/ApiModelGenerator.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,QAAQ,EAER,UAAU,EAwBX,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAkBnD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAgC;gBAEjD,SAAS,EAAE,SAAS;IAMvC,IAAW,QAAQ,IAAI,QAAQ,CAE9B;IAEM,eAAe,IAAI,UAAU;IA6BpC,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,0BAA0B;IAkClC,OAAO,CAAC,mBAAmB;IAyF3B,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,wBAAwB;IA+ChC,OAAO,CAAC,sBAAsB;IAuC9B,OAAO,CAAC,gBAAgB;IA2DxB,OAAO,CAAC,6BAA6B;IAkDrC,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,qBAAqB;IAoC7B,OAAO,CAAC,mBAAmB;IAgD3B,OAAO,CAAC,yBAAyB;IA2CjC,OAAO,CAAC,oBAAoB;IAuD5B,OAAO,CAAC,iBAAiB;IAuDzB,OAAO,CAAC,0BAA0B;IAqDlC,OAAO,CAAC,oBAAoB;IAwB5B,OAAO,CAAC,mBAAmB;IA2D3B,OAAO,CAAC,4BAA4B;IA4CpC,OAAO,CAAC,oBAAoB;IA0C5B,OAAO,CAAC,mBAAmB;IA2C3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,sBAAsB;IAuB9B,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,WAAW;CA8BpB"}
|