1 | "use strict";
|
2 |
|
3 |
|
4 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
5 | if (k2 === undefined) k2 = k;
|
6 | var desc = Object.getOwnPropertyDescriptor(m, k);
|
7 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
8 | desc = { enumerable: true, get: function() { return m[k]; } };
|
9 | }
|
10 | Object.defineProperty(o, k2, desc);
|
11 | }) : (function(o, m, k, k2) {
|
12 | if (k2 === undefined) k2 = k;
|
13 | o[k2] = m[k];
|
14 | }));
|
15 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
16 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
17 | }) : function(o, v) {
|
18 | o["default"] = v;
|
19 | });
|
20 | var __importStar = (this && this.__importStar) || function (mod) {
|
21 | if (mod && mod.__esModule) return mod;
|
22 | var result = {};
|
23 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
24 | __setModuleDefault(result, mod);
|
25 | return result;
|
26 | };
|
27 | Object.defineProperty(exports, "__esModule", { value: true });
|
28 | exports.Collector = void 0;
|
29 | const ts = __importStar(require("typescript"));
|
30 | const tsdoc = __importStar(require("@microsoft/tsdoc"));
|
31 | const node_core_library_1 = require("@rushstack/node-core-library");
|
32 | const api_extractor_model_1 = require("@microsoft/api-extractor-model");
|
33 | const CollectorEntity_1 = require("./CollectorEntity");
|
34 | const AstSymbolTable_1 = require("../analyzer/AstSymbolTable");
|
35 | const AstSymbol_1 = require("../analyzer/AstSymbol");
|
36 | const TypeScriptHelpers_1 = require("../analyzer/TypeScriptHelpers");
|
37 | const WorkingPackage_1 = require("./WorkingPackage");
|
38 | const PackageDocComment_1 = require("../aedoc/PackageDocComment");
|
39 | const DeclarationMetadata_1 = require("./DeclarationMetadata");
|
40 | const ApiItemMetadata_1 = require("./ApiItemMetadata");
|
41 | const SymbolMetadata_1 = require("./SymbolMetadata");
|
42 | const TypeScriptInternals_1 = require("../analyzer/TypeScriptInternals");
|
43 | const AstReferenceResolver_1 = require("../analyzer/AstReferenceResolver");
|
44 | const ExtractorConfig_1 = require("../api/ExtractorConfig");
|
45 | const AstNamespaceImport_1 = require("../analyzer/AstNamespaceImport");
|
46 | const AstImport_1 = require("../analyzer/AstImport");
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | class Collector {
|
54 | constructor(options) {
|
55 | this._entities = [];
|
56 | this._entitiesByAstEntity = new Map();
|
57 | this._starExportedExternalModulePaths = [];
|
58 | this._dtsTypeReferenceDirectives = new Set();
|
59 | this._dtsLibReferenceDirectives = new Set();
|
60 | this.packageJsonLookup = new node_core_library_1.PackageJsonLookup();
|
61 | this._program = options.program;
|
62 | this.extractorConfig = options.extractorConfig;
|
63 | const entryPointSourceFile = options.program.getSourceFile(this.extractorConfig.mainEntryPointFilePath);
|
64 | if (!entryPointSourceFile) {
|
65 | throw new Error('Unable to load file: ' + this.extractorConfig.mainEntryPointFilePath);
|
66 | }
|
67 | if (!this.extractorConfig.packageFolder || !this.extractorConfig.packageJson) {
|
68 |
|
69 |
|
70 | throw new Error('Unable to find a package.json file for the project being analyzed');
|
71 | }
|
72 | this.workingPackage = new WorkingPackage_1.WorkingPackage({
|
73 | packageFolder: this.extractorConfig.packageFolder,
|
74 | packageJson: this.extractorConfig.packageJson,
|
75 | entryPointSourceFile
|
76 | });
|
77 | this.messageRouter = options.messageRouter;
|
78 | this.program = options.program;
|
79 | this.typeChecker = options.program.getTypeChecker();
|
80 | this.globalVariableAnalyzer = TypeScriptInternals_1.TypeScriptInternals.getGlobalVariableAnalyzer(this.program);
|
81 | this._tsdocParser = new tsdoc.TSDocParser(this.extractorConfig.tsdocConfiguration);
|
82 | this.bundledPackageNames = new Set(this.extractorConfig.bundledPackages);
|
83 | this.astSymbolTable = new AstSymbolTable_1.AstSymbolTable(this.program, this.typeChecker, this.packageJsonLookup, this.bundledPackageNames, this.messageRouter);
|
84 | this.astReferenceResolver = new AstReferenceResolver_1.AstReferenceResolver(this);
|
85 | this._cachedOverloadIndexesByDeclaration = new Map();
|
86 | }
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 | get dtsTypeReferenceDirectives() {
|
95 | return this._dtsTypeReferenceDirectives;
|
96 | }
|
97 | |
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 | get dtsLibReferenceDirectives() {
|
105 | return this._dtsLibReferenceDirectives;
|
106 | }
|
107 | get entities() {
|
108 | return this._entities;
|
109 | }
|
110 | |
111 |
|
112 |
|
113 |
|
114 | get starExportedExternalModulePaths() {
|
115 | return this._starExportedExternalModulePaths;
|
116 | }
|
117 | |
118 |
|
119 |
|
120 | analyze() {
|
121 | if (this._astEntryPoint) {
|
122 | throw new Error('DtsRollupGenerator.analyze() was already called');
|
123 | }
|
124 |
|
125 |
|
126 |
|
127 | for (const diagnostic of this._program.getSemanticDiagnostics()) {
|
128 | this.messageRouter.addCompilerDiagnostic(diagnostic);
|
129 | }
|
130 | const sourceFiles = this.program.getSourceFiles();
|
131 | if (this.messageRouter.showDiagnostics) {
|
132 | this.messageRouter.logDiagnosticHeader('Root filenames');
|
133 | for (const fileName of this.program.getRootFileNames()) {
|
134 | this.messageRouter.logDiagnostic(fileName);
|
135 | }
|
136 | this.messageRouter.logDiagnosticFooter();
|
137 | this.messageRouter.logDiagnosticHeader('Files analyzed by compiler');
|
138 | for (const sourceFile of sourceFiles) {
|
139 | this.messageRouter.logDiagnostic(sourceFile.fileName);
|
140 | }
|
141 | this.messageRouter.logDiagnosticFooter();
|
142 | }
|
143 |
|
144 |
|
145 |
|
146 | const badSourceFile = sourceFiles.find(({ fileName }) => !ExtractorConfig_1.ExtractorConfig.hasDtsFileExtension(fileName));
|
147 | if (badSourceFile) {
|
148 | this.messageRouter.addAnalyzerIssueForPosition("ae-wrong-input-file-type" , 'Incorrect file type; API Extractor expects to analyze compiler outputs with the .d.ts file extension. ' +
|
149 | 'Troubleshooting tips: https://api-extractor.com/link/dts-error', badSourceFile, 0);
|
150 | }
|
151 |
|
152 | const entryPointSourceFile = this.workingPackage.entryPointSourceFile;
|
153 | const astEntryPoint = this.astSymbolTable.fetchAstModuleFromWorkingPackage(entryPointSourceFile);
|
154 | this._astEntryPoint = astEntryPoint;
|
155 | const packageDocCommentTextRange = PackageDocComment_1.PackageDocComment.tryFindInSourceFile(entryPointSourceFile, this);
|
156 | if (packageDocCommentTextRange) {
|
157 | const range = tsdoc.TextRange.fromStringRange(entryPointSourceFile.text, packageDocCommentTextRange.pos, packageDocCommentTextRange.end);
|
158 | this.workingPackage.tsdocParserContext = this._tsdocParser.parseRange(range);
|
159 | this.messageRouter.addTsdocMessages(this.workingPackage.tsdocParserContext, entryPointSourceFile);
|
160 | this.workingPackage.tsdocComment = this.workingPackage.tsdocParserContext.docComment;
|
161 | }
|
162 | const exportedAstEntities = [];
|
163 |
|
164 | const astModuleExportInfo = this.astSymbolTable.fetchAstModuleExportInfo(astEntryPoint);
|
165 | for (const [exportName, astEntity] of astModuleExportInfo.exportedLocalEntities) {
|
166 | this._createCollectorEntity(astEntity, exportName);
|
167 | exportedAstEntities.push(astEntity);
|
168 | }
|
169 |
|
170 |
|
171 |
|
172 | const alreadySeenAstSymbols = new Set();
|
173 | for (const exportedAstEntity of exportedAstEntities) {
|
174 | this._createEntityForIndirectReferences(exportedAstEntity, alreadySeenAstSymbols);
|
175 | if (exportedAstEntity instanceof AstSymbol_1.AstSymbol) {
|
176 | this.fetchSymbolMetadata(exportedAstEntity);
|
177 | }
|
178 | }
|
179 | this._makeUniqueNames();
|
180 | for (const starExportedExternalModule of astModuleExportInfo.starExportedExternalModules) {
|
181 | if (starExportedExternalModule.externalModulePath !== undefined) {
|
182 | this._starExportedExternalModulePaths.push(starExportedExternalModule.externalModulePath);
|
183 | }
|
184 | }
|
185 | node_core_library_1.Sort.sortBy(this._entities, (x) => x.getSortKey());
|
186 | node_core_library_1.Sort.sortSet(this._dtsTypeReferenceDirectives);
|
187 | node_core_library_1.Sort.sortSet(this._dtsLibReferenceDirectives);
|
188 | this._starExportedExternalModulePaths.sort();
|
189 | }
|
190 | |
191 |
|
192 |
|
193 |
|
194 |
|
195 |
|
196 | tryGetEntityForNode(identifier) {
|
197 | const astEntity = this.astSymbolTable.tryGetEntityForNode(identifier);
|
198 | if (astEntity) {
|
199 | return this._entitiesByAstEntity.get(astEntity);
|
200 | }
|
201 | return undefined;
|
202 | }
|
203 | |
204 |
|
205 |
|
206 | tryGetCollectorEntity(astEntity) {
|
207 | return this._entitiesByAstEntity.get(astEntity);
|
208 | }
|
209 | fetchSymbolMetadata(astSymbol) {
|
210 | if (astSymbol.symbolMetadata === undefined) {
|
211 | this._fetchSymbolMetadata(astSymbol);
|
212 | }
|
213 | return astSymbol.symbolMetadata;
|
214 | }
|
215 | fetchDeclarationMetadata(astDeclaration) {
|
216 | if (astDeclaration.declarationMetadata === undefined) {
|
217 |
|
218 | this._fetchSymbolMetadata(astDeclaration.astSymbol);
|
219 | }
|
220 | return astDeclaration.declarationMetadata;
|
221 | }
|
222 | fetchApiItemMetadata(astDeclaration) {
|
223 | if (astDeclaration.apiItemMetadata === undefined) {
|
224 |
|
225 | this._fetchSymbolMetadata(astDeclaration.astSymbol);
|
226 | }
|
227 | return astDeclaration.apiItemMetadata;
|
228 | }
|
229 | tryFetchMetadataForAstEntity(astEntity) {
|
230 | if (astEntity instanceof AstSymbol_1.AstSymbol) {
|
231 | return this.fetchSymbolMetadata(astEntity);
|
232 | }
|
233 | if (astEntity instanceof AstImport_1.AstImport) {
|
234 | if (astEntity.astSymbol) {
|
235 | return this.fetchSymbolMetadata(astEntity.astSymbol);
|
236 | }
|
237 | }
|
238 | return undefined;
|
239 | }
|
240 | isAncillaryDeclaration(astDeclaration) {
|
241 | const declarationMetadata = this.fetchDeclarationMetadata(astDeclaration);
|
242 | return declarationMetadata.isAncillary;
|
243 | }
|
244 | getNonAncillaryDeclarations(astSymbol) {
|
245 | const result = [];
|
246 | for (const astDeclaration of astSymbol.astDeclarations) {
|
247 | const declarationMetadata = this.fetchDeclarationMetadata(astDeclaration);
|
248 | if (!declarationMetadata.isAncillary) {
|
249 | result.push(astDeclaration);
|
250 | }
|
251 | }
|
252 | return result;
|
253 | }
|
254 | |
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 |
|
262 | static getSortKeyIgnoringUnderscore(identifier) {
|
263 | if (!identifier)
|
264 | return '';
|
265 | let parts;
|
266 | if (identifier[0] === '_') {
|
267 | const withoutUnderscore = identifier.substr(1);
|
268 | parts = [withoutUnderscore.toLowerCase(), '*', withoutUnderscore, '*', '_'];
|
269 | }
|
270 | else {
|
271 | parts = [identifier.toLowerCase(), '*', identifier];
|
272 | }
|
273 | return parts.join('');
|
274 | }
|
275 | |
276 |
|
277 |
|
278 |
|
279 | getOverloadIndex(astDeclaration) {
|
280 | const allDeclarations = astDeclaration.astSymbol.astDeclarations;
|
281 | if (allDeclarations.length === 1) {
|
282 | return 1;
|
283 | }
|
284 | let overloadIndex = this._cachedOverloadIndexesByDeclaration.get(astDeclaration);
|
285 | if (overloadIndex === undefined) {
|
286 |
|
287 | let nextIndex = 1;
|
288 | for (const other of allDeclarations) {
|
289 |
|
290 |
|
291 | if (other.declaration.kind === astDeclaration.declaration.kind) {
|
292 | this._cachedOverloadIndexesByDeclaration.set(other, nextIndex);
|
293 | ++nextIndex;
|
294 | }
|
295 | }
|
296 | overloadIndex = this._cachedOverloadIndexesByDeclaration.get(astDeclaration);
|
297 | }
|
298 | if (overloadIndex === undefined) {
|
299 |
|
300 | throw new node_core_library_1.InternalError('Error calculating overload index for declaration');
|
301 | }
|
302 | return overloadIndex;
|
303 | }
|
304 | _createCollectorEntity(astEntity, exportedName) {
|
305 | let entity = this._entitiesByAstEntity.get(astEntity);
|
306 | if (!entity) {
|
307 | entity = new CollectorEntity_1.CollectorEntity(astEntity);
|
308 | this._entitiesByAstEntity.set(astEntity, entity);
|
309 | this._entities.push(entity);
|
310 | this._collectReferenceDirectives(astEntity);
|
311 | }
|
312 | if (exportedName) {
|
313 | entity.addExportName(exportedName);
|
314 | }
|
315 | return entity;
|
316 | }
|
317 | _createEntityForIndirectReferences(astEntity, alreadySeenAstEntities) {
|
318 | if (alreadySeenAstEntities.has(astEntity)) {
|
319 | return;
|
320 | }
|
321 | alreadySeenAstEntities.add(astEntity);
|
322 | if (astEntity instanceof AstSymbol_1.AstSymbol) {
|
323 | astEntity.forEachDeclarationRecursive((astDeclaration) => {
|
324 | for (const referencedAstEntity of astDeclaration.referencedAstEntities) {
|
325 | if (referencedAstEntity instanceof AstSymbol_1.AstSymbol) {
|
326 |
|
327 |
|
328 |
|
329 | if (referencedAstEntity.parentAstSymbol === undefined) {
|
330 | this._createCollectorEntity(referencedAstEntity, undefined);
|
331 | }
|
332 | }
|
333 | else {
|
334 | this._createCollectorEntity(referencedAstEntity, undefined);
|
335 | }
|
336 | this._createEntityForIndirectReferences(referencedAstEntity, alreadySeenAstEntities);
|
337 | }
|
338 | });
|
339 | }
|
340 | if (astEntity instanceof AstNamespaceImport_1.AstNamespaceImport) {
|
341 | const astModuleExportInfo = astEntity.fetchAstModuleExportInfo(this);
|
342 | for (const exportedEntity of astModuleExportInfo.exportedLocalEntities.values()) {
|
343 |
|
344 | const entity = this._createCollectorEntity(exportedEntity, undefined);
|
345 | entity.addAstNamespaceImports(astEntity);
|
346 | this._createEntityForIndirectReferences(exportedEntity, alreadySeenAstEntities);
|
347 | }
|
348 | }
|
349 | }
|
350 | |
351 |
|
352 |
|
353 | _makeUniqueNames() {
|
354 |
|
355 |
|
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 | const usedNames = new Set();
|
373 |
|
374 | for (const entity of this._entities) {
|
375 | for (const exportName of entity.exportNames) {
|
376 | if (usedNames.has(exportName)) {
|
377 |
|
378 | throw new node_core_library_1.InternalError(`A package cannot have two exports with the name "${exportName}"`);
|
379 | }
|
380 | usedNames.add(exportName);
|
381 | }
|
382 | }
|
383 |
|
384 | for (const entity of this._entities) {
|
385 |
|
386 | let idealNameForEmit;
|
387 |
|
388 | if (entity.singleExportName !== undefined &&
|
389 | entity.singleExportName !== ts.InternalSymbolName.Default) {
|
390 | idealNameForEmit = entity.singleExportName;
|
391 | }
|
392 | else {
|
393 |
|
394 | idealNameForEmit = entity.astEntity.localName;
|
395 | }
|
396 | if (idealNameForEmit.includes('.')) {
|
397 |
|
398 | idealNameForEmit = idealNameForEmit.split('.')[0];
|
399 | }
|
400 |
|
401 | if (entity.exportNames.has(idealNameForEmit)) {
|
402 |
|
403 | if (!this.globalVariableAnalyzer.hasGlobalName(idealNameForEmit)) {
|
404 |
|
405 | if (idealNameForEmit !== 'default') {
|
406 | entity.nameForEmit = idealNameForEmit;
|
407 | continue;
|
408 | }
|
409 | }
|
410 | }
|
411 |
|
412 | let suffix = 1;
|
413 | let nameForEmit = idealNameForEmit;
|
414 |
|
415 | while (nameForEmit === 'default' ||
|
416 | usedNames.has(nameForEmit) ||
|
417 | this.globalVariableAnalyzer.hasGlobalName(nameForEmit)) {
|
418 | nameForEmit = `${idealNameForEmit}_${++suffix}`;
|
419 | }
|
420 | entity.nameForEmit = nameForEmit;
|
421 | usedNames.add(nameForEmit);
|
422 | }
|
423 | }
|
424 | _fetchSymbolMetadata(astSymbol) {
|
425 | if (astSymbol.symbolMetadata) {
|
426 | return;
|
427 | }
|
428 |
|
429 |
|
430 | if (astSymbol.parentAstSymbol && astSymbol.parentAstSymbol.symbolMetadata === undefined) {
|
431 | this._fetchSymbolMetadata(astSymbol.parentAstSymbol);
|
432 | }
|
433 |
|
434 | this._calculateDeclarationMetadataForDeclarations(astSymbol);
|
435 |
|
436 | for (const astDeclaration of astSymbol.astDeclarations) {
|
437 | this._calculateApiItemMetadata(astDeclaration);
|
438 | }
|
439 |
|
440 | let maxEffectiveReleaseTag = api_extractor_model_1.ReleaseTag.None;
|
441 | for (const astDeclaration of astSymbol.astDeclarations) {
|
442 |
|
443 | const apiItemMetadata = astDeclaration.apiItemMetadata;
|
444 | const effectiveReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
445 | if (effectiveReleaseTag > maxEffectiveReleaseTag) {
|
446 | maxEffectiveReleaseTag = effectiveReleaseTag;
|
447 | }
|
448 | }
|
449 |
|
450 | astSymbol.symbolMetadata = new SymbolMetadata_1.SymbolMetadata({
|
451 | maxEffectiveReleaseTag
|
452 | });
|
453 | }
|
454 | _calculateDeclarationMetadataForDeclarations(astSymbol) {
|
455 |
|
456 | for (const astDeclaration of astSymbol.astDeclarations) {
|
457 | if (astDeclaration.declarationMetadata) {
|
458 | throw new node_core_library_1.InternalError('AstDeclaration.declarationMetadata is not expected to have been initialized yet');
|
459 | }
|
460 | const metadata = new DeclarationMetadata_1.InternalDeclarationMetadata();
|
461 | metadata.tsdocParserContext = this._parseTsdocForAstDeclaration(astDeclaration);
|
462 | astDeclaration.declarationMetadata = metadata;
|
463 | }
|
464 |
|
465 | for (const astDeclaration of astSymbol.astDeclarations) {
|
466 |
|
467 | if (astDeclaration.declaration.kind === ts.SyntaxKind.SetAccessor) {
|
468 | let foundGetter = false;
|
469 | for (const getterAstDeclaration of astDeclaration.astSymbol.astDeclarations) {
|
470 | if (getterAstDeclaration.declaration.kind === ts.SyntaxKind.GetAccessor) {
|
471 |
|
472 | this._addAncillaryDeclaration(getterAstDeclaration, astDeclaration);
|
473 | foundGetter = true;
|
474 | }
|
475 | }
|
476 | if (!foundGetter) {
|
477 | this.messageRouter.addAnalyzerIssue("ae-missing-getter" , `The property "${astDeclaration.astSymbol.localName}" has a setter but no getter.`, astDeclaration);
|
478 | }
|
479 | }
|
480 | }
|
481 | }
|
482 | _addAncillaryDeclaration(mainAstDeclaration, ancillaryAstDeclaration) {
|
483 | const mainMetadata = mainAstDeclaration.declarationMetadata;
|
484 | const ancillaryMetadata = ancillaryAstDeclaration.declarationMetadata;
|
485 | if (mainMetadata.ancillaryDeclarations.indexOf(ancillaryAstDeclaration) >= 0) {
|
486 | return;
|
487 | }
|
488 | if (mainAstDeclaration.astSymbol !== ancillaryAstDeclaration.astSymbol) {
|
489 | throw new node_core_library_1.InternalError('Invalid call to _addAncillaryDeclaration() because declarations do not' +
|
490 | ' belong to the same symbol');
|
491 | }
|
492 | if (mainMetadata.isAncillary) {
|
493 | throw new node_core_library_1.InternalError('Invalid call to _addAncillaryDeclaration() because the target is ancillary itself');
|
494 | }
|
495 | if (ancillaryMetadata.isAncillary) {
|
496 | throw new node_core_library_1.InternalError('Invalid call to _addAncillaryDeclaration() because source is already ancillary' +
|
497 | ' to another declaration');
|
498 | }
|
499 | if (mainAstDeclaration.apiItemMetadata || ancillaryAstDeclaration.apiItemMetadata) {
|
500 | throw new node_core_library_1.InternalError('Invalid call to _addAncillaryDeclaration() because the API item metadata' +
|
501 | ' has already been constructed');
|
502 | }
|
503 | ancillaryMetadata.isAncillary = true;
|
504 | mainMetadata.ancillaryDeclarations.push(ancillaryAstDeclaration);
|
505 | }
|
506 | _calculateApiItemMetadata(astDeclaration) {
|
507 | const declarationMetadata = astDeclaration.declarationMetadata;
|
508 | if (declarationMetadata.isAncillary) {
|
509 | if (astDeclaration.declaration.kind === ts.SyntaxKind.SetAccessor) {
|
510 | if (declarationMetadata.tsdocParserContext) {
|
511 | this.messageRouter.addAnalyzerIssue("ae-setter-with-docs" , `The doc comment for the property "${astDeclaration.astSymbol.localName}"` +
|
512 | ` must appear on the getter, not the setter.`, astDeclaration);
|
513 | }
|
514 | }
|
515 |
|
516 |
|
517 | return;
|
518 | }
|
519 | const options = {
|
520 | declaredReleaseTag: api_extractor_model_1.ReleaseTag.None,
|
521 | effectiveReleaseTag: api_extractor_model_1.ReleaseTag.None,
|
522 | isEventProperty: false,
|
523 | isOverride: false,
|
524 | isSealed: false,
|
525 | isVirtual: false,
|
526 | isPreapproved: false,
|
527 | releaseTagSameAsParent: false
|
528 | };
|
529 | const parserContext = declarationMetadata.tsdocParserContext;
|
530 | if (parserContext) {
|
531 | const modifierTagSet = parserContext.docComment.modifierTagSet;
|
532 | let declaredReleaseTag = api_extractor_model_1.ReleaseTag.None;
|
533 | let extraReleaseTags = false;
|
534 | if (modifierTagSet.isPublic()) {
|
535 | declaredReleaseTag = api_extractor_model_1.ReleaseTag.Public;
|
536 | }
|
537 | if (modifierTagSet.isBeta()) {
|
538 | if (declaredReleaseTag !== api_extractor_model_1.ReleaseTag.None) {
|
539 | extraReleaseTags = true;
|
540 | }
|
541 | else {
|
542 | declaredReleaseTag = api_extractor_model_1.ReleaseTag.Beta;
|
543 | }
|
544 | }
|
545 | if (modifierTagSet.isAlpha()) {
|
546 | if (declaredReleaseTag !== api_extractor_model_1.ReleaseTag.None) {
|
547 | extraReleaseTags = true;
|
548 | }
|
549 | else {
|
550 | declaredReleaseTag = api_extractor_model_1.ReleaseTag.Alpha;
|
551 | }
|
552 | }
|
553 | if (modifierTagSet.isInternal()) {
|
554 | if (declaredReleaseTag !== api_extractor_model_1.ReleaseTag.None) {
|
555 | extraReleaseTags = true;
|
556 | }
|
557 | else {
|
558 | declaredReleaseTag = api_extractor_model_1.ReleaseTag.Internal;
|
559 | }
|
560 | }
|
561 | if (extraReleaseTags) {
|
562 | if (!astDeclaration.astSymbol.isExternal) {
|
563 |
|
564 | this.messageRouter.addAnalyzerIssue("ae-extra-release-tag" , 'The doc comment should not contain more than one release tag', astDeclaration);
|
565 | }
|
566 | }
|
567 | options.declaredReleaseTag = declaredReleaseTag;
|
568 | options.isEventProperty = modifierTagSet.isEventProperty();
|
569 | options.isOverride = modifierTagSet.isOverride();
|
570 | options.isSealed = modifierTagSet.isSealed();
|
571 | options.isVirtual = modifierTagSet.isVirtual();
|
572 | const preapprovedTag = this.extractorConfig.tsdocConfiguration.tryGetTagDefinition('@preapproved');
|
573 | if (preapprovedTag && modifierTagSet.hasTag(preapprovedTag)) {
|
574 |
|
575 | switch (astDeclaration.declaration.kind) {
|
576 | case ts.SyntaxKind.ClassDeclaration:
|
577 | case ts.SyntaxKind.EnumDeclaration:
|
578 | case ts.SyntaxKind.InterfaceDeclaration:
|
579 | case ts.SyntaxKind.ModuleDeclaration:
|
580 | if (declaredReleaseTag === api_extractor_model_1.ReleaseTag.Internal) {
|
581 | options.isPreapproved = true;
|
582 | }
|
583 | else {
|
584 | this.messageRouter.addAnalyzerIssue("ae-preapproved-bad-release-tag" , `The @preapproved tag cannot be applied to "${astDeclaration.astSymbol.localName}"` +
|
585 | ` without an @internal release tag`, astDeclaration);
|
586 | }
|
587 | break;
|
588 | default:
|
589 | this.messageRouter.addAnalyzerIssue("ae-preapproved-unsupported-type" , `The @preapproved tag cannot be applied to "${astDeclaration.astSymbol.localName}"` +
|
590 | ` because it is not a supported declaration type`, astDeclaration);
|
591 | break;
|
592 | }
|
593 | }
|
594 | }
|
595 |
|
596 | if (astDeclaration.parent) {
|
597 | const parentApiItemMetadata = this.fetchApiItemMetadata(astDeclaration.parent);
|
598 | options.effectiveReleaseTag =
|
599 | options.declaredReleaseTag === api_extractor_model_1.ReleaseTag.None
|
600 | ? parentApiItemMetadata.effectiveReleaseTag
|
601 | : options.declaredReleaseTag;
|
602 | options.releaseTagSameAsParent =
|
603 | parentApiItemMetadata.effectiveReleaseTag === options.effectiveReleaseTag;
|
604 | }
|
605 | else {
|
606 | options.effectiveReleaseTag = options.declaredReleaseTag;
|
607 | }
|
608 | if (options.effectiveReleaseTag === api_extractor_model_1.ReleaseTag.None) {
|
609 | if (!astDeclaration.astSymbol.isExternal) {
|
610 |
|
611 |
|
612 | const astSymbol = astDeclaration.astSymbol;
|
613 | const entity = this._entitiesByAstEntity.get(astSymbol.rootAstSymbol);
|
614 | if (entity && entity.consumable) {
|
615 |
|
616 |
|
617 | if (astSymbol.rootAstSymbol.localName !== '_default') {
|
618 | this.messageRouter.addAnalyzerIssue("ae-missing-release-tag" , `"${entity.astEntity.localName}" is exported by the package, but it is missing ` +
|
619 | `a release tag (@alpha, @beta, @public, or @internal)`, astSymbol);
|
620 | }
|
621 | }
|
622 | }
|
623 | options.effectiveReleaseTag = api_extractor_model_1.ReleaseTag.Public;
|
624 | }
|
625 | const apiItemMetadata = new ApiItemMetadata_1.ApiItemMetadata(options);
|
626 | if (parserContext) {
|
627 | apiItemMetadata.tsdocComment = parserContext.docComment;
|
628 | }
|
629 | astDeclaration.apiItemMetadata = apiItemMetadata;
|
630 |
|
631 | for (const ancillaryDeclaration of declarationMetadata.ancillaryDeclarations) {
|
632 | ancillaryDeclaration.apiItemMetadata = apiItemMetadata;
|
633 | }
|
634 | }
|
635 | _parseTsdocForAstDeclaration(astDeclaration) {
|
636 | const declaration = astDeclaration.declaration;
|
637 | let nodeForComment = declaration;
|
638 | if (ts.isVariableDeclaration(declaration)) {
|
639 |
|
640 |
|
641 |
|
642 |
|
643 |
|
644 |
|
645 |
|
646 |
|
647 |
|
648 |
|
649 |
|
650 | const statement = TypeScriptHelpers_1.TypeScriptHelpers.findFirstParent(declaration, ts.SyntaxKind.VariableStatement);
|
651 | if (statement !== undefined) {
|
652 |
|
653 | if (statement.declarationList.declarations.length === 1) {
|
654 | nodeForComment = statement;
|
655 | }
|
656 | }
|
657 | }
|
658 | const sourceFileText = declaration.getSourceFile().text;
|
659 | const ranges = TypeScriptInternals_1.TypeScriptInternals.getJSDocCommentRanges(nodeForComment, sourceFileText) || [];
|
660 | if (ranges.length === 0) {
|
661 | return undefined;
|
662 | }
|
663 |
|
664 |
|
665 | const range = ranges[ranges.length - 1];
|
666 | const tsdocTextRange = tsdoc.TextRange.fromStringRange(sourceFileText, range.pos, range.end);
|
667 | const parserContext = this._tsdocParser.parseRange(tsdocTextRange);
|
668 | this.messageRouter.addTsdocMessages(parserContext, declaration.getSourceFile(), astDeclaration);
|
669 |
|
670 |
|
671 | parserContext.docComment.privateRemarks = undefined;
|
672 | return parserContext;
|
673 | }
|
674 | _collectReferenceDirectives(astEntity) {
|
675 | if (astEntity instanceof AstSymbol_1.AstSymbol) {
|
676 | const sourceFiles = astEntity.astDeclarations.map((astDeclaration) => astDeclaration.declaration.getSourceFile());
|
677 | return this._collectReferenceDirectivesFromSourceFiles(sourceFiles);
|
678 | }
|
679 | if (astEntity instanceof AstNamespaceImport_1.AstNamespaceImport) {
|
680 | const sourceFiles = [astEntity.astModule.sourceFile];
|
681 | return this._collectReferenceDirectivesFromSourceFiles(sourceFiles);
|
682 | }
|
683 | }
|
684 | _collectReferenceDirectivesFromSourceFiles(sourceFiles) {
|
685 | const seenFilenames = new Set();
|
686 | for (const sourceFile of sourceFiles) {
|
687 | if (sourceFile && sourceFile.fileName) {
|
688 | if (!seenFilenames.has(sourceFile.fileName)) {
|
689 | seenFilenames.add(sourceFile.fileName);
|
690 | for (const typeReferenceDirective of sourceFile.typeReferenceDirectives) {
|
691 | const name = sourceFile.text.substring(typeReferenceDirective.pos, typeReferenceDirective.end);
|
692 | this._dtsTypeReferenceDirectives.add(name);
|
693 | }
|
694 | for (const libReferenceDirective of sourceFile.libReferenceDirectives) {
|
695 | const name = sourceFile.text.substring(libReferenceDirective.pos, libReferenceDirective.end);
|
696 | this._dtsLibReferenceDirectives.add(name);
|
697 | }
|
698 | }
|
699 | }
|
700 | }
|
701 | }
|
702 | }
|
703 | exports.Collector = Collector;
|
704 |
|
\ | No newline at end of file |