Initial commit
This commit is contained in:
24
node_modules/@microsoft/api-extractor/lib/enhancers/DocCommentEnhancer.d.ts
generated
vendored
Normal file
24
node_modules/@microsoft/api-extractor/lib/enhancers/DocCommentEnhancer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { Collector } from '../collector/Collector';
|
||||
export declare class DocCommentEnhancer {
|
||||
private readonly _collector;
|
||||
constructor(collector: Collector);
|
||||
static analyze(collector: Collector): void;
|
||||
analyze(): void;
|
||||
private _analyzeApiItem;
|
||||
private _analyzeNeedsDocumentation;
|
||||
private _checkForBrokenLinks;
|
||||
private _checkForBrokenLinksRecursive;
|
||||
/**
|
||||
* Follow an `{@inheritDoc ___}` reference and copy the content that we find in the referenced comment.
|
||||
*/
|
||||
private _applyInheritDoc;
|
||||
/**
|
||||
* Copy the content from `sourceDocComment` to `targetDocComment`.
|
||||
*/
|
||||
private _copyInheritedDocs;
|
||||
/**
|
||||
* Determines whether or not the provided declaration reference points to an item in the working package.
|
||||
*/
|
||||
private _refersToDeclarationInWorkingPackage;
|
||||
}
|
||||
//# sourceMappingURL=DocCommentEnhancer.d.ts.map
|
||||
1
node_modules/@microsoft/api-extractor/lib/enhancers/DocCommentEnhancer.d.ts.map
generated
vendored
Normal file
1
node_modules/@microsoft/api-extractor/lib/enhancers/DocCommentEnhancer.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"DocCommentEnhancer.d.ts","sourceRoot":"","sources":["../../src/enhancers/DocCommentEnhancer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAQxD,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;IAuGlC,OAAO,CAAC,oBAAoB;IAO5B,OAAO,CAAC,6BAA6B;IAyBrC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA2CxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;OAEG;IACH,OAAO,CAAC,oCAAoC;CAQ7C"}
|
||||
250
node_modules/@microsoft/api-extractor/lib/enhancers/DocCommentEnhancer.js
generated
vendored
Normal file
250
node_modules/@microsoft/api-extractor/lib/enhancers/DocCommentEnhancer.js
generated
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DocCommentEnhancer = void 0;
|
||||
const ts = __importStar(require("typescript"));
|
||||
const tsdoc = __importStar(require("@microsoft/tsdoc"));
|
||||
const api_extractor_model_1 = require("@microsoft/api-extractor-model");
|
||||
const AstSymbol_1 = require("../analyzer/AstSymbol");
|
||||
const ExtractorMessageId_1 = require("../api/ExtractorMessageId");
|
||||
const VisitorState_1 = require("../collector/VisitorState");
|
||||
const AstReferenceResolver_1 = require("../analyzer/AstReferenceResolver");
|
||||
class DocCommentEnhancer {
|
||||
constructor(collector) {
|
||||
this._collector = collector;
|
||||
}
|
||||
static analyze(collector) {
|
||||
const docCommentEnhancer = new DocCommentEnhancer(collector);
|
||||
docCommentEnhancer.analyze();
|
||||
}
|
||||
analyze() {
|
||||
for (const entity of this._collector.entities) {
|
||||
if (entity.astEntity instanceof AstSymbol_1.AstSymbol) {
|
||||
if (entity.consumable ||
|
||||
this._collector.extractorConfig.apiReportIncludeForgottenExports ||
|
||||
this._collector.extractorConfig.docModelIncludeForgottenExports) {
|
||||
entity.astEntity.forEachDeclarationRecursive((astDeclaration) => {
|
||||
this._analyzeApiItem(astDeclaration);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_analyzeApiItem(astDeclaration) {
|
||||
const metadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
||||
if (metadata.docCommentEnhancerVisitorState === VisitorState_1.VisitorState.Visited) {
|
||||
return;
|
||||
}
|
||||
if (metadata.docCommentEnhancerVisitorState === VisitorState_1.VisitorState.Visiting) {
|
||||
this._collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.CyclicInheritDoc, `The @inheritDoc tag for "${astDeclaration.astSymbol.localName}" refers to its own declaration`, astDeclaration);
|
||||
return;
|
||||
}
|
||||
metadata.docCommentEnhancerVisitorState = VisitorState_1.VisitorState.Visiting;
|
||||
if (metadata.tsdocComment && metadata.tsdocComment.inheritDocTag) {
|
||||
this._applyInheritDoc(astDeclaration, metadata.tsdocComment, metadata.tsdocComment.inheritDocTag);
|
||||
}
|
||||
this._analyzeNeedsDocumentation(astDeclaration, metadata);
|
||||
this._checkForBrokenLinks(astDeclaration, metadata);
|
||||
metadata.docCommentEnhancerVisitorState = VisitorState_1.VisitorState.Visited;
|
||||
}
|
||||
_analyzeNeedsDocumentation(astDeclaration, metadata) {
|
||||
if (astDeclaration.declaration.kind === ts.SyntaxKind.Constructor) {
|
||||
// Constructors always do pretty much the same thing, so it's annoying to require people to write
|
||||
// descriptions for them. Instead, if the constructor lacks a TSDoc summary, then API Extractor
|
||||
// will auto-generate one.
|
||||
metadata.undocumented = false;
|
||||
// The class that contains this constructor
|
||||
const classDeclaration = astDeclaration.parent;
|
||||
const configuration = this._collector.extractorConfig.tsdocConfiguration;
|
||||
if (!metadata.tsdocComment) {
|
||||
metadata.tsdocComment = new tsdoc.DocComment({ configuration });
|
||||
}
|
||||
if (!tsdoc.PlainTextEmitter.hasAnyTextContent(metadata.tsdocComment.summarySection)) {
|
||||
metadata.tsdocComment.summarySection.appendNodesInParagraph([
|
||||
new tsdoc.DocPlainText({ configuration, text: 'Constructs a new instance of the ' }),
|
||||
new tsdoc.DocCodeSpan({
|
||||
configuration,
|
||||
code: classDeclaration.astSymbol.localName
|
||||
}),
|
||||
new tsdoc.DocPlainText({ configuration, text: ' class' })
|
||||
]);
|
||||
}
|
||||
const apiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
|
||||
if (apiItemMetadata.effectiveReleaseTag === api_extractor_model_1.ReleaseTag.Internal) {
|
||||
// If the constructor is marked as internal, then add a boilerplate notice for the containing class
|
||||
const classMetadata = this._collector.fetchApiItemMetadata(classDeclaration);
|
||||
if (!classMetadata.tsdocComment) {
|
||||
classMetadata.tsdocComment = new tsdoc.DocComment({ configuration });
|
||||
}
|
||||
if (classMetadata.tsdocComment.remarksBlock === undefined) {
|
||||
classMetadata.tsdocComment.remarksBlock = new tsdoc.DocBlock({
|
||||
configuration,
|
||||
blockTag: new tsdoc.DocBlockTag({
|
||||
configuration,
|
||||
tagName: tsdoc.StandardTags.remarks.tagName
|
||||
})
|
||||
});
|
||||
}
|
||||
classMetadata.tsdocComment.remarksBlock.content.appendNode(new tsdoc.DocParagraph({ configuration }, [
|
||||
new tsdoc.DocPlainText({
|
||||
configuration,
|
||||
text: `The constructor for this class is marked as internal. Third-party code should not` +
|
||||
` call the constructor directly or create subclasses that extend the `
|
||||
}),
|
||||
new tsdoc.DocCodeSpan({
|
||||
configuration,
|
||||
code: classDeclaration.astSymbol.localName
|
||||
}),
|
||||
new tsdoc.DocPlainText({ configuration, text: ' class.' })
|
||||
]));
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// For non-constructor items, we will determine whether or not the item is documented as follows:
|
||||
// 1. If it contains a summary section with at least 10 characters, then it is considered "documented".
|
||||
// 2. If it contains an @inheritDoc tag, then it *may* be considered "documented", depending on whether or not
|
||||
// the tag resolves to a "documented" API member.
|
||||
// - Note: for external members, we cannot currently determine this, so we will consider the "documented"
|
||||
// status to be unknown.
|
||||
if (metadata.tsdocComment) {
|
||||
if (tsdoc.PlainTextEmitter.hasAnyTextContent(metadata.tsdocComment.summarySection, 10)) {
|
||||
// If the API item has a summary comment block (with at least 10 characters), mark it as "documented".
|
||||
metadata.undocumented = false;
|
||||
}
|
||||
else if (metadata.tsdocComment.inheritDocTag) {
|
||||
if (this._refersToDeclarationInWorkingPackage(metadata.tsdocComment.inheritDocTag.declarationReference)) {
|
||||
// If the API item has an `@inheritDoc` comment that points to an API item in the working package,
|
||||
// then the documentation contents should have already been copied from the target via `_applyInheritDoc`.
|
||||
// The continued existence of the tag indicates that the declaration reference was invalid, and not
|
||||
// documentation contents could be copied.
|
||||
// An analyzer issue will have already been logged for this.
|
||||
// We will treat such an API as "undocumented".
|
||||
metadata.undocumented = true;
|
||||
}
|
||||
else {
|
||||
// If the API item has an `@inheritDoc` comment that points to an external API item, we cannot currently
|
||||
// determine whether or not the target is "documented", so we cannot say definitively that this is "undocumented".
|
||||
metadata.undocumented = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If the API item has neither a summary comment block, nor an `@inheritDoc` comment, mark it as "undocumented".
|
||||
metadata.undocumented = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If there is no tsdoc comment at all, mark "undocumented".
|
||||
metadata.undocumented = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_checkForBrokenLinks(astDeclaration, metadata) {
|
||||
if (!metadata.tsdocComment) {
|
||||
return;
|
||||
}
|
||||
this._checkForBrokenLinksRecursive(astDeclaration, metadata.tsdocComment);
|
||||
}
|
||||
_checkForBrokenLinksRecursive(astDeclaration, node) {
|
||||
if (node instanceof tsdoc.DocLinkTag) {
|
||||
if (node.codeDestination) {
|
||||
// Is it referring to the working package? If not, we don't do any link validation, because
|
||||
// AstReferenceResolver doesn't support it yet (but ModelReferenceResolver does of course).
|
||||
// Tracked by: https://github.com/microsoft/rushstack/issues/1195
|
||||
if (this._refersToDeclarationInWorkingPackage(node.codeDestination)) {
|
||||
const referencedAstDeclaration = this._collector.astReferenceResolver.resolve(node.codeDestination);
|
||||
if (referencedAstDeclaration instanceof AstReferenceResolver_1.ResolverFailure) {
|
||||
this._collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.UnresolvedLink, 'The @link reference could not be resolved: ' + referencedAstDeclaration.reason, astDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const childNode of node.getChildNodes()) {
|
||||
this._checkForBrokenLinksRecursive(astDeclaration, childNode);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Follow an `{@inheritDoc ___}` reference and copy the content that we find in the referenced comment.
|
||||
*/
|
||||
_applyInheritDoc(astDeclaration, docComment, inheritDocTag) {
|
||||
if (!inheritDocTag.declarationReference) {
|
||||
this._collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.UnresolvedInheritDocBase, 'The @inheritDoc tag needs a TSDoc declaration reference; signature matching is not supported yet', astDeclaration);
|
||||
return;
|
||||
}
|
||||
if (!this._refersToDeclarationInWorkingPackage(inheritDocTag.declarationReference)) {
|
||||
// The `@inheritDoc` tag is referencing an external package. Skip it, since AstReferenceResolver doesn't
|
||||
// support it yet. As a workaround, this tag will get handled later by api-documenter.
|
||||
// Tracked by: https://github.com/microsoft/rushstack/issues/1195
|
||||
return;
|
||||
}
|
||||
const referencedAstDeclaration = this._collector.astReferenceResolver.resolve(inheritDocTag.declarationReference);
|
||||
if (referencedAstDeclaration instanceof AstReferenceResolver_1.ResolverFailure) {
|
||||
this._collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.UnresolvedInheritDocReference, 'The @inheritDoc reference could not be resolved: ' + referencedAstDeclaration.reason, astDeclaration);
|
||||
return;
|
||||
}
|
||||
this._analyzeApiItem(referencedAstDeclaration);
|
||||
const referencedMetadata = this._collector.fetchApiItemMetadata(referencedAstDeclaration);
|
||||
if (referencedMetadata.tsdocComment) {
|
||||
this._copyInheritedDocs(docComment, referencedMetadata.tsdocComment);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Copy the content from `sourceDocComment` to `targetDocComment`.
|
||||
*/
|
||||
_copyInheritedDocs(targetDocComment, sourceDocComment) {
|
||||
targetDocComment.summarySection = sourceDocComment.summarySection;
|
||||
targetDocComment.remarksBlock = sourceDocComment.remarksBlock;
|
||||
targetDocComment.params.clear();
|
||||
for (const param of sourceDocComment.params) {
|
||||
targetDocComment.params.add(param);
|
||||
}
|
||||
for (const typeParam of sourceDocComment.typeParams) {
|
||||
targetDocComment.typeParams.add(typeParam);
|
||||
}
|
||||
targetDocComment.returnsBlock = sourceDocComment.returnsBlock;
|
||||
targetDocComment.inheritDocTag = undefined;
|
||||
}
|
||||
/**
|
||||
* Determines whether or not the provided declaration reference points to an item in the working package.
|
||||
*/
|
||||
_refersToDeclarationInWorkingPackage(declarationReference) {
|
||||
return ((declarationReference === null || declarationReference === void 0 ? void 0 : declarationReference.packageName) === undefined ||
|
||||
declarationReference.packageName === this._collector.workingPackage.name);
|
||||
}
|
||||
}
|
||||
exports.DocCommentEnhancer = DocCommentEnhancer;
|
||||
//# sourceMappingURL=DocCommentEnhancer.js.map
|
||||
1
node_modules/@microsoft/api-extractor/lib/enhancers/DocCommentEnhancer.js.map
generated
vendored
Normal file
1
node_modules/@microsoft/api-extractor/lib/enhancers/DocCommentEnhancer.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
9
node_modules/@microsoft/api-extractor/lib/enhancers/ValidationEnhancer.d.ts
generated
vendored
Normal file
9
node_modules/@microsoft/api-extractor/lib/enhancers/ValidationEnhancer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { Collector } from '../collector/Collector';
|
||||
export declare class ValidationEnhancer {
|
||||
static analyze(collector: Collector): void;
|
||||
private static _checkForInternalUnderscore;
|
||||
private static _checkForInconsistentReleaseTags;
|
||||
private static _checkReferences;
|
||||
private static _isEcmaScriptSymbol;
|
||||
}
|
||||
//# sourceMappingURL=ValidationEnhancer.d.ts.map
|
||||
1
node_modules/@microsoft/api-extractor/lib/enhancers/ValidationEnhancer.d.ts.map
generated
vendored
Normal file
1
node_modules/@microsoft/api-extractor/lib/enhancers/ValidationEnhancer.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ValidationEnhancer.d.ts","sourceRoot":"","sources":["../../src/enhancers/ValidationEnhancer.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAWxD,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"}
|
||||
254
node_modules/@microsoft/api-extractor/lib/enhancers/ValidationEnhancer.js
generated
vendored
Normal file
254
node_modules/@microsoft/api-extractor/lib/enhancers/ValidationEnhancer.js
generated
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ValidationEnhancer = void 0;
|
||||
const path = __importStar(require("node:path"));
|
||||
const ts = __importStar(require("typescript"));
|
||||
const api_extractor_model_1 = require("@microsoft/api-extractor-model");
|
||||
const AstSymbol_1 = require("../analyzer/AstSymbol");
|
||||
const ExtractorMessageId_1 = require("../api/ExtractorMessageId");
|
||||
const AstNamespaceImport_1 = require("../analyzer/AstNamespaceImport");
|
||||
class ValidationEnhancer {
|
||||
static analyze(collector) {
|
||||
const alreadyWarnedEntities = new Set();
|
||||
for (const entity of collector.entities) {
|
||||
if (!(entity.consumable ||
|
||||
collector.extractorConfig.apiReportIncludeForgottenExports ||
|
||||
collector.extractorConfig.docModelIncludeForgottenExports)) {
|
||||
continue;
|
||||
}
|
||||
if (entity.astEntity instanceof AstSymbol_1.AstSymbol) {
|
||||
// A regular exported AstSymbol
|
||||
const astSymbol = entity.astEntity;
|
||||
astSymbol.forEachDeclarationRecursive((astDeclaration) => {
|
||||
ValidationEnhancer._checkReferences(collector, astDeclaration, alreadyWarnedEntities);
|
||||
});
|
||||
const symbolMetadata = collector.fetchSymbolMetadata(astSymbol);
|
||||
ValidationEnhancer._checkForInternalUnderscore(collector, entity, astSymbol, symbolMetadata);
|
||||
ValidationEnhancer._checkForInconsistentReleaseTags(collector, astSymbol, symbolMetadata);
|
||||
}
|
||||
else if (entity.astEntity instanceof AstNamespaceImport_1.AstNamespaceImport) {
|
||||
// A namespace created using "import * as ___ from ___"
|
||||
const astNamespaceImport = entity.astEntity;
|
||||
const astModuleExportInfo = astNamespaceImport.fetchAstModuleExportInfo(collector);
|
||||
for (const namespaceMemberAstEntity of astModuleExportInfo.exportedLocalEntities.values()) {
|
||||
if (namespaceMemberAstEntity instanceof AstSymbol_1.AstSymbol) {
|
||||
const astSymbol = namespaceMemberAstEntity;
|
||||
astSymbol.forEachDeclarationRecursive((astDeclaration) => {
|
||||
ValidationEnhancer._checkReferences(collector, astDeclaration, alreadyWarnedEntities);
|
||||
});
|
||||
const symbolMetadata = collector.fetchSymbolMetadata(astSymbol);
|
||||
// (Don't apply ValidationEnhancer._checkForInternalUnderscore() for AstNamespaceImport members)
|
||||
ValidationEnhancer._checkForInconsistentReleaseTags(collector, astSymbol, symbolMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static _checkForInternalUnderscore(collector, collectorEntity, astSymbol, symbolMetadata) {
|
||||
let needsUnderscore = false;
|
||||
if (symbolMetadata.maxEffectiveReleaseTag === api_extractor_model_1.ReleaseTag.Internal) {
|
||||
if (!astSymbol.parentAstSymbol) {
|
||||
// If it's marked as @internal and has no parent, then it needs an underscore.
|
||||
// We use maxEffectiveReleaseTag because a merged declaration would NOT need an underscore in a case like this:
|
||||
//
|
||||
// /** @public */
|
||||
// export enum X { }
|
||||
//
|
||||
// /** @internal */
|
||||
// export namespace X { }
|
||||
//
|
||||
// (The above normally reports an error "ae-different-release-tags", but that may be suppressed.)
|
||||
needsUnderscore = true;
|
||||
}
|
||||
else {
|
||||
// If it's marked as @internal and the parent isn't obviously already @internal, then it needs an underscore.
|
||||
//
|
||||
// For example, we WOULD need an underscore for a merged declaration like this:
|
||||
//
|
||||
// /** @internal */
|
||||
// export namespace X {
|
||||
// export interface _Y { }
|
||||
// }
|
||||
//
|
||||
// /** @public */
|
||||
// export class X {
|
||||
// /** @internal */
|
||||
// public static _Y(): void { } // <==== different from parent
|
||||
// }
|
||||
const parentSymbolMetadata = collector.fetchSymbolMetadata(astSymbol);
|
||||
if (parentSymbolMetadata.maxEffectiveReleaseTag > api_extractor_model_1.ReleaseTag.Internal) {
|
||||
needsUnderscore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needsUnderscore) {
|
||||
for (const exportName of collectorEntity.exportNames) {
|
||||
if (exportName[0] !== '_') {
|
||||
collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.InternalMissingUnderscore, `The name "${exportName}" should be prefixed with an underscore` +
|
||||
` because the declaration is marked as @internal`, astSymbol, { exportName });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static _checkForInconsistentReleaseTags(collector, astSymbol, symbolMetadata) {
|
||||
if (astSymbol.isExternal) {
|
||||
// For now, don't report errors for external code. If the developer cares about it, they should run
|
||||
// API Extractor separately on the external project
|
||||
return;
|
||||
}
|
||||
// Normally we will expect all release tags to be the same. Arbitrarily we choose the maxEffectiveReleaseTag
|
||||
// as the thing they should all match.
|
||||
const expectedEffectiveReleaseTag = symbolMetadata.maxEffectiveReleaseTag;
|
||||
// This is set to true if we find a declaration whose release tag is different from expectedEffectiveReleaseTag
|
||||
let mixedReleaseTags = false;
|
||||
// This is set to false if we find a declaration that is not a function/method overload
|
||||
let onlyFunctionOverloads = true;
|
||||
// This is set to true if we find a declaration that is @internal
|
||||
let anyInternalReleaseTags = false;
|
||||
for (const astDeclaration of astSymbol.astDeclarations) {
|
||||
const apiItemMetadata = collector.fetchApiItemMetadata(astDeclaration);
|
||||
const effectiveReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
||||
switch (astDeclaration.declaration.kind) {
|
||||
case ts.SyntaxKind.FunctionDeclaration:
|
||||
case ts.SyntaxKind.MethodDeclaration:
|
||||
break;
|
||||
default:
|
||||
onlyFunctionOverloads = false;
|
||||
}
|
||||
if (effectiveReleaseTag !== expectedEffectiveReleaseTag) {
|
||||
mixedReleaseTags = true;
|
||||
}
|
||||
if (effectiveReleaseTag === api_extractor_model_1.ReleaseTag.Internal) {
|
||||
anyInternalReleaseTags = true;
|
||||
}
|
||||
}
|
||||
if (mixedReleaseTags) {
|
||||
if (!onlyFunctionOverloads) {
|
||||
collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.DifferentReleaseTags, 'This symbol has another declaration with a different release tag', astSymbol);
|
||||
}
|
||||
if (anyInternalReleaseTags) {
|
||||
collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.InternalMixedReleaseTag, `Mixed release tags are not allowed for "${astSymbol.localName}" because one of its declarations` +
|
||||
` is marked as @internal`, astSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
static _checkReferences(collector, astDeclaration, alreadyWarnedEntities) {
|
||||
const apiItemMetadata = collector.fetchApiItemMetadata(astDeclaration);
|
||||
const declarationReleaseTag = apiItemMetadata.effectiveReleaseTag;
|
||||
for (const referencedEntity of astDeclaration.referencedAstEntities) {
|
||||
let collectorEntity;
|
||||
let referencedReleaseTag;
|
||||
let localName;
|
||||
if (referencedEntity instanceof AstSymbol_1.AstSymbol) {
|
||||
// If this is e.g. a member of a namespace, then we need to be checking the top-level scope to see
|
||||
// whether it's exported.
|
||||
//
|
||||
// TODO: Technically we should also check each of the nested scopes along the way.
|
||||
const rootSymbol = referencedEntity.rootAstSymbol;
|
||||
if (rootSymbol.isExternal) {
|
||||
continue;
|
||||
}
|
||||
collectorEntity = collector.tryGetCollectorEntity(rootSymbol);
|
||||
localName = (collectorEntity === null || collectorEntity === void 0 ? void 0 : collectorEntity.nameForEmit) || rootSymbol.localName;
|
||||
const referencedMetadata = collector.fetchSymbolMetadata(referencedEntity);
|
||||
referencedReleaseTag = referencedMetadata.maxEffectiveReleaseTag;
|
||||
}
|
||||
else if (referencedEntity instanceof AstNamespaceImport_1.AstNamespaceImport) {
|
||||
collectorEntity = collector.tryGetCollectorEntity(referencedEntity);
|
||||
// TODO: Currently the "import * as ___ from ___" syntax does not yet support doc comments
|
||||
referencedReleaseTag = api_extractor_model_1.ReleaseTag.Public;
|
||||
localName = (collectorEntity === null || collectorEntity === void 0 ? void 0 : collectorEntity.nameForEmit) || referencedEntity.localName;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
if (collectorEntity && collectorEntity.consumable) {
|
||||
if (api_extractor_model_1.ReleaseTag.compare(declarationReleaseTag, referencedReleaseTag) > 0) {
|
||||
collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.IncompatibleReleaseTags, `The symbol "${astDeclaration.astSymbol.localName}"` +
|
||||
` is marked as ${api_extractor_model_1.ReleaseTag.getTagName(declarationReleaseTag)},` +
|
||||
` but its signature references "${localName}"` +
|
||||
` which is marked as ${api_extractor_model_1.ReleaseTag.getTagName(referencedReleaseTag)}`, astDeclaration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const entryPointFilename = path.basename(collector.workingPackage.entryPointSourceFile.fileName);
|
||||
if (!alreadyWarnedEntities.has(referencedEntity)) {
|
||||
alreadyWarnedEntities.add(referencedEntity);
|
||||
if (referencedEntity instanceof AstSymbol_1.AstSymbol &&
|
||||
ValidationEnhancer._isEcmaScriptSymbol(referencedEntity)) {
|
||||
// The main usage scenario for ECMAScript symbols is to attach private data to a JavaScript object,
|
||||
// so as a special case, we do NOT report them as forgotten exports.
|
||||
}
|
||||
else {
|
||||
collector.messageRouter.addAnalyzerIssue(ExtractorMessageId_1.ExtractorMessageId.ForgottenExport, `The symbol "${localName}" needs to be exported by the entry point ${entryPointFilename}`, astDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Detect an AstSymbol that refers to an ECMAScript symbol declaration such as:
|
||||
//
|
||||
// const mySymbol: unique symbol = Symbol('mySymbol');
|
||||
static _isEcmaScriptSymbol(astSymbol) {
|
||||
if (astSymbol.astDeclarations.length !== 1) {
|
||||
return false;
|
||||
}
|
||||
// We are matching a form like this:
|
||||
//
|
||||
// - VariableDeclaration:
|
||||
// - Identifier: pre=[mySymbol]
|
||||
// - ColonToken: pre=[:] sep=[ ]
|
||||
// - TypeOperator:
|
||||
// - UniqueKeyword: pre=[unique] sep=[ ]
|
||||
// - SymbolKeyword: pre=[symbol]
|
||||
const astDeclaration = astSymbol.astDeclarations[0];
|
||||
if (ts.isVariableDeclaration(astDeclaration.declaration)) {
|
||||
const variableTypeNode = astDeclaration.declaration.type;
|
||||
if (variableTypeNode) {
|
||||
for (const token of variableTypeNode.getChildren()) {
|
||||
if (token.kind === ts.SyntaxKind.SymbolKeyword) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
exports.ValidationEnhancer = ValidationEnhancer;
|
||||
//# sourceMappingURL=ValidationEnhancer.js.map
|
||||
1
node_modules/@microsoft/api-extractor/lib/enhancers/ValidationEnhancer.js.map
generated
vendored
Normal file
1
node_modules/@microsoft/api-extractor/lib/enhancers/ValidationEnhancer.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user