Initial commit

This commit is contained in:
yuding
2025-12-03 12:00:46 +08:00
commit 5763b764a3
5365 changed files with 1483113 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.DocNodeManager = void 0;
const StringChecks_1 = require("../parser/StringChecks");
/**
* Part of the {@link TSDocConfiguration} object.
*
* @remarks
* If you define your own custom subclasses of `DocNode`, they must be registered with the `DocNodeManager`.
* Use {@link DocNodeManager.registerAllowableChildren} to specify which {@link DocNodeContainer} subclasses
* are allowed to contain your nodes.
*/
class DocNodeManager {
constructor() {
this._docNodeDefinitionsByKind = new Map();
this._docNodeDefinitionsByConstructor = new Map();
}
/**
* Registers a list of {@link IDocNodeDefinition} objects to be used with the associated
* {@link TSDocConfiguration} object.
*/
registerDocNodes(packageName, definitions) {
const packageNameError = StringChecks_1.StringChecks.explainIfInvalidPackageName(packageName);
if (packageNameError) {
throw new Error('Invalid NPM package name: ' + packageNameError);
}
for (const definition of definitions) {
if (!DocNodeManager._nodeKindRegExp.test(definition.docNodeKind)) {
throw new Error(`The DocNode kind ${JSON.stringify(definition.docNodeKind)} is not a valid identifier.` +
` It must start with an underscore or letter, and be comprised of letters, numbers, and underscores`);
}
let existingDefinition = this._docNodeDefinitionsByKind.get(definition.docNodeKind);
if (existingDefinition !== undefined) {
throw new Error(`The DocNode kind "${definition.docNodeKind}" was already registered` +
` by ${existingDefinition.packageName}`);
}
existingDefinition = this._docNodeDefinitionsByConstructor.get(definition.constructor);
if (existingDefinition !== undefined) {
throw new Error(`This DocNode constructor was already registered by ${existingDefinition.packageName}` +
` as ${existingDefinition.docNodeKind}`);
}
const newDefinition = {
docNodeKind: definition.docNodeKind,
constructor: definition.constructor,
packageName,
allowedChildKinds: new Set()
};
this._docNodeDefinitionsByKind.set(definition.docNodeKind, newDefinition);
this._docNodeDefinitionsByConstructor.set(definition.constructor, newDefinition);
}
}
/**
* Reports an error if the specified DocNode kind has not been registered.
*/
throwIfNotRegisteredKind(docNodeKind) {
if (!this._docNodeDefinitionsByKind.has(docNodeKind)) {
throw new Error(`The DocNode kind "${docNodeKind}" was not registered with this TSDocConfiguration`);
}
}
/**
* For the given parent DocNode kind, registers the specified DocNode kinds as being allowable children of
* the parent.
*
* @remarks
* To prevent mistakes, `DocNodeContainer` will report an error if you try to add node that was not registered
* as an allowable child of the container.
*/
registerAllowableChildren(parentKind, childKinds) {
const parentDefinition = this._getDefinition(parentKind);
for (const childKind of childKinds) {
this._getDefinition(childKind);
parentDefinition.allowedChildKinds.add(childKind);
}
}
/**
* Returns true if the specified DocNode kind has been registered as an allowable child of the specified
* parent DocNode kind.
*/
isAllowedChild(parentKind, childKind) {
const parentDefinition = this._getDefinition(parentKind);
return parentDefinition.allowedChildKinds.has(childKind);
}
_getDefinition(docNodeKind) {
const definition = this._docNodeDefinitionsByKind.get(docNodeKind);
if (definition === undefined) {
throw new Error(`The DocNode kind "${docNodeKind}" was not registered with this TSDocConfiguration`);
}
return definition;
}
}
exports.DocNodeManager = DocNodeManager;
// Matches an ASCII TypeScript-style identifier.
//
// Example: "_myIdentifier99"
DocNodeManager._nodeKindRegExp = /^[_a-z][_a-z0-9]*$/i;
//# sourceMappingURL=DocNodeManager.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,223 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSDocConfiguration = void 0;
const StandardTags_1 = require("../details/StandardTags");
const TSDocValidationConfiguration_1 = require("./TSDocValidationConfiguration");
const DocNodeManager_1 = require("./DocNodeManager");
const BuiltInDocNodes_1 = require("../nodes/BuiltInDocNodes");
const TSDocMessageId_1 = require("../parser/TSDocMessageId");
/**
* Configuration for the TSDocParser.
*/
class TSDocConfiguration {
constructor() {
this._tagDefinitions = [];
this._tagDefinitionsByName = new Map();
this._supportedTagDefinitions = new Set();
this._validation = new TSDocValidationConfiguration_1.TSDocValidationConfiguration();
this._docNodeManager = new DocNodeManager_1.DocNodeManager();
this._supportedHtmlElements = new Set();
this.clear(false);
// Register the built-in node kinds
BuiltInDocNodes_1.BuiltInDocNodes.register(this);
}
/**
* Resets the `TSDocConfiguration` object to its initial empty state.
* @param noStandardTags - The `TSDocConfiguration` constructor normally adds definitions for the
* standard TSDoc tags. Set `noStandardTags` to true for a completely empty `tagDefinitions` collection.
*/
clear(noStandardTags = false) {
this._tagDefinitions.length = 0;
this._tagDefinitionsByName.clear();
this._supportedTagDefinitions.clear();
this._validation.ignoreUndefinedTags = false;
this._validation.reportUnsupportedTags = false;
this._validation.reportUnsupportedHtmlElements = false;
this._supportedHtmlElements.clear();
if (!noStandardTags) {
// Define all the standard tags
this.addTagDefinitions(StandardTags_1.StandardTags.allDefinitions);
}
}
/**
* The TSDoc tags that are defined in this configuration.
*
* @remarks
* The subset of "supported" tags is tracked by {@link TSDocConfiguration.supportedTagDefinitions}.
*/
get tagDefinitions() {
return this._tagDefinitions;
}
/**
* Returns the subset of {@link TSDocConfiguration.tagDefinitions}
* that are supported in this configuration.
*
* @remarks
* This property is only used when
* {@link TSDocValidationConfiguration.reportUnsupportedTags} is enabled.
*/
get supportedTagDefinitions() {
return this.tagDefinitions.filter((x) => this.isTagSupported(x));
}
/**
* Enable/disable validation checks performed by the parser.
*/
get validation() {
return this._validation;
}
/**
* The HTML element names that are supported in this configuration. Used in conjunction with the `reportUnsupportedHtmlElements` setting.
*/
get supportedHtmlElements() {
return Array.from(this._supportedHtmlElements.values());
}
/**
* Register custom DocNode subclasses.
*/
get docNodeManager() {
return this._docNodeManager;
}
/**
* Return the tag that was defined with the specified name, or undefined
* if not found.
*/
tryGetTagDefinition(tagName) {
return this._tagDefinitionsByName.get(tagName.toUpperCase());
}
/**
* Return the tag that was defined with the specified name, or undefined
* if not found.
*/
tryGetTagDefinitionWithUpperCase(alreadyUpperCaseTagName) {
return this._tagDefinitionsByName.get(alreadyUpperCaseTagName);
}
/**
* Define a new TSDoc tag to be recognized by the TSDocParser, and mark it as unsupported.
* Use {@link TSDocConfiguration.setSupportForTag} to mark it as supported.
*
* @remarks
* If a tag is "defined" this means that the parser recognizes it and understands its syntax.
* Whereas if a tag is "supported", this means it is defined AND the application implements the tag.
*/
addTagDefinition(tagDefinition) {
const existingDefinition = this._tagDefinitionsByName.get(tagDefinition.tagNameWithUpperCase);
if (existingDefinition === tagDefinition) {
return;
}
if (existingDefinition) {
throw new Error(`A tag is already defined using the name ${existingDefinition.tagName}`);
}
this._tagDefinitions.push(tagDefinition);
this._tagDefinitionsByName.set(tagDefinition.tagNameWithUpperCase, tagDefinition);
}
/**
* Calls {@link TSDocConfiguration.addTagDefinition} for a list of definitions,
* and optionally marks them as supported.
* @param tagDefinitions - the definitions to be added
* @param supported - if specified, calls the {@link TSDocConfiguration.setSupportForTag}
* method to mark the definitions as supported or unsupported
*/
addTagDefinitions(tagDefinitions, supported) {
for (const tagDefinition of tagDefinitions) {
this.addTagDefinition(tagDefinition);
if (supported !== undefined) {
this.setSupportForTag(tagDefinition, supported);
}
}
}
/**
* Returns true if the tag is supported in this configuration.
*/
isTagSupported(tagDefinition) {
this._requireTagToBeDefined(tagDefinition);
return this._supportedTagDefinitions.has(tagDefinition);
}
/**
* Specifies whether the tag definition is supported in this configuration.
* The parser may issue warnings for unsupported tags.
*
* @remarks
* If a tag is "defined" this means that the parser recognizes it and understands its syntax.
* Whereas if a tag is "supported", this means it is defined AND the application implements the tag.
*
* This function automatically sets {@link TSDocValidationConfiguration.reportUnsupportedTags}
* to true.
*/
setSupportForTag(tagDefinition, supported) {
this._requireTagToBeDefined(tagDefinition);
if (supported) {
this._supportedTagDefinitions.add(tagDefinition);
}
else {
this._supportedTagDefinitions.delete(tagDefinition);
}
this.validation.reportUnsupportedTags = true;
}
/**
* Specifies whether the tag definition is supported in this configuration.
* This operation sets {@link TSDocValidationConfiguration.reportUnsupportedTags} to `true`.
*
* @remarks
* The parser may issue warnings for unsupported tags.
* If a tag is "defined" this means that the parser recognizes it and understands its syntax.
* Whereas if a tag is "supported", this means it is defined AND the application implements the tag.
*/
setSupportForTags(tagDefinitions, supported) {
for (const tagDefinition of tagDefinitions) {
this.setSupportForTag(tagDefinition, supported);
}
}
/**
* Assigns the `supportedHtmlElements` property, replacing any previous elements.
* This operation sets {@link TSDocValidationConfiguration.reportUnsupportedHtmlElements} to `true`.
*/
setSupportedHtmlElements(htmlTags) {
this._supportedHtmlElements.clear();
this._validation.reportUnsupportedHtmlElements = true;
for (const htmlTag of htmlTags) {
this._supportedHtmlElements.add(htmlTag);
}
}
/**
* Returns true if the html element is supported in this configuration.
*/
isHtmlElementSupported(htmlTag) {
return this._supportedHtmlElements.has(htmlTag);
}
/**
* Returns true if the specified {@link TSDocMessageId} string is implemented by this release of the TSDoc parser.
* This can be used to detect misspelled identifiers.
*
* @privateRemarks
*
* Why this API is associated with TSDocConfiguration: In the future, if we enable support for custom extensions
* of the TSDoc parser, we may provide a way to register custom message identifiers.
*/
isKnownMessageId(messageId) {
return TSDocMessageId_1.allTsdocMessageIdsSet.has(messageId);
}
/**
* Returns the list of {@link TSDocMessageId} strings that are implemented by this release of the TSDoc parser.
*
* @privateRemarks
*
* Why this API is associated with TSDocConfiguration: In the future, if we enable support for custom extensions
* of the TSDoc parser, we may provide a way to register custom message identifiers.
*/
get allTsdocMessageIds() {
return TSDocMessageId_1.allTsdocMessageIds;
}
_requireTagToBeDefined(tagDefinition) {
const matching = this._tagDefinitionsByName.get(tagDefinition.tagNameWithUpperCase);
if (matching) {
if (matching === tagDefinition) {
return;
}
}
throw new Error('The specified TSDocTagDefinition is not defined for this TSDocConfiguration');
}
}
exports.TSDocConfiguration = TSDocConfiguration;
//# sourceMappingURL=TSDocConfiguration.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,49 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSDocTagDefinition = exports.TSDocTagSyntaxKind = void 0;
const StringChecks_1 = require("../parser/StringChecks");
const Standardization_1 = require("../details/Standardization");
/**
* Determines the type of syntax for a TSDocTagDefinition
*/
var TSDocTagSyntaxKind;
(function (TSDocTagSyntaxKind) {
/**
* The tag is intended to be an inline tag. For example: `{@link}`.
*/
TSDocTagSyntaxKind[TSDocTagSyntaxKind["InlineTag"] = 0] = "InlineTag";
/**
* The tag is intended to be a block tag that starts a new documentation
* section. For example: `@remarks`
*/
TSDocTagSyntaxKind[TSDocTagSyntaxKind["BlockTag"] = 1] = "BlockTag";
/**
* The tag is intended to be a modifier tag whose presence indicates
* an aspect of the associated API item. For example: `@internal`
*/
TSDocTagSyntaxKind[TSDocTagSyntaxKind["ModifierTag"] = 2] = "ModifierTag";
})(TSDocTagSyntaxKind || (exports.TSDocTagSyntaxKind = TSDocTagSyntaxKind = {}));
/**
* Defines a TSDoc tag that will be understood by the TSDocParser.
*/
class TSDocTagDefinition {
constructor(parameters) {
StringChecks_1.StringChecks.validateTSDocTagName(parameters.tagName);
this.tagName = parameters.tagName;
this.tagNameWithUpperCase = parameters.tagName.toUpperCase();
this.syntaxKind = parameters.syntaxKind;
this.standardization =
parameters.standardization || Standardization_1.Standardization.None;
this.allowMultiple = !!parameters.allowMultiple;
}
/**
* Throws an exception if `tagName` is not a valid TSDoc tag name.
*/
static validateTSDocTagName(tagName) {
StringChecks_1.StringChecks.validateTSDocTagName(tagName);
}
}
exports.TSDocTagDefinition = TSDocTagDefinition;
//# sourceMappingURL=TSDocTagDefinition.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TSDocTagDefinition.js","sourceRoot":"","sources":["../../src/configuration/TSDocTagDefinition.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,yDAAsD;AACtD,gEAA6D;AAE7D;;GAEG;AACH,IAAY,kBAiBX;AAjBD,WAAY,kBAAkB;IAC5B;;OAEG;IACH,qEAAS,CAAA;IAET;;;OAGG;IACH,mEAAQ,CAAA;IAER;;;OAGG;IACH,yEAAW,CAAA;AACb,CAAC,EAjBW,kBAAkB,kCAAlB,kBAAkB,QAiB7B;AAkBD;;GAEG;AACH,MAAa,kBAAkB;IA8B7B,YAAmB,UAAyC;QAC1D,2BAAY,CAAC,oBAAoB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,oBAAoB,GAAG,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC7D,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC;QACxC,IAAI,CAAC,eAAe;YACjB,UAAoD,CAAC,eAAe,IAAI,iCAAe,CAAC,IAAI,CAAC;QAChG,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC;IAClD,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,oBAAoB,CAAC,OAAe;QAChD,2BAAY,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;CACF;AA9CD,gDA8CC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\nimport { StringChecks } from '../parser/StringChecks';\r\nimport { Standardization } from '../details/Standardization';\r\n\r\n/**\r\n * Determines the type of syntax for a TSDocTagDefinition\r\n */\r\nexport enum TSDocTagSyntaxKind {\r\n /**\r\n * The tag is intended to be an inline tag. For example: `{@link}`.\r\n */\r\n InlineTag,\r\n\r\n /**\r\n * The tag is intended to be a block tag that starts a new documentation\r\n * section. For example: `@remarks`\r\n */\r\n BlockTag,\r\n\r\n /**\r\n * The tag is intended to be a modifier tag whose presence indicates\r\n * an aspect of the associated API item. For example: `@internal`\r\n */\r\n ModifierTag\r\n}\r\n\r\n/**\r\n * Constructor parameters for {@link TSDocTagDefinition}\r\n */\r\nexport interface ITSDocTagDefinitionParameters {\r\n tagName: string;\r\n syntaxKind: TSDocTagSyntaxKind;\r\n allowMultiple?: boolean;\r\n}\r\n\r\n/**\r\n * @internal\r\n */\r\nexport interface ITSDocTagDefinitionInternalParameters extends ITSDocTagDefinitionParameters {\r\n standardization: Standardization;\r\n}\r\n\r\n/**\r\n * Defines a TSDoc tag that will be understood by the TSDocParser.\r\n */\r\nexport class TSDocTagDefinition {\r\n /**\r\n * The TSDoc tag name. TSDoc tag names start with an at-sign (`@`) followed\r\n * by ASCII letters using \"camelCase\" capitalization.\r\n */\r\n public readonly tagName: string;\r\n\r\n /**\r\n * The TSDoc tag name in all capitals, which is used for performing\r\n * case-insensitive comparisons or lookups.\r\n */\r\n public readonly tagNameWithUpperCase: string;\r\n\r\n /**\r\n * Specifies the expected syntax for this tag.\r\n */\r\n public readonly syntaxKind: TSDocTagSyntaxKind;\r\n\r\n /**\r\n * Indicates the level of support expected from documentation tools that implement\r\n * the standard.\r\n */\r\n public readonly standardization: Standardization;\r\n\r\n /**\r\n * If true, then this TSDoc tag may appear multiple times in a doc comment.\r\n * By default, a tag may only appear once.\r\n */\r\n public readonly allowMultiple: boolean;\r\n\r\n public constructor(parameters: ITSDocTagDefinitionParameters) {\r\n StringChecks.validateTSDocTagName(parameters.tagName);\r\n this.tagName = parameters.tagName;\r\n this.tagNameWithUpperCase = parameters.tagName.toUpperCase();\r\n this.syntaxKind = parameters.syntaxKind;\r\n this.standardization =\r\n (parameters as ITSDocTagDefinitionInternalParameters).standardization || Standardization.None;\r\n this.allowMultiple = !!parameters.allowMultiple;\r\n }\r\n\r\n /**\r\n * Throws an exception if `tagName` is not a valid TSDoc tag name.\r\n */\r\n public static validateTSDocTagName(tagName: string): void {\r\n StringChecks.validateTSDocTagName(tagName);\r\n }\r\n}\r\n"]}

View File

@@ -0,0 +1,51 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSDocValidationConfiguration = void 0;
/**
* Part of the {@link TSDocConfiguration} object.
*/
class TSDocValidationConfiguration {
constructor() {
/**
* Set `ignoreUndefinedTags` to true to silently ignore unrecognized tags,
* instead of reporting a warning.
*
* @remarks
* Normally the parser will issue errors when it encounters tag names that do not
* have a corresponding definition in {@link TSDocConfiguration.tagDefinitions}.
* This helps to catch common mistakes such as a misspelled tag.
*
* @defaultValue `false`
*/
this.ignoreUndefinedTags = false;
/**
* Set `reportUnsupportedTags` to true to issue a warning for tags that are not
* supported by your tool.
*
* @remarks
* The TSDoc standard defines may tags. By default it assumes that if your tool does
* not implement one of these tags, then it will simply ignore it. But sometimes this
* may be misleading for developers. (For example, they might write an `@example` block
* and then be surprised if it doesn't appear in the documentation output.).
*
* For a better experience, you can tell the parser which tags you support, and then it
* will issue warnings wherever unsupported tags are used. This is done using
* {@link TSDocConfiguration.setSupportForTag}. Note that calling that function
* automatically sets `reportUnsupportedTags` to true.
*
* @defaultValue `false`
*/
this.reportUnsupportedTags = false;
/**
* Set `reportUnsupportedHtmlElements` to true to issue a warning for HTML elements which
* are not defined in your TSDoc configuration's `supportedHtmlElements` field.
*
* @defaultValue `false`
*/
this.reportUnsupportedHtmlElements = false;
}
}
exports.TSDocValidationConfiguration = TSDocValidationConfiguration;
//# sourceMappingURL=TSDocValidationConfiguration.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TSDocValidationConfiguration.js","sourceRoot":"","sources":["../../src/configuration/TSDocValidationConfiguration.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D;;GAEG;AACH,MAAa,4BAA4B;IAAzC;QACE;;;;;;;;;;WAUG;QACI,wBAAmB,GAAY,KAAK,CAAC;QAE5C;;;;;;;;;;;;;;;;WAgBG;QACI,0BAAqB,GAAY,KAAK,CAAC;QAE9C;;;;;WAKG;QACI,kCAA6B,GAAY,KAAK,CAAC;IACxD,CAAC;CAAA;AAxCD,oEAwCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\r\n// See LICENSE in the project root for license information.\r\n\r\n/**\r\n * Part of the {@link TSDocConfiguration} object.\r\n */\r\nexport class TSDocValidationConfiguration {\r\n /**\r\n * Set `ignoreUndefinedTags` to true to silently ignore unrecognized tags,\r\n * instead of reporting a warning.\r\n *\r\n * @remarks\r\n * Normally the parser will issue errors when it encounters tag names that do not\r\n * have a corresponding definition in {@link TSDocConfiguration.tagDefinitions}.\r\n * This helps to catch common mistakes such as a misspelled tag.\r\n *\r\n * @defaultValue `false`\r\n */\r\n public ignoreUndefinedTags: boolean = false;\r\n\r\n /**\r\n * Set `reportUnsupportedTags` to true to issue a warning for tags that are not\r\n * supported by your tool.\r\n *\r\n * @remarks\r\n * The TSDoc standard defines may tags. By default it assumes that if your tool does\r\n * not implement one of these tags, then it will simply ignore it. But sometimes this\r\n * may be misleading for developers. (For example, they might write an `@example` block\r\n * and then be surprised if it doesn't appear in the documentation output.).\r\n *\r\n * For a better experience, you can tell the parser which tags you support, and then it\r\n * will issue warnings wherever unsupported tags are used. This is done using\r\n * {@link TSDocConfiguration.setSupportForTag}. Note that calling that function\r\n * automatically sets `reportUnsupportedTags` to true.\r\n *\r\n * @defaultValue `false`\r\n */\r\n public reportUnsupportedTags: boolean = false;\r\n\r\n /**\r\n * Set `reportUnsupportedHtmlElements` to true to issue a warning for HTML elements which\r\n * are not defined in your TSDoc configuration's `supportedHtmlElements` field.\r\n *\r\n * @defaultValue `false`\r\n */\r\n public reportUnsupportedHtmlElements: boolean = false;\r\n}\r\n"]}